Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2018-04-25 11:06:05 +02:00
commit 8071be26a9
11 changed files with 351 additions and 31 deletions

View file

@ -2,25 +2,30 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/list_content_padding" android:layout_marginBottom="@dimen/list_content_padding"
android:layout_marginTop="@dimen/list_content_padding" android:layout_marginTop="@dimen/list_content_padding"
android:background="@drawable/travel_card_bg"> android:layout_marginLeft="@dimen/text_margin_small"
android:layout_marginRight="@dimen/text_margin_small"
android:background="@drawable/travel_card_bg"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/wikivoyage_explore_card_image_height"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:orientation="vertical"> android:orientation="vertical"
android:background="@color/wikivoyage_open_beta_card_image_background">
<ImageView <ImageView
android:id="@+id/background_image" android:id="@+id/background_image"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/welcome_to_open_beta" android:contentDescription="@string/welcome_to_open_beta"
tools:src="@drawable/img_help_wikivoyage_articles" /> tools:src="@drawable/img_help_wikivoyage_articles" />
</LinearLayout>
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
@ -53,7 +58,7 @@
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/bottom_button_text" android:id="@+id/bottom_button_text"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_title_height" android:layout_height="@dimen/bottom_sheet_title_height"
android:layout_gravity="center" android:layout_gravity="center"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
@ -63,6 +68,5 @@
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
tools:text="@string/get_unlimited_access" /> tools:text="@string/get_unlimited_access" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -2,11 +2,13 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/list_content_padding" android:layout_marginBottom="@dimen/list_content_padding"
android:layout_marginTop="@dimen/list_content_padding" android:layout_marginTop="@dimen/list_content_padding"
android:layout_marginLeft="@dimen/text_margin_small"
android:layout_marginRight="@dimen/text_margin_small"
android:background="@drawable/travel_card_bg"> android:background="@drawable/travel_card_bg">
<LinearLayout <LinearLayout
@ -16,9 +18,9 @@
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/wikivoyage_start_editing_image_background" android:background="@color/wikivoyage_start_editing_card_image_background"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
@ -64,7 +66,7 @@
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/bottom_button_text" android:id="@+id/bottom_button_text"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_title_height" android:layout_height="@dimen/bottom_sheet_title_height"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center" android:gravity="center"

View file

@ -207,4 +207,5 @@
<dimen name="wikivoyage_search_icon_margin_left">21dp</dimen> <dimen name="wikivoyage_search_icon_margin_left">21dp</dimen>
<dimen name="wikivoyage_search_icon_margin_right">33dp</dimen> <dimen name="wikivoyage_search_icon_margin_right">33dp</dimen>
<dimen name="wikivoyage_search_divider_margin_start">82dp</dimen> <dimen name="wikivoyage_search_divider_margin_start">82dp</dimen>
<dimen name="wikivoyage_explore_card_image_height">216dp</dimen>
</resources> </resources>

View file

@ -428,6 +428,7 @@
<color name="wikivoyage_primary_text_light">#212121</color> <color name="wikivoyage_primary_text_light">#212121</color>
<color name="wikivoyage_primary_text_dark">#cccccc</color> <color name="wikivoyage_primary_text_dark">#cccccc</color>
<color name="wikivoyage_secondary_text">#727272</color> <color name="wikivoyage_secondary_text">#727272</color>
<color name="wikivoyage_start_editing_image_background">#339966</color> <color name="wikivoyage_start_editing_card_image_background">#339966</color>
<color name="wikivoyage_open_beta_card_image_background">#008bf8</color>
</resources> </resources>

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 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 PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="popular_destinations">Popular destinations</string>
<string name="paid_app">Paid application</string> <string name="paid_app">Paid application</string>
<string name="paid_plugin">Paid plugin</string> <string name="paid_plugin">Paid plugin</string>
<string name="travel_card_update_descr">We prepared updates and fixes in the Wikivoyage data, update the file to see them.</string> <string name="travel_card_update_descr">We prepared updates and fixes in the Wikivoyage data, update the file to see them.</string>

