Merge remote-tracking branch 'origin/master'
BIN
OsmAnd/res/drawable-hdpi/bg_card_shadow_cr3dp.9.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_contents.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_list_bullet.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-hdpi/ic_action_list_header.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-mdpi/bg_card_shadow_cr3dp.9.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_contents.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_list_bullet.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-mdpi/ic_action_list_header.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
OsmAnd/res/drawable-xhdpi/bg_card_shadow_cr3dp.9.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_contents.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_list_bullet.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
OsmAnd/res/drawable-xhdpi/ic_action_list_header.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/bg_card_shadow_cr3dp.9.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_contents.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_list_bullet.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/ic_action_list_header.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
12
OsmAnd/res/drawable/wikivoyage_search_card_bg.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<nine-patch android:src="@drawable/bg_card_shadow_cr3dp"/>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="?attr/wikivoyage_card_bg_color"/>
|
||||
<corners android:radius="3dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -37,7 +37,7 @@
|
|||
android:layout_marginTop="@dimen/content_padding_small"
|
||||
android:drawablePadding="@dimen/context_menu_padding_margin_small"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="0.01"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:padding="@dimen/context_menu_padding_margin_tiny"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
|
|
|
@ -48,48 +48,60 @@
|
|||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="0.01"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:text="@string/shared_string_options"
|
||||
android:textColor="?attr/wikivoyage_active_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"/>
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/search_button"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dashboard_map_toolbar"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center_vertical">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/text_margin_small"
|
||||
android:layout_marginRight="@dimen/text_margin_small"
|
||||
android:background="@drawable/wikivoyage_search_card_bg">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:text="@string/search_poi_category_hint"
|
||||
android:textColor="?attr/searchbar_text_hint"
|
||||
android:textSize="@dimen/default_list_text_size_large"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/search_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_list_item_height"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/search_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/shared_string_search"
|
||||
tools:src="@drawable/ic_action_search_dark"/>
|
||||
<TextView
|
||||
android:id="@+id/search_hint"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:text="@string/wikivoyage_search_hint"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:textColor="?attr/searchbar_text_hint"/>
|
||||
|
||||
</LinearLayout>
|
||||
<ImageView
|
||||
android:id="@+id/search_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_small"
|
||||
android:layout_marginRight="@dimen/content_padding_small"
|
||||
android:contentDescription="@string/shared_string_search"
|
||||
tools:src="@drawable/ic_action_search_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<net.osmand.plus.LockableViewPager
|
||||
android:id="@+id/view_pager"
|
||||
|
|
157
OsmAnd/res/layout/wikivoyage_saved_articles_list_item.xml
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?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:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/wikivoyage_card_bg_color">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/bottom_sheet_content_padding_small"
|
||||
android:paddingTop="@dimen/content_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_padding_margin_medium"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.ListItemTitle"
|
||||
tools:text="London"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:textAppearance="@style/TextAppearance.ContextMenuSubtitle"
|
||||
tools:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard."/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/wikivoyage_saved_article_icon_size"
|
||||
android:layout_height="@dimen/wikivoyage_saved_article_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@drawable/ic_empty_state_marker_history_night"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/part_of"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_padding_margin_tiny"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_marginTop="@dimen/bottom_sheet_content_padding_small"
|
||||
android:alpha=".5"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.ContextMenuSubtitle"
|
||||
tools:text="England • United Kingdom"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/read_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/bottom_sheet_content_padding_small"
|
||||
android:layout_marginStart="@dimen/bottom_sheet_content_padding_small"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:paddingBottom="@dimen/context_menu_padding_margin_tiny"
|
||||
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||
android:text="@string/shared_string_read"
|
||||
android:textColor="?attr/wikivoyage_active_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:drawableLeft="@drawable/ic_action_read_article"
|
||||
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/delete_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/bottom_sheet_content_padding_small"
|
||||
android:layout_marginRight="@dimen/bottom_sheet_content_padding_small"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:paddingBottom="@dimen/context_menu_padding_margin_tiny"
|
||||
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||
android:text="@string/shared_string_delete"
|
||||
android:textColor="?attr/wikivoyage_active_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:drawableRight="@drawable/ic_action_read_later_fill"
|
||||
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/wikivoyage_card_divider_color"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/shadow"
|
||||
layout="@layout/card_bottom_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</LinearLayout>
|
3
OsmAnd/res/values-b+hrx/strings.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<resources>
|
||||
</resources>
|
|
@ -195,4 +195,5 @@
|
|||
<dimen name="toolbar_height">84dp</dimen>
|
||||
|
||||
<dimen name="wikivoyage_search_list_header_height">54dp</dimen>
|
||||
<dimen name="wikivoyage_saved_article_icon_size">120dp</dimen>
|
||||
</resources>
|
|
@ -269,4 +269,7 @@
|
|||
<dimen name="toolbar_height">56dp</dimen>
|
||||
|
||||
<dimen name="wikivoyage_search_list_header_height">36dp</dimen>
|
||||
<dimen name="wikivoyage_saved_article_icon_size">80dp</dimen>
|
||||
|
||||
<dimen name="text_button_letter_spacing" format="float">0.01</dimen>
|
||||
</resources>
|
|
@ -9,6 +9,8 @@
|
|||
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
|
||||
-->
|
||||
<string name="wikivoyage_search_hint">Search: Country, City, Province</string>
|
||||
<string name="shared_string_read">Read</string>
|
||||
<string name="saved_articles">Saved articles</string>
|
||||
<string name="shared_string_explore">Explore</string>
|
||||
<string name="shared_string_result">Result</string>
|
||||
|
|
|
@ -1099,6 +1099,7 @@ public class OsmandSettings {
|
|||
public final OsmandPreference<Boolean> SPEAK_PEDESTRIAN = new BooleanPreference("speak_pedestrian", true).makeProfile().cache();
|
||||
public final OsmandPreference<Boolean> SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", true).makeProfile().cache();
|
||||
public final OsmandPreference<Boolean> SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", false).makeProfile().cache();
|
||||
public final OsmandPreference<Boolean> SPEAK_TUNNELS = new BooleanPreference("speak_tunnels", false).makeProfile().cache();
|
||||
public final OsmandPreference<Boolean> ANNOUNCE_WPT = new BooleanPreference("announce_wpt", true).makeGlobal().cache();
|
||||
public final OsmandPreference<Boolean> ANNOUNCE_NEARBY_FAVORITES = new BooleanPreference("announce_nearby_favorites", false).makeProfile().cache();
|
||||
public final OsmandPreference<Boolean> ANNOUNCE_NEARBY_POI = new BooleanPreference("announce_nearby_poi", false).makeProfile().cache();
|
||||
|
|
|
@ -636,11 +636,12 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
|
|||
} else if (preference == speakAlarms) {
|
||||
AlertDialog dlg = showBooleanSettings(new String[] { getString(R.string.speak_street_names),
|
||||
getString(R.string.speak_traffic_warnings), getString(R.string.speak_pedestrian),
|
||||
getString(R.string.speak_speed_limit), getString(R.string.speak_cameras),
|
||||
getString(R.string.speak_speed_limit), getString(R.string.speak_cameras), getString(R.string.show_tunnels),
|
||||
getString(R.string.announce_gpx_waypoints), getString(R.string.speak_favorites),
|
||||
getString(R.string.speak_poi) }, new OsmandPreference[] { settings.SPEAK_STREET_NAMES,
|
||||
settings.SPEAK_TRAFFIC_WARNINGS, settings.SPEAK_PEDESTRIAN, settings.SPEAK_SPEED_LIMIT,
|
||||
settings.SPEAK_SPEED_CAMERA, settings.ANNOUNCE_WPT, settings.ANNOUNCE_NEARBY_FAVORITES,
|
||||
settings.SPEAK_SPEED_CAMERA, settings.SPEAK_TUNNELS,
|
||||
settings.ANNOUNCE_WPT, settings.ANNOUNCE_NEARBY_FAVORITES,
|
||||
settings.ANNOUNCE_NEARBY_POI }, preference.getTitle());
|
||||
final boolean initialSpeedCam = settings.SPEAK_SPEED_CAMERA.get();
|
||||
final boolean initialFavorites = settings.ANNOUNCE_NEARBY_FAVORITES.get();
|
||||
|
|
|
@ -219,6 +219,8 @@ public class WaypointHelper {
|
|||
app.getSettings().SPEAK_TRAFFIC_WARNINGS.setModeValue(appMode, enable);
|
||||
app.getSettings().SHOW_PEDESTRIAN.setModeValue(appMode, enable);
|
||||
app.getSettings().SPEAK_PEDESTRIAN.setModeValue(appMode, enable);
|
||||
app.getSettings().SHOW_TUNNELS.setModeValue(appMode, enable);
|
||||
app.getSettings().SPEAK_TUNNELS.setModeValue(appMode, enable);
|
||||
//But do not implicitly change speed_cam settings here because of legal restrictions in some countries, so Nav settings must prevail
|
||||
} else if (type == POI) {
|
||||
app.getSettings().SHOW_NEARBY_POI.setModeValue(appMode, enable);
|
||||
|
|
|
@ -349,6 +349,14 @@ public class VoiceRouter {
|
|||
p.attention(type+"").play();
|
||||
}
|
||||
}
|
||||
} else if (type == AlarmInfoType.TUNNEL) {
|
||||
if (router.getSettings().SPEAK_TUNNELS.get()) {
|
||||
CommandBuilder p = getNewCommandPlayerToPlay();
|
||||
if (p != null) {
|
||||
notifyOnVoiceMessage();
|
||||
p.attention(type+"").play();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (router.getSettings().SPEAK_TRAFFIC_WARNINGS.get()) {
|
||||
CommandBuilder p = getNewCommandPlayerToPlay();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package net.osmand.plus.wikivoyage.data;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import android.text.Html;
|
||||
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
|
||||
|
@ -14,6 +16,8 @@ public class WikivoyageArticle {
|
|||
private static final String THUMB_PREFIX = "320px-";
|
||||
private static final String REGULAR_PREFIX = "800px-";
|
||||
|
||||
private static final int PARTIAL_CONTENT_PHRASES = 3;
|
||||
|
||||
String id;
|
||||
String title;
|
||||
String content;
|
||||
|
@ -80,6 +84,35 @@ public class WikivoyageArticle {
|
|||
return aggregatedPartOf;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPartialContent() {
|
||||
if (content == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int firstParagraphStart = content.indexOf("<p>");
|
||||
int firstParagraphEnd = content.indexOf("</p>");
|
||||
if (firstParagraphStart == -1 || firstParagraphEnd == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 4 is the length of </p> tag
|
||||
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + 4);
|
||||
String firstParagraphText = Html.fromHtml(firstParagraphHtml).toString();
|
||||
String[] phrases = firstParagraphText.split("\\. ");
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES);
|
||||
for (int i = 0; i < limit; i++) {
|
||||
res.append(phrases[i]).append(".");
|
||||
if (i < limit - 1) {
|
||||
res.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) {
|
||||
String[] hash = getHash(imageTitle);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus.wikivoyage.data;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
|
||||
|
@ -22,10 +23,12 @@ public class WikivoyageLocalDataHelper {
|
|||
private WikivoyageLocalDataDbHelper dbHelper;
|
||||
|
||||
private TLongObjectHashMap<WikivoyageSearchHistoryItem> historyMap;
|
||||
private List<WikivoyageArticle> savedArticles;
|
||||
|
||||
private WikivoyageLocalDataHelper(OsmandApplication app) {
|
||||
dbHelper = new WikivoyageLocalDataDbHelper(app);
|
||||
historyMap = dbHelper.getAllHistoryMap();
|
||||
savedArticles = dbHelper.getSavedArticles();
|
||||
}
|
||||
|
||||
public static WikivoyageLocalDataHelper getInstance(OsmandApplication app) {
|
||||
|
@ -51,7 +54,7 @@ public class WikivoyageLocalDataHelper {
|
|||
return res;
|
||||
}
|
||||
|
||||
public void addToHistory(WikivoyageArticle article) {
|
||||
public void addToHistory(@NonNull WikivoyageArticle article) {
|
||||
addToHistory(article.getCityId(), article.getTitle(), article.getLang(), article.getIsPartOf());
|
||||
}
|
||||
|
||||
|
@ -80,9 +83,49 @@ public class WikivoyageLocalDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public List<WikivoyageArticle> getSavedArticles() {
|
||||
return new ArrayList<>(savedArticles);
|
||||
}
|
||||
|
||||
public void addArticleToSaved(@NonNull WikivoyageArticle article) {
|
||||
if (!isArticleSaved(article)) {
|
||||
WikivoyageArticle saved = new WikivoyageArticle();
|
||||
saved.cityId = article.cityId;
|
||||
saved.title = article.title;
|
||||
saved.lang = article.lang;
|
||||
saved.aggregatedPartOf = article.aggregatedPartOf;
|
||||
saved.imageTitle = article.imageTitle;
|
||||
saved.content = article.getPartialContent();
|
||||
savedArticles.add(saved);
|
||||
dbHelper.addSavedArticle(saved);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeArticleFromSaved(@NonNull WikivoyageArticle article) {
|
||||
WikivoyageArticle savedArticle = getArticle(article.cityId, article.lang);
|
||||
if (savedArticle != null) {
|
||||
savedArticles.remove(savedArticle);
|
||||
dbHelper.removeSavedArticle(savedArticle);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isArticleSaved(@NonNull WikivoyageArticle article) {
|
||||
return getArticle(article.cityId, article.lang) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private WikivoyageArticle getArticle(long cityId, String lang) {
|
||||
for (WikivoyageArticle article : savedArticles) {
|
||||
if (article.cityId == cityId && article.lang != null && article.lang.equals(lang)) {
|
||||
return article;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class WikivoyageLocalDataDbHelper {
|
||||
|
||||
private static final int DB_VERSION = 1;
|
||||
private static final int DB_VERSION = 2;
|
||||
private static final String DB_NAME = "wikivoyage_local_data";
|
||||
|
||||
private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history";
|
||||
|
@ -108,9 +151,35 @@ public class WikivoyageLocalDataHelper {
|
|||
HISTORY_COL_LAST_ACCESSED +
|
||||
" FROM " + HISTORY_TABLE_NAME;
|
||||
|
||||
private static final String BOOKMARKS_TABLE_NAME = "wikivoyage_saved_articles";
|
||||
private static final String BOOKMARKS_COL_CITY_ID = "city_id";
|
||||
private static final String BOOKMARKS_COL_ARTICLE_TITLE = "article_title";
|
||||
private static final String BOOKMARKS_COL_LANG = "lang";
|
||||
private static final String BOOKMARKS_COL_IS_PART_OF = "is_part_of";
|
||||
private static final String BOOKMARKS_COL_IMAGE_TITLE = "image_title";
|
||||
private static final String BOOKMARKS_COL_PARTIAL_CONTENT = "partial_content";
|
||||
|
||||
private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
|
||||
BOOKMARKS_TABLE_NAME + " (" +
|
||||
BOOKMARKS_COL_CITY_ID + " long, " +
|
||||
BOOKMARKS_COL_ARTICLE_TITLE + " TEXT, " +
|
||||
BOOKMARKS_COL_LANG + " TEXT, " +
|
||||
BOOKMARKS_COL_IS_PART_OF + " TEXT, " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + " TEXT, " +
|
||||
BOOKMARKS_COL_PARTIAL_CONTENT + " TEXT);";
|
||||
|
||||
private static final String BOOKMARKS_TABLE_SELECT = "SELECT " +
|
||||
BOOKMARKS_COL_CITY_ID + ", " +
|
||||
BOOKMARKS_COL_ARTICLE_TITLE + ", " +
|
||||
BOOKMARKS_COL_LANG + ", " +
|
||||
BOOKMARKS_COL_IS_PART_OF + ", " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + ", " +
|
||||
BOOKMARKS_COL_PARTIAL_CONTENT +
|
||||
" FROM " + BOOKMARKS_TABLE_NAME;
|
||||
|
||||
private final OsmandApplication context;
|
||||
|
||||
private WikivoyageLocalDataDbHelper(OsmandApplication context) {
|
||||
WikivoyageLocalDataDbHelper(OsmandApplication context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
@ -135,11 +204,14 @@ public class WikivoyageLocalDataHelper {
|
|||
|
||||
private void onCreate(SQLiteConnection conn) {
|
||||
conn.execSQL(HISTORY_TABLE_CREATE);
|
||||
conn.execSQL(BOOKMARKS_TABLE_CREATE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void onUpgrade(SQLiteConnection conn, int oldVersion, int newVersion) {
|
||||
|
||||
if (oldVersion < 2) {
|
||||
conn.execSQL(BOOKMARKS_TABLE_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -203,6 +275,52 @@ public class WikivoyageLocalDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
List<WikivoyageArticle> getSavedArticles() {
|
||||
List<WikivoyageArticle> res = new ArrayList<>();
|
||||
SQLiteConnection conn = openConnection(true);
|
||||
if (conn != null) {
|
||||
try {
|
||||
SQLiteCursor cursor = conn.rawQuery(BOOKMARKS_TABLE_SELECT, null);
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
res.add(readSavedArticle(cursor));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void addSavedArticle(WikivoyageArticle article) {
|
||||
SQLiteConnection conn = openConnection(false);
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.execSQL("INSERT INTO " + BOOKMARKS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?)",
|
||||
new Object[]{article.cityId, article.title, article.lang,
|
||||
article.aggregatedPartOf, article.imageTitle, article.content});
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeSavedArticle(WikivoyageArticle article) {
|
||||
SQLiteConnection conn = openConnection(false);
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.execSQL("DELETE FROM " + BOOKMARKS_TABLE_NAME +
|
||||
" WHERE " + BOOKMARKS_COL_CITY_ID + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_LANG + " = ?",
|
||||
new Object[]{article.cityId, article.lang});
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private WikivoyageSearchHistoryItem readHistoryItem(SQLiteCursor cursor) {
|
||||
WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem();
|
||||
|
||||
|
@ -214,5 +332,18 @@ public class WikivoyageLocalDataHelper {
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
private WikivoyageArticle readSavedArticle(SQLiteCursor cursor) {
|
||||
WikivoyageArticle res = new WikivoyageArticle();
|
||||
|
||||
res.cityId = cursor.getLong(0);
|
||||
res.title = cursor.getString(1);
|
||||
res.lang = cursor.getString(2);
|
||||
res.aggregatedPartOf = cursor.getString(3);
|
||||
res.imageTitle = cursor.getString(4);
|
||||
res.content = cursor.getString(5);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.LockableViewPager;
|
||||
|
@ -40,8 +41,10 @@ public class WikivoyageExploreDialogFragment extends WikivoyageBaseDialogFragmen
|
|||
|
||||
setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar));
|
||||
|
||||
int searchColorId = nightMode ? R.color.icon_color : R.color.ctx_menu_title_color_dark;
|
||||
((TextView) mainView.findViewById(R.id.search_hint)).setTextColor(getResolvedColor(searchColorId));
|
||||
((ImageView) mainView.findViewById(R.id.search_icon))
|
||||
.setImageDrawable(getContentIcon(R.drawable.ic_action_search_dark));
|
||||
.setImageDrawable(getIcon(R.drawable.ic_action_search_dark, searchColorId));
|
||||
|
||||
mainView.findViewById(R.id.search_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
|