View file

@ -199,6 +199,24 @@ public class TravelDbHelper {
return list; return list;
} }
@NonNull
public List<TravelArticle> searchPopular() {
List<TravelArticle> 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<WikivoyageSearchResult> list) { private void sortSearchResults(final String searchQuery, List<WikivoyageSearchResult> list) {
Collections.sort(list, new Comparator<WikivoyageSearchResult>() { Collections.sort(list, new Comparator<WikivoyageSearchResult>() {
@Override @Override

View file

@ -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<RecyclerView.ViewHolder> {
private static final int HEADER_TYPE = 3;
private final OsmandSettings settings;
private final List<Object> 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<Object> getItems() {
return items;
}
public void setItems(List<Object> 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);
}
}
}

View file

@ -3,41 +3,56 @@ package net.osmand.plus.wikivoyage.explore;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.BaseOsmAndFragment; 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.OpenBetaTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ExploreTabFragment extends BaseOsmAndFragment { public class ExploreTabFragment extends BaseOsmAndFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 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); final View mainView = inflater.inflate(R.layout.fragment_explore_tab, container, false);
ExploreRvAdapter adapter = new ExploreRvAdapter(getMyApplication());
ArrayList<BaseTravelCard> items = new ArrayList<>();
OpenBetaTravelCard openBetaTravelCard = new OpenBetaTravelCard(app, nightMode, getFragmentManager());
StartEditingTravelCard startEditingTravelCard = new StartEditingTravelCard(app, nightMode);
items.add(openBetaTravelCard);
items.add(startEditingTravelCard);
final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view); final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view);
rv.setLayoutManager(new LinearLayoutManager(getContext())); rv.setLayoutManager(new LinearLayoutManager(getContext()));
adapter.setItems(getItems());
rv.setAdapter(adapter);
return mainView; return mainView;
} }
private List<Object> getItems() {
final OsmandApplication app = getMyApplication();
boolean nightMode = !getSettings().isLightContent();
List<Object> items = new ArrayList<>();
List<TravelArticle> 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;
}
} }

View file

@ -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;
}
}

View file

@ -13,6 +13,8 @@ import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
public class OpenBetaTravelCard extends BaseTravelCard { public class OpenBetaTravelCard extends BaseTravelCard {
public static final int TYPE = 0;
private FragmentManager fragmentManager; private FragmentManager fragmentManager;
public OpenBetaTravelCard(OsmandApplication app, boolean nightMode, 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 title;
final TextView description; final TextView description;
final TextView button; final TextView button;
final ImageView backgroundImage; final ImageView backgroundImage;
OpenBetaTravelVH(final View itemView) { public OpenBetaTravelVH(final View itemView) {
super(itemView); super(itemView);
title = (TextView) itemView.findViewById(R.id.title); title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description); description = (TextView) itemView.findViewById(R.id.description);
@ -55,6 +57,6 @@ public class OpenBetaTravelCard extends BaseTravelCard {
@Override @Override
public int getCardType() { public int getCardType() {
return 0; return TYPE;
} }
} }

View file

@ -14,6 +14,8 @@ import net.osmand.plus.R;
public class StartEditingTravelCard extends BaseTravelCard { public class StartEditingTravelCard extends BaseTravelCard {
public static final int TYPE = 1;
public StartEditingTravelCard(OsmandApplication app, boolean nightMode) { public StartEditingTravelCard(OsmandApplication app, boolean nightMode) {
super(app, 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 title;
final TextView description; final TextView description;
final TextView button; final TextView button;
final ImageView backgroundImage; final ImageView backgroundImage;
StartEditingTravelVH(final View itemView) { public StartEditingTravelVH(final View itemView) {
super(itemView); super(itemView);
title = (TextView) itemView.findViewById(R.id.title); title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description); description = (TextView) itemView.findViewById(R.id.description);
@ -57,6 +59,6 @@ public class StartEditingTravelCard extends BaseTravelCard {
@Override @Override
public int getCardType() { public int getCardType() {
return 1; return TYPE;
} }
} }