forked from organicmaps/organicmaps
Merge pull request #4367 from goblinr/MAPSME-1-external-place-page-booking
[android] place page booking
This commit is contained in:
commit
d487f11baa
106 changed files with 4074 additions and 360 deletions
|
@ -71,11 +71,11 @@
|
|||
|
||||
<meta-data
|
||||
android:name="PW_APPID"
|
||||
android:value="${PW_APPID}" />
|
||||
android:value="${PW_APPID}"/>
|
||||
|
||||
<meta-data
|
||||
android:name="PW_PROJECT_ID"
|
||||
android:value="${PW_PROJECT_ID}" />
|
||||
android:value="${PW_PROJECT_ID}"/>
|
||||
|
||||
<!--meta-data
|
||||
android:name="PW_LOG_LEVEL"
|
||||
|
@ -241,52 +241,79 @@
|
|||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.editor.EditorActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/edit_place"
|
||||
android:theme="@style/MwmTheme.EditorActivity"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
android:name="com.mapswithme.maps.editor.EditorActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/edit_place"
|
||||
android:theme="@style/MwmTheme.EditorActivity"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.editor.ProfileActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.settings.SettingsActivity">
|
||||
android:name="com.mapswithme.maps.editor.ProfileActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.settings.SettingsActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.settings.SettingsActivity"/>
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.settings.SettingsActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.editor.FeatureCategoryActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
android:name="com.mapswithme.maps.editor.FeatureCategoryActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.editor.ReportActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
android:name="com.mapswithme.maps.editor.ReportActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.editor.OsmAuthActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
android:name="com.mapswithme.maps.editor.OsmAuthActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.gallery.GalleryActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.gallery.FullScreenGalleryActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.review.ReviewActivity"
|
||||
android:parentActivityName="com.mapswithme.maps.MwmActivity">
|
||||
<!-- The meta-data element is needed for versions lower than 4.1 -->
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.mapswithme.maps.MwmActivity"/>
|
||||
</activity>
|
||||
|
||||
<!-- facebook -->
|
||||
|
@ -346,17 +373,17 @@
|
|||
</receiver>
|
||||
|
||||
<!-- PushWoosh -->
|
||||
<activity android:name="com.pushwoosh.richpages.RichPageActivity" />
|
||||
<activity android:name="com.pushwoosh.MessageActivity" />
|
||||
<activity android:name="com.pushwoosh.PushHandlerActivity" />
|
||||
<activity android:name="com.pushwoosh.richpages.RichPageActivity"/>
|
||||
<activity android:name="com.pushwoosh.MessageActivity"/>
|
||||
<activity android:name="com.pushwoosh.PushHandlerActivity"/>
|
||||
|
||||
<receiver
|
||||
android:name="com.google.android.gms.gcm.GcmReceiver"
|
||||
android:exported="true"
|
||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
android:permission="com.google.android.c2dm.permission.SEND">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||
<category android:name="${applicationId}" />
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
|
||||
<category android:name="${applicationId}"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
@ -378,10 +405,10 @@
|
|||
|
||||
<service
|
||||
android:name="com.pushwoosh.GCMRegistrationService"
|
||||
android:exported="false" />
|
||||
android:exported="false"/>
|
||||
|
||||
<service
|
||||
android:name="com.pushwoosh.location.GeoLocationService" />
|
||||
android:name="com.pushwoosh.location.GeoLocationService"/>
|
||||
|
||||
<!-- Catches app upgraded intent -->
|
||||
<receiver android:name=".background.UpgradeReceiver">
|
||||
|
|
|
@ -57,6 +57,8 @@ dependencies {
|
|||
// TODO remove this library when default LinearLayoutManager will be fixed.
|
||||
compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
|
||||
compile 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
|
||||
//Glide
|
||||
compile 'com.github.bumptech.glide:glide:3.7.0'
|
||||
}
|
||||
|
||||
def getDate() {
|
||||
|
@ -93,15 +95,15 @@ android {
|
|||
// Crashlytics API key
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream("${projectDir}/fabric.properties"));
|
||||
manifestPlaceholders = [ 'FABRIC_API_KEY': props['apiKey'] ]
|
||||
manifestPlaceholders = ['FABRIC_API_KEY': props['apiKey']]
|
||||
buildConfigField 'String', 'FABRIC_API_KEY', /"${props['apiKey']}"/
|
||||
|
||||
// PushWoosh keys
|
||||
Properties pwProps = new Properties()
|
||||
pwProps.load(new FileInputStream("${projectDir}/pushwoosh.properties"));
|
||||
manifestPlaceholders += [ 'PW_APPID': pwProps['pwAppId'] ]
|
||||
manifestPlaceholders += ['PW_APPID': pwProps['pwAppId']]
|
||||
buildConfigField 'String', 'PW_APPID', /"${pwProps['pwAppId']}"/
|
||||
manifestPlaceholders += [ 'PW_PROJECT_ID': pwProps['pwProjectId'] ]
|
||||
manifestPlaceholders += ['PW_PROJECT_ID': pwProps['pwProjectId']]
|
||||
}
|
||||
|
||||
sourceSets.main {
|
||||
|
@ -210,13 +212,6 @@ android {
|
|||
android.sourceSets.blackberry.assets.srcDirs = ['flavors/mwm-ttf-assets']
|
||||
buildConfigField 'String', 'REVIEW_URL', '"https://appworld.blackberry.com/webstore/content/51013892"'
|
||||
}
|
||||
|
||||
nineStore {
|
||||
versionName = android.defaultConfig.versionName + '-NineStore'
|
||||
android.sourceSets.blackberry.assets.srcDirs = ['flavors/mwm-ttf-assets']
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"ninestore@mapswithme.com"'
|
||||
buildConfigField 'String', 'REVIEW_URL', '"http://www.ninestore.ru/android-apps/mapswithme-maps-pro"'
|
||||
}
|
||||
}
|
||||
|
||||
// Currently (as of 1.2.3 gradle plugin) ABI filters aren't supported inside of product flavors, so we cannot generate splitted builds only for Google build.
|
||||
|
@ -331,7 +326,7 @@ if (System.properties['os.name'].toLowerCase().contains('windows'))
|
|||
project.ext.NDK_BUILD += ".cmd"
|
||||
|
||||
def archs = ['x86', 'armeabi-v7a-hard']
|
||||
def buildTypes = [[ndkType: 'release', cppType: "production", flags : propReleaseNdkFlags], [ndkType: 'debug', cppType: "debug", flags : propDebugNdkFlags]]
|
||||
def buildTypes = [[ndkType: 'release', cppType: "production", flags: propReleaseNdkFlags], [ndkType: 'debug', cppType: "debug", flags: propDebugNdkFlags]]
|
||||
|
||||
buildTypes.each { type ->
|
||||
def suffix = type.ndkType.capitalize()
|
||||
|
@ -408,14 +403,14 @@ obbGenerate.dependsOn obbClean, obbMainGenerate, obbPatchGenerate, obbMainAlign,
|
|||
|
||||
def createObbGenerateTask(type, data, name) {
|
||||
return tasks.create(name: "obb${type}Generate", type: Exec, description: 'Generate obb files') {
|
||||
commandLine ((['zip', '-0', '-j', name, data]).flatten())
|
||||
commandLine((['zip', '-0', '-j', name, data]).flatten())
|
||||
}
|
||||
}
|
||||
|
||||
def createObbAlignTask(type, rawObb, alignedObb) {
|
||||
def sdkDir = "${android.getSdkDirectory().getAbsolutePath()}"
|
||||
def zipalignPath = sdkDir + File.separator + "build-tools" + File.separator +
|
||||
propBuildToolsVersion + File.separator + "zipalign";
|
||||
propBuildToolsVersion + File.separator + "zipalign";
|
||||
|
||||
return tasks.create(name: "obb${type}Align", dependsOn: "obb${type}Generate", type: Exec, description: 'Align obb files') {
|
||||
commandLine zipalignPath, '-v', '8', rawObb, alignedObb
|
||||
|
|
|
@ -476,6 +476,12 @@ void Framework::RequestBookingMinPrice(string const & hotelId, string const & cu
|
|||
return m_work.GetBookingApi().GetMinPrice(hotelId, currencyCode, callback);
|
||||
}
|
||||
|
||||
void Framework::RequestBookingInfo(string const & hotelId, string const & lang,
|
||||
function<void(BookingApi::HotelInfo const &)> const & callback)
|
||||
{
|
||||
return m_work.GetBookingApi().GetHotelInfo(hotelId, lang, callback);
|
||||
}
|
||||
|
||||
bool Framework::HasSpaceForMigration()
|
||||
{
|
||||
return m_work.IsEnoughSpaceForMigrate();
|
||||
|
|
|
@ -155,6 +155,8 @@ namespace android
|
|||
void SetPlacePageInfo(place_page::Info const & info);
|
||||
place_page::Info & GetPlacePageInfo();
|
||||
void RequestBookingMinPrice(string const & hotelId, string const & currency, function<void(string const &, string const &)> const & callback);
|
||||
void RequestBookingInfo(string const & hotelId, string const & lang,
|
||||
function<void(BookingApi::HotelInfo const &)> const & callback);
|
||||
|
||||
bool HasSpaceForMigration();
|
||||
storage::TCountryId PreMigrate(ms::LatLon const & position, storage::Storage::TChangeCountryFunction const & statusChangeListener,
|
||||
|
|
|
@ -2,16 +2,28 @@
|
|||
|
||||
#include "../core/jni_helper.hpp"
|
||||
#include "../platform/Platform.hpp"
|
||||
#include "map/booking_api.hpp"
|
||||
#include "map/place_page_info.hpp"
|
||||
|
||||
#include "std/bind.hpp"
|
||||
#include "std/chrono.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
jclass g_hotelClass;
|
||||
jmethodID g_hotelClassCtor;
|
||||
jclass g_facilityTypeClass;
|
||||
jclass g_nearbyObjectClass;
|
||||
jclass g_imageClass;
|
||||
jclass g_reviewClass;
|
||||
jclass g_hotelInfoClass;
|
||||
jmethodID g_facilityConstructor;
|
||||
jmethodID g_nearbyConstructor;
|
||||
jmethodID g_imageConstructor;
|
||||
jmethodID g_reviewConstructor;
|
||||
jmethodID g_hotelInfoConstructor;
|
||||
jmethodID g_hotelClassConstructor;
|
||||
jmethodID g_priceCallback;
|
||||
jmethodID g_infoCallback;
|
||||
|
||||
void PrepareClassRefs(JNIEnv * env, jclass hotelClass)
|
||||
{
|
||||
|
@ -19,21 +31,51 @@ void PrepareClassRefs(JNIEnv * env, jclass hotelClass)
|
|||
return;
|
||||
|
||||
g_hotelClass = static_cast<jclass>(env->NewGlobalRef(hotelClass));
|
||||
g_hotelInfoClass =
|
||||
jni::GetGlobalClassRef(env, "com/mapswithme/maps/widget/placepage/SponsoredHotel$HotelInfo");
|
||||
g_facilityTypeClass = jni::GetGlobalClassRef(
|
||||
env, "com/mapswithme/maps/widget/placepage/SponsoredHotel$FacilityType");
|
||||
g_nearbyObjectClass = jni::GetGlobalClassRef(
|
||||
env, "com/mapswithme/maps/widget/placepage/SponsoredHotel$NearbyObject");
|
||||
g_reviewClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/review/Review");
|
||||
g_imageClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/gallery/Image");
|
||||
|
||||
g_facilityConstructor =
|
||||
jni::GetConstructorID(env, g_facilityTypeClass, "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
g_nearbyConstructor = jni::GetConstructorID(
|
||||
env, g_nearbyObjectClass, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DD)V");
|
||||
g_imageConstructor =
|
||||
jni::GetConstructorID(env, g_imageClass, "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
g_reviewConstructor = jni::GetConstructorID(env, g_reviewClass,
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
|
||||
"String;Ljava/lang/String;Ljava/lang/String;FJ)V");
|
||||
g_hotelInfoConstructor = jni::GetConstructorID(
|
||||
env, g_hotelInfoClass,
|
||||
"(Ljava/lang/String;[Lcom/mapswithme/maps/gallery/Image;[Lcom/mapswithme/maps/widget/"
|
||||
"placepage/SponsoredHotel$FacilityType;[Lcom/mapswithme/maps/review/Review;[Lcom/mapswithme/"
|
||||
"maps/widget/placepage/SponsoredHotel$NearbyObject;)V");
|
||||
|
||||
// SponsoredHotel(String rating, String price, String urlBook, String urlDescription)
|
||||
g_hotelClassCtor = jni::GetConstructorID(env, g_hotelClass, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
g_hotelClassConstructor = jni::GetConstructorID(
|
||||
env, g_hotelClass,
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
// static void onPriceReceived(final String id, final String price, final String currency)
|
||||
g_priceCallback = jni::GetStaticMethodID(env, g_hotelClass, "onPriceReceived", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
g_priceCallback =
|
||||
jni::GetStaticMethodID(env, g_hotelClass, "onPriceReceived",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
// static void onDescriptionReceived(final String id, final String description)
|
||||
g_infoCallback = jni::GetStaticMethodID(
|
||||
env, g_hotelClass, "onInfoReceived",
|
||||
"(Ljava/lang/String;Lcom/mapswithme/maps/widget/placepage/SponsoredHotel$HotelInfo;)V");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
|
||||
// static SponsoredHotel nativeGetCurrent();
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeGetCurrent(JNIEnv * env, jclass clazz)
|
||||
JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeGetCurrent(
|
||||
JNIEnv * env, jclass clazz)
|
||||
{
|
||||
PrepareClassRefs(env, clazz);
|
||||
|
||||
|
@ -41,31 +83,79 @@ Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeGetCurrent(JNIEnv
|
|||
if (!ppInfo.m_isSponsoredHotel)
|
||||
return nullptr;
|
||||
|
||||
return env->NewObject(g_hotelClass, g_hotelClassCtor, jni::ToJavaString(env, ppInfo.GetRatingFormatted()),
|
||||
jni::ToJavaString(env, ppInfo.GetApproximatePricing()),
|
||||
jni::ToJavaString(env, ppInfo.GetSponsoredBookingUrl()),
|
||||
jni::ToJavaString(env, ppInfo.GetSponsoredDescriptionUrl()));
|
||||
return env->NewObject(g_hotelClass, g_hotelClassConstructor,
|
||||
jni::ToJavaString(env, ppInfo.GetRatingFormatted()),
|
||||
jni::ToJavaString(env, ppInfo.GetApproximatePricing()),
|
||||
jni::ToJavaString(env, ppInfo.GetSponsoredBookingUrl()),
|
||||
jni::ToJavaString(env, ppInfo.GetSponsoredDescriptionUrl()));
|
||||
}
|
||||
|
||||
// static void nativeRequestPrice(String id, String currencyCode);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeRequestPrice(JNIEnv * env, jclass clazz, jstring id, jstring currencyCode)
|
||||
JNIEXPORT void JNICALL Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeRequestPrice(
|
||||
JNIEnv * env, jclass clazz, jstring id, jstring currencyCode)
|
||||
{
|
||||
PrepareClassRefs(env, clazz);
|
||||
|
||||
string const hotelId = jni::ToNativeString(env, id);
|
||||
string const code = jni::ToNativeString(env, currencyCode);
|
||||
|
||||
g_framework->RequestBookingMinPrice(hotelId, code, [hotelId](string const & price, string const & currency)
|
||||
{
|
||||
GetPlatform().RunOnGuiThread([=]()
|
||||
{
|
||||
g_framework->RequestBookingMinPrice(hotelId, code, [hotelId](string const & price,
|
||||
string const & currency) {
|
||||
GetPlatform().RunOnGuiThread([=]() {
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
env->CallStaticVoidMethod(g_hotelClass, g_priceCallback, jni::ToJavaString(env, hotelId),
|
||||
jni::ToJavaString(env, price),
|
||||
jni::ToJavaString(env, currency));
|
||||
jni::ToJavaString(env, price), jni::ToJavaString(env, currency));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
// static void nativeRequestInfo(String id, String locale);
|
||||
JNIEXPORT void JNICALL Java_com_mapswithme_maps_widget_placepage_SponsoredHotel_nativeRequestInfo(
|
||||
JNIEnv * env, jclass clazz, jstring id, jstring locale)
|
||||
{
|
||||
PrepareClassRefs(env, clazz);
|
||||
|
||||
string const hotelId = jni::ToNativeString(env, id);
|
||||
string const code = jni::ToNativeString(env, locale);
|
||||
|
||||
g_framework->RequestBookingInfo(hotelId, code, [hotelId](
|
||||
BookingApi::HotelInfo const & hotelInfo) {
|
||||
GetPlatform().RunOnGuiThread([=]() {
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
|
||||
auto description = jni::ToJavaString(env, hotelInfo.m_description);
|
||||
auto photos =
|
||||
jni::ToJavaArray(env, g_imageClass, hotelInfo.m_photos,
|
||||
[](JNIEnv * env, BookingApi::HotelPhotoUrls const & item) {
|
||||
return env->NewObject(g_imageClass, g_imageConstructor,
|
||||
jni::ToJavaString(env, item.m_original),
|
||||
jni::ToJavaString(env, item.m_small));
|
||||
});
|
||||
auto facilities =
|
||||
jni::ToJavaArray(env, g_facilityTypeClass, hotelInfo.m_facilities,
|
||||
[](JNIEnv * env, BookingApi::Facility const & item) {
|
||||
return env->NewObject(g_facilityTypeClass, g_facilityConstructor,
|
||||
jni::ToJavaString(env, item.m_id),
|
||||
jni::ToJavaString(env, item.m_localizedName));
|
||||
});
|
||||
auto reviews = jni::ToJavaArray(
|
||||
env, g_reviewClass, hotelInfo.m_reviews,
|
||||
[](JNIEnv * env, BookingApi::HotelReview const & item) {
|
||||
return env->NewObject(
|
||||
g_reviewClass, g_reviewConstructor, jni::ToJavaString(env, item.m_reviewNeutral),
|
||||
jni::ToJavaString(env, item.m_reviewPositive),
|
||||
jni::ToJavaString(env, item.m_reviewNegative),
|
||||
jni::ToJavaString(env, item.m_author), jni::ToJavaString(env, item.m_authorPictUrl),
|
||||
item.m_rating,
|
||||
time_point_cast<milliseconds>(item.m_date).time_since_epoch().count());
|
||||
});
|
||||
auto nearby = env->NewObjectArray(0, g_nearbyObjectClass, 0);
|
||||
|
||||
env->CallStaticVoidMethod(g_hotelClass, g_infoCallback, jni::ToJavaString(env, hotelId),
|
||||
env->NewObject(g_hotelInfoClass, g_hotelInfoConstructor,
|
||||
description, photos, facilities, reviews, nearby));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
8
android/res/drawable/bg_circle_green.xml
Normal file
8
android/res/drawable/bg_circle_green.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bg_placepage_rating_positive"/>
|
||||
<size
|
||||
android:height="@dimen/placepage_margin_rating"
|
||||
android:width="@dimen/placepage_margin_rating"/>
|
||||
</shape>
|
8
android/res/drawable/bg_circle_green_night.xml
Normal file
8
android/res/drawable/bg_circle_green_night.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bg_placepage_rating_positive_night"/>
|
||||
<size
|
||||
android:height="@dimen/placepage_margin_rating"
|
||||
android:width="@dimen/placepage_margin_rating"/>
|
||||
</shape>
|
8
android/res/drawable/bg_circle_red.xml
Normal file
8
android/res/drawable/bg_circle_red.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bg_placepage_rating_negative"/>
|
||||
<size
|
||||
android:height="@dimen/placepage_margin_rating"
|
||||
android:width="@dimen/placepage_margin_rating"/>
|
||||
</shape>
|
8
android/res/drawable/bg_circle_red_night.xml
Normal file
8
android/res/drawable/bg_circle_red_night.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bg_placepage_rating_negative_night"/>
|
||||
<size
|
||||
android:height="@dimen/placepage_margin_rating"
|
||||
android:width="@dimen/placepage_margin_rating"/>
|
||||
</shape>
|
6
android/res/drawable/divider_transparent.xml
Normal file
6
android/res/drawable/divider_transparent.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<size android:width="@dimen/margin_quarter"
|
||||
android:height="@dimen/margin_quarter"/>
|
||||
<solid android:color="@android:color/transparent"/>
|
||||
</shape>
|
9
android/res/drawable/ic_chevron_right_white.xml
Normal file
9
android/res/drawable/ic_chevron_right_white.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
|
||||
</vector>
|
8
android/res/drawable/ic_minus_red.xml
Normal file
8
android/res/drawable/ic_minus_red.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<vector android:height="10dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:width="10dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FFF44336"
|
||||
android:pathData="M19,13H5v-2h14v2z"/>
|
||||
</vector>
|
15
android/res/drawable/ic_negative_review.xml
Normal file
15
android/res/drawable/ic_negative_review.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/bg_circle_red"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
<item
|
||||
android:drawable="@drawable/ic_minus_red"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
</layer-list>
|
15
android/res/drawable/ic_negative_review_night.xml
Normal file
15
android/res/drawable/ic_negative_review_night.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/bg_circle_red_night"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
<item
|
||||
android:drawable="@drawable/ic_minus_red"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
</layer-list>
|
8
android/res/drawable/ic_plus_green.xml
Normal file
8
android/res/drawable/ic_plus_green.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<vector android:height="10dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:width="10dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF578B2D"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||
</vector>
|
15
android/res/drawable/ic_positive_review.xml
Normal file
15
android/res/drawable/ic_positive_review.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/bg_circle_green"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
<item
|
||||
android:drawable="@drawable/ic_plus_green"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
</layer-list>
|
15
android/res/drawable/ic_positive_review_night.xml
Normal file
15
android/res/drawable/ic_positive_review_night.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/bg_circle_green_night"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
<item
|
||||
android:drawable="@drawable/ic_plus_green"
|
||||
android:left="@dimen/margin_eighth"
|
||||
android:right="@dimen/margin_eighth"
|
||||
android:bottom="@dimen/margin_eighth"
|
||||
android:top="@dimen/margin_eighth"/>
|
||||
</layer-list>
|
|
@ -47,6 +47,12 @@
|
|||
android:layout_toLeftOf="@id/anchor_center"
|
||||
android:layout_toStartOf="@id/anchor_center"
|
||||
android:orientation="vertical">
|
||||
<include layout="@layout/place_page_hotel_gallery"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_facilities"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_description"/>
|
||||
|
||||
<include layout="@layout/place_page_placename"/>
|
||||
|
||||
<include layout="@layout/place_page_entrance"/>
|
||||
|
@ -82,7 +88,13 @@
|
|||
|
||||
<include layout="@layout/place_page_cuisine"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_nearby"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_rating"/>
|
||||
|
||||
<!--TODO: remove this after booking_api.cpp will be done-->
|
||||
<include layout="@layout/place_page_more"/>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
|
94
android/res/layout/activity_full_screen_gallery.xml
Normal file
94
android/res/layout/activity_full_screen_gallery.xml
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/vp__image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<include
|
||||
layout="@layout/toolbar_transparent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:layout_gravity="bottom">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:textColor="@color/white_primary"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:maxLines="1"
|
||||
tools:text="Staff, rooftop view, location, free bike…"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl__user_block"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/divider_gallery"/>
|
||||
<ImageView
|
||||
android:id="@+id/iv__avatar"
|
||||
android:layout_width="@dimen/track_circle_size"
|
||||
android:layout_height="@dimen/track_circle_size"
|
||||
android:layout_marginTop="@dimen/margin_half"
|
||||
android:layout_below="@id/divider"
|
||||
android:layout_marginRight="@dimen/margin_half"
|
||||
android:layout_marginEnd="@dimen/margin_half"
|
||||
tools:src="@drawable/img_editor_medal"/>
|
||||
<TextView
|
||||
android:id="@+id/tv__name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_half"
|
||||
android:layout_toRightOf="@id/iv__avatar"
|
||||
android:layout_toEndOf="@id/iv__avatar"
|
||||
android:layout_below="@id/divider"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white_primary"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
tools:text="Polina"/>
|
||||
<TextView
|
||||
android:id="@+id/tv__source"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/iv__avatar"
|
||||
android:layout_toEndOf="@id/iv__avatar"
|
||||
android:layout_below="@id/tv__name"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white_primary"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body4"
|
||||
tools:text="via Booking"/>
|
||||
<TextView
|
||||
android:id="@+id/tv__date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/tv__source"
|
||||
android:layout_toEndOf="@id/tv__source"
|
||||
android:layout_alignBaseline="@id/tv__source"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white_primary"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body4"
|
||||
tools:text="Jule 8, 2016"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
13
android/res/layout/fragment_fullscreen_image.xml
Normal file
13
android/res/layout/fragment_fullscreen_image.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
16
android/res/layout/fragment_gallery.xml
Normal file
16
android/res/layout/fragment_gallery.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv__gallery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/margin_half"
|
||||
android:paddingRight="@dimen/margin_half"
|
||||
android:paddingTop="@dimen/margin_half_plus"
|
||||
tools:listitem="@layout/item_image"/>
|
||||
</LinearLayout>
|
13
android/res/layout/fragment_review.xml
Normal file
13
android/res/layout/fragment_review.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?cardBackground">
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv__review"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/item_comment"/>
|
||||
</LinearLayout>
|
122
android/res/layout/item_comment.xml
Normal file
122
android/res/layout/item_comment.xml
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:id="@+id/v__divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:background="?dividerHorizontal"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__user_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:layout_toLeftOf="@+id/tv__user_rating"
|
||||
android:layout_toStartOf="@+id/tv__user_rating"
|
||||
android:layout_below="@id/v__divider"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
tools:text="Аleksey"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__comment_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:layout_below="@id/tv__user_name"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body4"
|
||||
tools:text="March 29, 2016"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__user_rating"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@id/v__divider"
|
||||
android:textAppearance="@style/MwmTextAppearance.Headline"
|
||||
tools:text="9.2"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__review"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:layout_below="@id/tv__comment_date"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3.Primary"
|
||||
android:visibility="gone"
|
||||
tools:text="Interesting place among SoHo, Little Italy and China town. Modern design. Great view from roof. Near subway. Free refreshment every afternoon. The staff was very friendly."/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll__positive_review"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/tv__comment_date">
|
||||
<ImageView
|
||||
android:layout_width="@dimen/margin_base_plus"
|
||||
android:layout_height="@dimen/margin_base_plus"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:src="?ppPositive"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__positive_review"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_double"
|
||||
android:layout_marginStart="@dimen/margin_double"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:paddingTop="@dimen/margin_eighth"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3.Primary"
|
||||
tools:text="Interesting place among SoHo, Little Italy and China town. Modern design. Great view from roof. Near subway. Free refreshment every afternoon. The staff was very friendly."/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll__negative_review"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ll__positive_review">
|
||||
<ImageView
|
||||
android:id="@+id/iv__negative_review"
|
||||
android:layout_width="@dimen/margin_base_plus"
|
||||
android:layout_height="@dimen/margin_base_plus"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:src="?ppNegative"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__negative_review"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_double"
|
||||
android:layout_marginStart="@dimen/margin_double"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:paddingTop="@dimen/margin_eighth"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3.Primary"
|
||||
tools:text="Little bit noise from outsideLittle bit noise from outside"/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
24
android/res/layout/item_facility.xml
Normal file
24
android/res/layout/item_facility.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/height_block_base"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?clickableBackground"
|
||||
android:clickable="true"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__icon"
|
||||
style="@style/PlacePageMetadataIcon"
|
||||
android:src="@drawable/ic_entrance"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__facility"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3.Primary"
|
||||
tools:text="Pets are allowed on request"/>
|
||||
</LinearLayout>
|
22
android/res/layout/item_gallery.xml
Normal file
22
android/res/layout/item_gallery.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/placepage_hotel_gallery_width"
|
||||
android:layout_height="@dimen/placepage_hotel_gallery_height"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__image"
|
||||
android:layout_width="@dimen/placepage_hotel_gallery_width"
|
||||
android:layout_height="@dimen/placepage_hotel_gallery_height"
|
||||
tools:src="@color/base_green"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__more"
|
||||
style="@style/PlacePageGalleryText"
|
||||
android:text="@string/placepage_more_button"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
</FrameLayout>
|
15
android/res/layout/item_image.xml
Normal file
15
android/res/layout/item_image.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gallery_image_height"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gallery_image_height"
|
||||
tools:src="@color/base_green"/>
|
||||
</FrameLayout>
|
8
android/res/layout/item_more_button.xml
Normal file
8
android/res/layout/item_more_button.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/PlacePageMetadataText.Button"
|
||||
android:height="@dimen/height_block_base"
|
||||
android:background="?clickableBackground"
|
||||
android:gravity="center"
|
||||
android:text="@string/placepage_more_reviews_button"/>
|
66
android/res/layout/item_nearby.xml
Normal file
66
android/res/layout/item_nearby.xml
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:paddingTop="@dimen/margin_half_plus"
|
||||
android:paddingBottom="@dimen/margin_half_plus"
|
||||
android:paddingRight="@dimen/margin_base"
|
||||
android:paddingEnd="@dimen/margin_base"
|
||||
android:paddingLeft="@dimen/margin_base"
|
||||
android:paddingStart="@dimen/margin_base"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
tools:background="#4000FFFF">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__icon"
|
||||
android:layout_width="@dimen/placepage_hotel_nearby_icon_size"
|
||||
android:layout_height="@dimen/placepage_hotel_nearby_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
tools:src="@color/base_green"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll__info"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_double"
|
||||
android:layout_marginStart="@dimen/margin_double"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@id/iv__icon"
|
||||
android:layout_toEndOf="@id/iv__icon"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
tools:text="Bowery"/>
|
||||
<TextView
|
||||
android:id="@+id/tv__type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_quarter"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
tools:text="Subway Station"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@id/ll__info"
|
||||
android:layout_toEndOf="@id/ll__info"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/MwmTextAppearance.PlacePage.Accent"
|
||||
android:gravity="end"
|
||||
tools:text="800 ft"/>
|
||||
</RelativeLayout>
|
29
android/res/layout/item_rating.xml
Normal file
29
android/res/layout/item_rating.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/placepage_margin_rating"
|
||||
android:paddingBottom="@dimen/margin_base"
|
||||
android:paddingLeft="@dimen/margin_base"
|
||||
android:paddingRight="@dimen/margin_base"
|
||||
android:background="?ppRatingBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_rating"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textColor="?ppRatingText"
|
||||
tools:text="Rating: 8.7 (Excellent)"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_rating_base"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_half"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
tools:text="Based on 848 hotel reviews"/>
|
||||
</LinearLayout>
|
|
@ -27,6 +27,12 @@
|
|||
android:layout_marginBottom="@dimen/margin_half"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_gallery"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_facilities"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_description"/>
|
||||
|
||||
<include layout="@layout/place_page_placename"/>
|
||||
|
||||
<include layout="@layout/place_page_opening_hours"/>
|
||||
|
@ -49,6 +55,11 @@
|
|||
|
||||
<include layout="@layout/place_page_cuisine"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_nearby"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_rating"/>
|
||||
|
||||
<!--TODO: remove this after booking_api.cpp will be done-->
|
||||
<include layout="@layout/place_page_more"/>
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
|
|
43
android/res/layout/place_page_hotel_description.xml
Normal file
43
android/res/layout/place_page_hotel_description.xml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_hotel_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="@dimen/height_block_base"
|
||||
android:visibility="gone"
|
||||
tools:background="#20FF0000"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
style="@style/PlacePageTitleText"
|
||||
android:text="@string/details"/>
|
||||
|
||||
<com.mapswithme.maps.widget.LineCountTextView
|
||||
android:id="@+id/tv__place_hotel_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_half_plus"
|
||||
android:layout_marginBottom="@dimen/margin_half_plus"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3.Primary"
|
||||
android:maxLines="@integer/pp_hotel_description_lines"
|
||||
tools:text="One of our top picks in New York City. This boutique hotel in the Manhattan neighborhood of Nolita features a private rooftop and rooms with free WiFi. The Bowery subway station is 1 block from this New York hotel."/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_more"
|
||||
style="@style/PlacePageMetadataText.Button"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:height="@dimen/height_block_base"
|
||||
android:background="?clickableBackground"
|
||||
android:gravity="center"
|
||||
android:text="@string/placepage_more_button"/>
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
</LinearLayout>
|
42
android/res/layout/place_page_hotel_facilities.xml
Normal file
42
android/res/layout/place_page_hotel_facilities.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_hotel_facilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="@dimen/height_block_base"
|
||||
android:visibility="gone"
|
||||
tools:background="#4000FFFF"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
style="@style/PlacePageTitleText"
|
||||
android:text="@string/placepage_hotel_facilities"/>
|
||||
|
||||
<com.mapswithme.maps.widget.StaticGridView
|
||||
android:id="@+id/gv__place_hotel_facilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:numColumns="2"
|
||||
tools:listitem="@layout/item_facility"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_facilities_more"
|
||||
style="@style/PlacePageMetadataText.Button"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:height="@dimen/height_block_base"
|
||||
android:background="?clickableBackground"
|
||||
android:gravity="center"
|
||||
android:text="@string/placepage_more_button"/>
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
</LinearLayout>
|
18
android/res/layout/place_page_hotel_gallery.xml
Normal file
18
android/res/layout/place_page_hotel_gallery.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_hotel_gallery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/placepage_hotel_gallery_height"
|
||||
android:orientation="horizontal"
|
||||
android:minHeight="@dimen/placepage_hotel_gallery_height"
|
||||
android:visibility="gone"
|
||||
tools:background="#20FF0000"
|
||||
tools:visibility="visible">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv__place_hotel_gallery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/item_gallery"/>
|
||||
</LinearLayout>
|
29
android/res/layout/place_page_hotel_nearby.xml
Normal file
29
android/res/layout/place_page_hotel_nearby.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_hotel_nearby"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="@dimen/height_block_base"
|
||||
android:visibility="gone"
|
||||
tools:background="#4000FFFF"
|
||||
tools:visibility="visible">
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
style="@style/PlacePageTitleText"
|
||||
android:text="@string/placepage_hotel_nearby"/>
|
||||
|
||||
<com.mapswithme.maps.widget.StaticGridView
|
||||
android:id="@+id/gv__place_hotel_nearby"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_quarter"
|
||||
android:numColumns="1"
|
||||
tools:listitem="@layout/item_nearby"/>
|
||||
</LinearLayout>
|
58
android/res/layout/place_page_hotel_rating.xml
Normal file
58
android/res/layout/place_page_hotel_rating.xml
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_hotel_rating"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/placepage_margin_rating"
|
||||
android:paddingBottom="@dimen/margin_base"
|
||||
android:paddingLeft="@dimen/margin_base"
|
||||
android:paddingRight="@dimen/margin_base"
|
||||
android:background="?ppRatingBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_rating"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textColor="?ppRatingText"
|
||||
tools:text="Rating: 8.7 (Excellent)"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_rating_base"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_half"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
tools:text="Based on 848 hotel reviews"/>
|
||||
</LinearLayout>
|
||||
|
||||
<com.mapswithme.maps.widget.StaticGridView
|
||||
android:id="@+id/gv__place_hotel_review"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:numColumns="1"
|
||||
tools:listitem="@layout/item_comment"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="@dimen/margin_base"
|
||||
android:layout_marginRight="@dimen/margin_base"
|
||||
android:background="?dividerHorizontal"/>
|
||||
<TextView
|
||||
android:id="@+id/tv__place_hotel_reviews_more"
|
||||
style="@style/PlacePageMetadataText.Button"
|
||||
android:height="@dimen/height_block_base"
|
||||
android:background="?clickableBackground"
|
||||
android:gravity="center"
|
||||
android:text="@string/placepage_more_reviews_button"/>
|
||||
</LinearLayout>
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--TODO: remove this layout after booking_api.cpp will be done-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/ll__more"
|
||||
|
|
8
android/res/layout/toolbar_transparent.xml
Normal file
8
android/res/layout/toolbar_transparent.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.Toolbar
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/MwmWidget.ToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="@style/MwmWidget.ToolbarTheme.Transparent"/>
|
|
@ -879,6 +879,7 @@
|
|||
<string name="minute">мин</string>
|
||||
<string name="placepage_place_description">Описание</string>
|
||||
<string name="placepage_more_button">Ещё</string>
|
||||
<string name="placepage_more_reviews_button">Ещё отзывы</string>
|
||||
<string name="bookingcom_book_button">Забронировать</string>
|
||||
<string name="placepage_call_button">Позвонить</string>
|
||||
<string name="placepage_edit_bookmark_button">Редактировать метку</string>
|
||||
|
@ -964,4 +965,8 @@
|
|||
<string name="whats_new_route_profile_message">На пеших и веломаршрутах отображается профиль рельефа.</string>
|
||||
<string name="whats_new_booking_improve_title">Экономь на бронировании отеля</string>
|
||||
<string name="whats_new_booking_improve_message">Результаты поиска отелей на карте показывают ценовую категорию.\nОтелей для бронирования стало на 110 000 больше.</string>
|
||||
<!-- For place page hotel facilities block -->
|
||||
<string name="placepage_hotel_facilities">Удобства</string>
|
||||
<!-- For place page hotel nearby block -->
|
||||
<string name="placepage_hotel_nearby">Рядом</string>
|
||||
</resources>
|
||||
|
|
11
android/res/values-v16/strings.xml
Normal file
11
android/res/values-v16/strings.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Android Strings File -->
|
||||
<!-- Generated by Twine 0.6.0 -->
|
||||
<!-- Language: v16 -->
|
||||
<resources>
|
||||
<!-- SECTION: Strings -->
|
||||
|
||||
<!-- SECTION: Routing dialogs strings -->
|
||||
|
||||
<!-- SECTION: Strings for downloading map from search -->
|
||||
</resources>
|
7
android/res/values-v16/styles-text.xml
Normal file
7
android/res/values-v16/styles-text.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="MwmTextAppearance.PlacePage.Title"
|
||||
parent="MwmTextAppearance.Body3">
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
</resources>
|
11
android/res/values-w840dp/strings.xml
Normal file
11
android/res/values-w840dp/strings.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Android Strings File -->
|
||||
<!-- Generated by Twine 0.6.0 -->
|
||||
<!-- Language: w840dp -->
|
||||
<resources>
|
||||
<!-- SECTION: Strings -->
|
||||
|
||||
<!-- SECTION: Routing dialogs strings -->
|
||||
|
||||
<!-- SECTION: Strings for downloading map from search -->
|
||||
</resources>
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
<color name="divider">#1E000000</color>
|
||||
<color name="divider_night">#1EFFFFFF</color>
|
||||
<color name="divider_gallery">#66FFFFFF</color>
|
||||
|
||||
<color name="text_placepage_rating">#568B2E</color>
|
||||
<color name="text_placepage_rating_night">#46A046</color>
|
||||
|
||||
<!-- Backgrounds -->
|
||||
<color name="bg_window">#FFEEEEEE</color>
|
||||
|
@ -59,6 +63,13 @@
|
|||
<color name="bg_azimut_arrow">#1D414651</color>
|
||||
<color name="fg_azimut_arrow">#FFFFFFFF</color>
|
||||
|
||||
<color name="bg_placepage_rating">#F1F8E9</color>
|
||||
<color name="bg_placepage_rating_night">#1EF0FAEB</color>
|
||||
<color name="bg_placepage_rating_positive">#DCEDC8</color>
|
||||
<color name="bg_placepage_rating_positive_night">#1EF0FAEB</color>
|
||||
<color name="bg_placepage_rating_negative">#FFCDD2</color>
|
||||
<color name="bg_placepage_rating_negative_night">#1EFFEBF0</color>
|
||||
|
||||
<!-- Buttons -->
|
||||
<color name="button">@color/button_normal</color>
|
||||
<color name="button_night">@color/button_normal_night</color>
|
||||
|
|
|
@ -145,6 +145,16 @@
|
|||
<dimen name="altitude_chart_image_height">40dp</dimen>
|
||||
<dimen name="altitude_chart_image_width">232dp</dimen>
|
||||
|
||||
<!-- Gallery-->
|
||||
<dimen name="placepage_hotel_gallery_height">100dp</dimen>
|
||||
<dimen name="placepage_hotel_gallery_width">150dp</dimen>
|
||||
<dimen name="gallery_image_height">84dp</dimen>
|
||||
|
||||
<!-- Nearby-->
|
||||
<dimen name="placepage_hotel_nearby_height">64dp</dimen>
|
||||
<dimen name="placepage_hotel_nearby_icon_size">24dp</dimen>
|
||||
|
||||
<!-- Rating-->
|
||||
<dimen name="placepage_margin_rating">20dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<resources>
|
||||
<integer name="pp_title_lines">5</integer>
|
||||
<integer name="pp_buttons_max">4</integer>
|
||||
<integer name="pp_hotel_description_lines">5</integer>
|
||||
|
||||
<integer name="sharing_initial_rows">2</integer>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
11
android/res/values/plurals.xml
Normal file
11
android/res/values/plurals.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="place_page_booking_rating_base">
|
||||
<item quantity="zero">Based on %d hotel reviews</item>
|
||||
<item quantity="one">Based on %d hotel reviews</item>
|
||||
<item quantity="two">Based on %d hotel reviews</item>
|
||||
<item quantity="few">Based on %d hotel reviews</item>
|
||||
<item quantity="many">Based on %d hotel reviews</item>
|
||||
<item quantity="other">Based on %d hotel reviews</item>
|
||||
</plurals>
|
||||
</resources>
|
|
@ -883,6 +883,7 @@
|
|||
<string name="minute">min</string>
|
||||
<string name="placepage_place_description">Description</string>
|
||||
<string name="placepage_more_button">More</string>
|
||||
<string name="placepage_more_reviews_button">More Reviews</string>
|
||||
<string name="bookingcom_book_button">Book</string>
|
||||
<string name="placepage_call_button">Call</string>
|
||||
<string name="placepage_edit_bookmark_button">Edit Bookmark</string>
|
||||
|
@ -968,4 +969,8 @@
|
|||
<string name="whats_new_route_profile_message">For pedestrian and bike routes we now display the elevation profile.</string>
|
||||
<string name="whats_new_booking_improve_title">Save when booking hotels</string>
|
||||
<string name="whats_new_booking_improve_message">Search results for hotels now contain the price category.\nWe also added more than 110,000 hotels.</string>
|
||||
<!-- For place page hotel facilities block -->
|
||||
<string name="placepage_hotel_facilities">Facilities</string>
|
||||
<!-- For place page hotel nearby block -->
|
||||
<string name="placepage_hotel_nearby">Nearby</string>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,23 @@
|
|||
<item name="android:textAppearance">@style/MwmTextAppearance.PlacePage.Accent</item>
|
||||
</style>
|
||||
|
||||
<style name="PlacePageTitleText">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textAppearance">@style/MwmTextAppearance.PlacePage.Title</item>
|
||||
</style>
|
||||
|
||||
<style name="PlacePageGalleryText">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textColor">@color/white_primary</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
<item name="android:drawableRight">@drawable/ic_chevron_right_white</item>
|
||||
<item name="android:drawableEnd" tools:targetApi="jelly_bean_mr1">@drawable/ic_chevron_right_white</item>
|
||||
</style>
|
||||
|
||||
<style name="PlacePageMetadataIcon">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
|
@ -66,4 +83,4 @@
|
|||
<item name="android:layout_marginEnd" tools:targetApi="jelly_bean_mr1">@dimen/margin_base</item>
|
||||
<item name="android:layout_marginRight">@dimen/margin_base</item>
|
||||
</style>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -53,6 +53,11 @@
|
|||
<item name="android:textColor">?android:textColorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.Body3.Primary">
|
||||
<item name="android:textSize">@dimen/text_size_body_3</item>
|
||||
<item name="android:textColor">?android:textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.Body3.Light">
|
||||
<item name="android:textColor">?android:textColorPrimaryInverse</item>
|
||||
</style>
|
||||
|
@ -116,6 +121,10 @@
|
|||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.RoutingDimension.Inline" parent="MwmTextAppearance.RoutingNumber">
|
||||
<item name="android:textSize">@dimen/text_size_routing_dimension_inline</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.RoutingDetail">
|
||||
<item name="android:textSize">@dimen/text_size_routing_plan_detail</item>
|
||||
<item name="android:fontFamily" tools:ignore="NewApi">@string/robotoMedium</item>
|
||||
|
@ -143,13 +152,14 @@
|
|||
<item name="android:textSize">@dimen/text_size_nav_circle_exit</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.PlacePage"
|
||||
parent="MwmTextAppearance.Body1"/>
|
||||
<style name="MwmTextAppearance.PlacePage" parent="MwmTextAppearance.Body1"/>
|
||||
|
||||
<style name="MwmTextAppearance.PlacePage.Accent">
|
||||
<item name="android:textColor">?colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.PlacePage.Title" parent="MwmTextAppearance.Body3"/>
|
||||
|
||||
<style name="MwmTextAppearance.Editor">
|
||||
</style>
|
||||
|
||||
|
@ -161,4 +171,4 @@
|
|||
<style name="MwmTextAppearance.Editor.Buttons">
|
||||
<item name="android:textSize">@dimen/text_size_body_3</item>
|
||||
</style>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
<item name="android:layout_marginLeft">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.MapButton"
|
||||
parent="android:Widget.ImageButton">
|
||||
<style name="MwmWidget.MapButton" parent="android:Widget.ImageButton">
|
||||
<item name="android:scaleType">center</item>
|
||||
<item name="android:layout_height">64dp</item>
|
||||
<item name="android:layout_width">64dp</item>
|
||||
|
@ -53,73 +52,56 @@
|
|||
</style>
|
||||
|
||||
<style name="MwmWidget.Floating">
|
||||
<item name="android:elevation"
|
||||
tools:ignore="NewApi">@dimen/appbar_elevation
|
||||
</item>
|
||||
<item name="android:elevation" tools:ignore="NewApi">@dimen/appbar_elevation</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.Floating.Panel">
|
||||
<item name="android:background">?panel</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.PlacePage.EditText"
|
||||
parent="Widget.AppCompat.EditText">
|
||||
<style name="MwmWidget.PlacePage.EditText" parent="Widget.AppCompat.EditText">
|
||||
<item name="android:imeOptions">actionDone</item>
|
||||
<item name="android:textAppearance">@style/MwmTextAppearance.PlacePage</item>
|
||||
<item name="android:textColorHint">?secondary</item>
|
||||
<item name="android:textCursorDrawable">@null</item>
|
||||
<item name="android:fontFamily"
|
||||
tools:ignore="NewApi">@string/robotoRegular
|
||||
</item>
|
||||
<item name="android:fontFamily" tools:ignore="NewApi">@string/robotoRegular</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.ToolbarStyle"
|
||||
parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<style name="MwmWidget.ToolbarStyle" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<item name="android:background">?colorPrimary</item>
|
||||
<item name="android:elevation"
|
||||
tools:ignore="NewApi">@dimen/appbar_elevation
|
||||
</item>
|
||||
<item name="android:elevation" tools:ignore="NewApi">@dimen/appbar_elevation</item>
|
||||
<item name="android:displayOptions">homeAsUp|showTitle</item>
|
||||
<item name="contentInsetStart">72dp</item>
|
||||
<item name="android:titleTextAppearance"
|
||||
tools:ignore="NewApi">@style/MwmTextAppearance.Toolbar.Title
|
||||
</item>
|
||||
<item name="android:titleTextAppearance" tools:ignore="NewApi">@style/MwmTextAppearance.Toolbar.Title</item>
|
||||
<item name="titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title</item>
|
||||
<item name="contentInsetLeft">72dp</item>
|
||||
<item name="android:contentInsetStart"
|
||||
tools:ignore="NewApi">72dp
|
||||
</item>
|
||||
<item name="android:contentInsetLeft"
|
||||
tools:ignore="NewApi">72dp
|
||||
</item>
|
||||
<item name="android:contentInsetStart" tools:ignore="NewApi">72dp</item>
|
||||
<item name="android:contentInsetLeft" tools:ignore="NewApi">72dp</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.ToolbarStyle.Light">
|
||||
<item name="android:titleTextAppearance"
|
||||
tools:targetApi="lollipop">@style/MwmTextAppearance.Toolbar.Title.Light
|
||||
</item>
|
||||
<item name="android:titleTextAppearance" tools:targetApi="lollipop">@style/MwmTextAppearance.Toolbar.Title.Light</item>
|
||||
<item name="titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title.Light</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.ToolbarTheme"
|
||||
parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<style name="MwmWidget.ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="colorAccent">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.ToolbarTheme.Light"
|
||||
parent="ThemeOverlay.AppCompat.ActionBar">
|
||||
<style name="MwmWidget.ToolbarTheme.Light" parent="ThemeOverlay.AppCompat.ActionBar">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="colorAccent">@color/bg_window_night</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.ListView"
|
||||
parent="Widget.AppCompat.ListView">
|
||||
<style name="MwmWidget.ToolbarTheme.Transparent" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="colorAccent">@android:color/white</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
<item name="windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.ListView" parent="Widget.AppCompat.ListView">
|
||||
<item name="android:fadingEdge">none</item>
|
||||
<item name="android:divider">@color/divider</item>
|
||||
<item name="android:background">@null</item>
|
||||
|
@ -129,8 +111,7 @@
|
|||
<item name="android:cacheColorHint">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.TextView"
|
||||
parent="android:Widget.TextView">
|
||||
<style name="MwmWidget.TextView" parent="android:Widget.TextView">
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
|
@ -203,8 +184,7 @@
|
|||
<item name="android:foreground">@drawable/shadow_top</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.RatingBar"
|
||||
parent="android:Widget.RatingBar">
|
||||
<style name="MwmWidget.RatingBar" parent="android:Widget.RatingBar">
|
||||
<item name="android:progressDrawable">@drawable/rating_bar</item>
|
||||
<item name="android:indeterminateDrawable">@drawable/rating_bar</item>
|
||||
</style>
|
||||
|
@ -240,9 +220,7 @@
|
|||
<item name="android:textAppearance">@style/MwmTextAppearance.Toolbar.Title.Button</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.SearchNavigationButton"
|
||||
parent="android:Widget.ImageButton">
|
||||
<style name="MwmWidget.SearchNavigationButton" parent="android:Widget.ImageButton">
|
||||
<item name="android:scaleType">center</item>
|
||||
<item name="android:layout_height">44dp</item>
|
||||
<item name="android:layout_width">44dp</item>
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
<attr name="ppPreviewHeadOpen" format="reference"/>
|
||||
<attr name="ppPreviewHeadClosed" format="reference"/>
|
||||
<attr name="ppArrowDrawable" format="reference"/>
|
||||
<attr name="ppRatingBackground" format="color"/>
|
||||
<attr name="ppRatingText" format="color"/>
|
||||
<attr name="ppPositive" format="reference"/>
|
||||
<attr name="ppNegative" format="reference"/>
|
||||
|
||||
<attr name="routingSlot" format="reference"/>
|
||||
<attr name="routingSlotPressed" format="reference"/>
|
||||
|
|
|
@ -75,6 +75,11 @@
|
|||
|
||||
<item name="routingButtonHint">@color/routing_button_tint</item>
|
||||
<item name="routingButtonPressedHint">@color/routing_button_pressed_tint</item>
|
||||
|
||||
<item name="ppRatingBackground">@color/bg_placepage_rating</item>
|
||||
<item name="ppRatingText">@color/text_placepage_rating</item>
|
||||
<item name="ppPositive">@drawable/ic_positive_review</item>
|
||||
<item name="ppNegative">@drawable/ic_negative_review</item>
|
||||
</style>
|
||||
|
||||
<!-- Night theme -->
|
||||
|
@ -152,5 +157,10 @@
|
|||
|
||||
<item name="routingButtonHint">@color/routing_button_tint</item>
|
||||
<item name="routingButtonPressedHint">@color/routing_button_pressed_tint</item>
|
||||
|
||||
<item name="ppRatingBackground">@color/bg_placepage_rating_night</item>
|
||||
<item name="ppRatingText">@color/text_placepage_rating_night</item>
|
||||
<item name="ppPositive">@drawable/ic_positive_review_night</item>
|
||||
<item name="ppNegative">@drawable/ic_negative_review_night</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -153,4 +153,24 @@
|
|||
<item name="newsMarker">@drawable/news_marker_night</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
<style name="MwmTheme.FullScreenGalleryActivity">
|
||||
<item name="colorPrimary">@android:color/transparent</item>
|
||||
<item name="android:colorPrimaryDark" tools:targetApi="lollipop">@android:color/black</item>
|
||||
<item name="android:timePickerStyle" tools:targetApi="lollipop">@style/MwmWidget.Editor.TimePicker</item>
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowActionBarOverlay">true</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmTheme.Night.FullScreenGalleryActivity">
|
||||
<item name="colorPrimary">@android:color/transparent</item>
|
||||
<item name="android:colorPrimaryDark" tools:targetApi="lollipop">@android:color/black</item>
|
||||
<item name="android:timePickerStyle" tools:targetApi="lollipop">@style/MwmWidget.Editor.TimePicker</item>
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowActionBarOverlay">true</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.mapswithme.maps.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
public class BaseMwmExtraTitleActivity extends BaseMwmFragmentActivity
|
||||
{
|
||||
protected static final String EXTRA_TITLE = "activity_title";
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
String title = "";
|
||||
Bundle bundle = getIntent().getExtras();
|
||||
if (bundle != null)
|
||||
{
|
||||
title = bundle.getString(EXTRA_TITLE);
|
||||
}
|
||||
Toolbar toolbar = getToolbar();
|
||||
toolbar.setTitle(title);
|
||||
UiUtils.showHomeUpButton(toolbar);
|
||||
displayToolbarAsActionBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentLayoutResId()
|
||||
{
|
||||
return R.layout.activity_fragment_and_toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFragmentContentResId()
|
||||
{
|
||||
return R.id.fragment_container;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
|
||||
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.BitmapImageViewTarget;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
|
||||
import com.mapswithme.util.ThemeUtils;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class FullScreenGalleryActivity extends BaseMwmFragmentActivity
|
||||
implements ViewPager.OnPageChangeListener
|
||||
{
|
||||
public static final String EXTRA_IMAGES = "gallery_images";
|
||||
public static final String EXTRA_POSITION = "gallery_position";
|
||||
|
||||
private List<Image> mImages;
|
||||
private int mPosition;
|
||||
private View mUserBlock;
|
||||
private TextView mDescription;
|
||||
private TextView mUserName;
|
||||
private TextView mSource;
|
||||
private TextView mDate;
|
||||
private ImageView mAvatar;
|
||||
|
||||
private GalleryPageAdapter mGalleryPageAdapter;
|
||||
|
||||
public static void start(Context context, ArrayList<Image> images, int position)
|
||||
{
|
||||
final Intent i = new Intent(context, FullScreenGalleryActivity.class);
|
||||
i.putParcelableArrayListExtra(EXTRA_IMAGES, images);
|
||||
i.putExtra(EXTRA_POSITION, position);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Toolbar toolbar = getToolbar();
|
||||
toolbar.setTitle("");
|
||||
UiUtils.showHomeUpButton(toolbar);
|
||||
displayToolbarAsActionBar();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
|
||||
mUserBlock = findViewById(R.id.rl__user_block);
|
||||
mDescription = (TextView) findViewById(R.id.tv__description);
|
||||
mUserName = (TextView) findViewById(R.id.tv__name);
|
||||
mSource = (TextView) findViewById(R.id.tv__source);
|
||||
mDate = (TextView) findViewById(R.id.tv__date);
|
||||
mAvatar = (ImageView) findViewById(R.id.iv__avatar);
|
||||
|
||||
readParameters();
|
||||
if (mImages != null)
|
||||
{
|
||||
mGalleryPageAdapter = new GalleryPageAdapter(getSupportFragmentManager(), mImages);
|
||||
final ViewPager viewPager = (ViewPager) findViewById(R.id.vp__image);
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
viewPager.setAdapter(mGalleryPageAdapter);
|
||||
viewPager.setCurrentItem(mPosition);
|
||||
viewPager.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
onPageSelected(viewPager.getCurrentItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeResourceId(String theme)
|
||||
{
|
||||
if (ThemeUtils.isDefaultTheme(theme))
|
||||
return R.style.MwmTheme_FullScreenGalleryActivity;
|
||||
|
||||
if (ThemeUtils.isNightTheme(theme))
|
||||
return R.style.MwmTheme_Night_FullScreenGalleryActivity;
|
||||
|
||||
throw new IllegalArgumentException("Attempt to apply unsupported theme: " + theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentLayoutResId()
|
||||
{
|
||||
return R.layout.activity_full_screen_gallery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position)
|
||||
{
|
||||
updateInformation(mGalleryPageAdapter.getImage(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state)
|
||||
{
|
||||
}
|
||||
|
||||
private void readParameters()
|
||||
{
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if (extras != null)
|
||||
{
|
||||
mImages = extras.getParcelableArrayList(EXTRA_IMAGES);
|
||||
mPosition = extras.getInt(EXTRA_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInformation(@NonNull Image image)
|
||||
{
|
||||
UiUtils.setTextAndHideIfEmpty(mDescription, image.getDescription());
|
||||
UiUtils.setTextAndHideIfEmpty(mUserName, image.getUserName());
|
||||
UiUtils.setTextAndHideIfEmpty(mSource, image.getSource());
|
||||
updateDate(image);
|
||||
updateUserAvatar(image);
|
||||
updateUserBlock();
|
||||
}
|
||||
|
||||
private void updateDate(Image image)
|
||||
{
|
||||
if (image.getDate() != null)
|
||||
{
|
||||
Date date = new Date(image.getDate());
|
||||
mDate.setText(DateFormat.getMediumDateFormat(this).format(date));
|
||||
UiUtils.show(mDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.hide(mDate);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUserAvatar(Image image)
|
||||
{
|
||||
if (!TextUtils.isEmpty(image.getUserAvatar()))
|
||||
{
|
||||
UiUtils.show(mAvatar);
|
||||
Glide.with(this)
|
||||
.load(image.getUserAvatar())
|
||||
.asBitmap()
|
||||
.centerCrop()
|
||||
.into(new BitmapImageViewTarget(mAvatar)
|
||||
{
|
||||
@Override
|
||||
protected void setResource(Bitmap resource)
|
||||
{
|
||||
RoundedBitmapDrawable circularBitmapDrawable =
|
||||
RoundedBitmapDrawableFactory.create(getResources(), resource);
|
||||
circularBitmapDrawable.setCircular(true);
|
||||
mAvatar.setImageDrawable(circularBitmapDrawable);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
UiUtils.hide(mAvatar);
|
||||
}
|
||||
|
||||
private void updateUserBlock()
|
||||
{
|
||||
if (UiUtils.isHidden(mUserName)
|
||||
&& UiUtils.isHidden(mSource)
|
||||
&& UiUtils.isHidden(mDate)
|
||||
&& UiUtils.isHidden(mAvatar))
|
||||
{
|
||||
UiUtils.hide(mUserBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mUserBlock);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmFragment;
|
||||
|
||||
public class FullScreenGalleryFragment extends BaseMwmFragment
|
||||
{
|
||||
static final String ARGUMENT_IMAGE = "argument_image";
|
||||
|
||||
@Nullable
|
||||
private Image mImage;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
return inflater.inflate(R.layout.fragment_fullscreen_image, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
readArguments();
|
||||
|
||||
if (mImage != null)
|
||||
{
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.iv__image);
|
||||
Glide.with(view.getContext())
|
||||
.load(mImage.getUrl())
|
||||
.into(imageView);
|
||||
}
|
||||
}
|
||||
|
||||
private void readArguments()
|
||||
{
|
||||
Bundle args = getArguments();
|
||||
if (args != null)
|
||||
mImage = args.getParcelable(ARGUMENT_IMAGE);
|
||||
}
|
||||
}
|
29
android/src/com/mapswithme/maps/gallery/GalleryActivity.java
Normal file
29
android/src/com/mapswithme/maps/gallery/GalleryActivity.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import com.mapswithme.maps.base.BaseMwmExtraTitleActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GalleryActivity extends BaseMwmExtraTitleActivity
|
||||
{
|
||||
public static final String EXTRA_IMAGES = "gallery_images";
|
||||
|
||||
public static void start(Context context, @NonNull ArrayList<Image> images, @NonNull String title)
|
||||
{
|
||||
final Intent i = new Intent(context, GalleryActivity.class);
|
||||
i.putParcelableArrayListExtra(EXTRA_IMAGES, images);
|
||||
i.putExtra(EXTRA_TITLE, title);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Fragment> getFragmentClass()
|
||||
{
|
||||
return GalleryFragment.class;
|
||||
}
|
||||
}
|
65
android/src/com/mapswithme/maps/gallery/GalleryFragment.java
Normal file
65
android/src/com/mapswithme/maps/gallery/GalleryFragment.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmFragment;
|
||||
import com.mapswithme.maps.widget.recycler.GridDividerItemDecoration;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GalleryFragment extends BaseMwmFragment implements RecyclerClickListener
|
||||
{
|
||||
private static final int NUM_COLUMNS = 3;
|
||||
|
||||
@Nullable
|
||||
private ArrayList<Image> mImages;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
return inflater.inflate(R.layout.fragment_gallery, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
readArguments();
|
||||
|
||||
if (mImages != null)
|
||||
{
|
||||
RecyclerView rvGallery = (RecyclerView) view.findViewById(R.id.rv__gallery);
|
||||
rvGallery.setLayoutManager(new GridLayoutManager(getContext(), NUM_COLUMNS));
|
||||
rvGallery.setAdapter(new ImageAdapter(mImages, this));
|
||||
Drawable divider = ContextCompat.getDrawable(getContext(), R.drawable.divider_transparent);
|
||||
rvGallery.addItemDecoration(new GridDividerItemDecoration(divider, divider, NUM_COLUMNS));
|
||||
}
|
||||
}
|
||||
|
||||
private void readArguments()
|
||||
{
|
||||
final Bundle arguments = getArguments();
|
||||
if (arguments == null)
|
||||
return;
|
||||
|
||||
mImages = arguments.getParcelableArrayList(GalleryActivity.EXTRA_IMAGES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(View v, int position)
|
||||
{
|
||||
FullScreenGalleryActivity.start(getContext(), mImages, position);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class GalleryPageAdapter extends FragmentStatePagerAdapter
|
||||
{
|
||||
|
||||
@NonNull
|
||||
private final List<Image> mImages;
|
||||
|
||||
GalleryPageAdapter(@NonNull FragmentManager fm, @NonNull List<Image> images)
|
||||
{
|
||||
super(fm);
|
||||
mImages = images;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position)
|
||||
{
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(FullScreenGalleryFragment.ARGUMENT_IMAGE, mImages.get(position));
|
||||
FullScreenGalleryFragment fragment = new FullScreenGalleryFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return mImages.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
Image getImage(int position)
|
||||
{
|
||||
return mImages.get(position);
|
||||
}
|
||||
}
|
144
android/src/com/mapswithme/maps/gallery/Image.java
Normal file
144
android/src/com/mapswithme/maps/gallery/Image.java
Normal file
|
@ -0,0 +1,144 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class Image implements Parcelable
|
||||
{
|
||||
@NonNull
|
||||
private final String mUrl;
|
||||
@NonNull
|
||||
private final String mSmallUrl;
|
||||
@Nullable
|
||||
private String mDescription;
|
||||
@Nullable
|
||||
private String mUserName;
|
||||
@Nullable
|
||||
private String mUserAvatar;
|
||||
@Nullable
|
||||
private String mSource;
|
||||
@Nullable
|
||||
private Long mDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Image(@NonNull String url, @NonNull String smallUrl)
|
||||
{
|
||||
this.mUrl = url;
|
||||
this.mSmallUrl = smallUrl;
|
||||
}
|
||||
|
||||
protected Image(Parcel in)
|
||||
{
|
||||
mUrl = in.readString();
|
||||
mSmallUrl = in.readString();
|
||||
mDescription = in.readString();
|
||||
mUserName = in.readString();
|
||||
mUserAvatar = in.readString();
|
||||
mSource = in.readString();
|
||||
mDate = (Long) in.readValue(Long.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags)
|
||||
{
|
||||
dest.writeString(mUrl);
|
||||
dest.writeString(mSmallUrl);
|
||||
dest.writeString(mDescription);
|
||||
dest.writeString(mUserName);
|
||||
dest.writeString(mUserAvatar);
|
||||
dest.writeString(mSource);
|
||||
dest.writeValue(mDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<Image> CREATOR = new Creator<Image>()
|
||||
{
|
||||
@Override
|
||||
public Image createFromParcel(Parcel in)
|
||||
{
|
||||
return new Image(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image[] newArray(int size)
|
||||
{
|
||||
return new Image[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull
|
||||
public String getUrl()
|
||||
{
|
||||
return mUrl;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getSmallUrl()
|
||||
{
|
||||
return mSmallUrl;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDescription()
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public void setDescription(@Nullable String description)
|
||||
{
|
||||
this.mDescription = description;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getUserName()
|
||||
{
|
||||
return mUserName;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void setUserName(@Nullable String userName)
|
||||
{
|
||||
this.mUserName = userName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getUserAvatar()
|
||||
{
|
||||
return mUserAvatar;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void setUserAvatar(@Nullable String userAvatar)
|
||||
{
|
||||
this.mUserAvatar = userAvatar;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getSource()
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
|
||||
public void setSource(@Nullable String source)
|
||||
{
|
||||
this.mSource = source;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getDate()
|
||||
{
|
||||
return mDate;
|
||||
}
|
||||
|
||||
public void setDate(@Nullable Long date)
|
||||
{
|
||||
this.mDate = date;
|
||||
}
|
||||
}
|
79
android/src/com/mapswithme/maps/gallery/ImageAdapter.java
Normal file
79
android/src/com/mapswithme/maps/gallery/ImageAdapter.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package com.mapswithme.maps.gallery;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ViewHolder>
|
||||
{
|
||||
@NonNull
|
||||
private final ArrayList<Image> mItems;
|
||||
@Nullable
|
||||
private final RecyclerClickListener mListener;
|
||||
|
||||
ImageAdapter(@NonNull ArrayList<Image> images, @Nullable RecyclerClickListener listener)
|
||||
{
|
||||
mItems = images;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
||||
{
|
||||
return new ViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_image, parent, false), mListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position)
|
||||
{
|
||||
holder.bind(mItems.get(position), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||
{
|
||||
private ImageView mImage;
|
||||
private final RecyclerClickListener mListener;
|
||||
private int mPosition;
|
||||
|
||||
public ViewHolder(View itemView, RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView);
|
||||
mListener = listener;
|
||||
itemView.setOnClickListener(this);
|
||||
mImage = (ImageView) itemView.findViewById(R.id.iv__image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mListener != null)
|
||||
mListener.onItemClick(v, mPosition);
|
||||
}
|
||||
|
||||
public void bind(Image image, int position)
|
||||
{
|
||||
mPosition = position;
|
||||
Glide.with(mImage.getContext())
|
||||
.load(image.getSmallUrl())
|
||||
.centerCrop()
|
||||
.into(mImage);
|
||||
}
|
||||
}
|
||||
}
|
121
android/src/com/mapswithme/maps/review/Review.java
Normal file
121
android/src/com/mapswithme/maps/review/Review.java
Normal file
|
@ -0,0 +1,121 @@
|
|||
package com.mapswithme.maps.review;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class Review implements Parcelable
|
||||
{
|
||||
@Nullable
|
||||
private final String mReview;
|
||||
@Nullable
|
||||
private final String mReviewPositive;
|
||||
@Nullable
|
||||
private final String mReviewNegative;
|
||||
@NonNull
|
||||
private final String mAuthor;
|
||||
@NonNull
|
||||
private final String mAuthorAvatar;
|
||||
private final float mRating;
|
||||
private final long mDate;
|
||||
|
||||
public Review(@Nullable String review, @Nullable String reviewPositive,
|
||||
@Nullable String reviewNegative, @NonNull String author,
|
||||
@NonNull String authorAvatar,
|
||||
float rating, long date)
|
||||
{
|
||||
mReview = review;
|
||||
mReviewPositive = reviewPositive;
|
||||
mReviewNegative = reviewNegative;
|
||||
mAuthor = author;
|
||||
mAuthorAvatar = authorAvatar;
|
||||
mRating = rating;
|
||||
mDate = date;
|
||||
}
|
||||
|
||||
protected Review(Parcel in)
|
||||
{
|
||||
mReview = in.readString();
|
||||
mReviewPositive = in.readString();
|
||||
mReviewNegative = in.readString();
|
||||
mAuthor = in.readString();
|
||||
mAuthorAvatar = in.readString();
|
||||
mRating = in.readFloat();
|
||||
mDate = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags)
|
||||
{
|
||||
dest.writeString(mReview);
|
||||
dest.writeString(mReviewPositive);
|
||||
dest.writeString(mReviewNegative);
|
||||
dest.writeString(mAuthor);
|
||||
dest.writeString(mAuthorAvatar);
|
||||
dest.writeFloat(mRating);
|
||||
dest.writeLong(mDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<Review> CREATOR = new Creator<Review>()
|
||||
{
|
||||
@Override
|
||||
public Review createFromParcel(Parcel in)
|
||||
{
|
||||
return new Review(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Review[] newArray(int size)
|
||||
{
|
||||
return new Review[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public String getReview()
|
||||
{
|
||||
return mReview;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getReviewPositive()
|
||||
{
|
||||
return mReviewPositive;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getReviewNegative()
|
||||
{
|
||||
return mReviewNegative;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getAuthor()
|
||||
{
|
||||
return mAuthor;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@NonNull
|
||||
public String getAuthorAvatar()
|
||||
{
|
||||
return mAuthorAvatar;
|
||||
}
|
||||
|
||||
public float getRating()
|
||||
{
|
||||
return mRating;
|
||||
}
|
||||
|
||||
public long getDate()
|
||||
{
|
||||
return mDate;
|
||||
}
|
||||
}
|
37
android/src/com/mapswithme/maps/review/ReviewActivity.java
Normal file
37
android/src/com/mapswithme/maps/review/ReviewActivity.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package com.mapswithme.maps.review;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import com.mapswithme.maps.base.BaseMwmExtraTitleActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ReviewActivity extends BaseMwmExtraTitleActivity
|
||||
{
|
||||
static final String EXTRA_REVIEWS = "review_items";
|
||||
static final String EXTRA_RATING = "review_rating";
|
||||
static final String EXTRA_RATING_BASE = "review_rating_base";
|
||||
static final String EXTRA_RATING_URL = "review_rating_url";
|
||||
|
||||
public static void start(Context context, @NonNull ArrayList<Review> items,
|
||||
@NonNull String title, @NonNull String rating, int ratingBase,
|
||||
@NonNull String url)
|
||||
{
|
||||
final Intent i = new Intent(context, ReviewActivity.class);
|
||||
i.putParcelableArrayListExtra(EXTRA_REVIEWS, items);
|
||||
i.putExtra(EXTRA_TITLE, title);
|
||||
i.putExtra(EXTRA_RATING, rating);
|
||||
i.putExtra(EXTRA_RATING_BASE, ratingBase);
|
||||
i.putExtra(EXTRA_RATING_URL, url);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Fragment> getFragmentClass()
|
||||
{
|
||||
return ReviewFragment.class;
|
||||
}
|
||||
}
|
217
android/src/com/mapswithme/maps/review/ReviewAdapter.java
Normal file
217
android/src/com/mapswithme/maps/review/ReviewAdapter.java
Normal file
|
@ -0,0 +1,217 @@
|
|||
package com.mapswithme.maps.review;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.BaseViewHolder>
|
||||
{
|
||||
private static final int MAX_COUNT = 15;
|
||||
private static final int VIEW_TYPE_REVIEW = 0;
|
||||
private static final int VIEW_TYPE_MORE = 1;
|
||||
private static final int VIEW_TYPE_RATING = 2;
|
||||
|
||||
@NonNull
|
||||
private final ArrayList<Review> mItems;
|
||||
@Nullable
|
||||
private final RecyclerClickListener mListener;
|
||||
@NonNull
|
||||
private final String mRating;
|
||||
private final int mRatingBase;
|
||||
|
||||
ReviewAdapter(@NonNull ArrayList<Review> images, @Nullable RecyclerClickListener listener,
|
||||
@NonNull String rating,
|
||||
int ratingBase)
|
||||
{
|
||||
mItems = images;
|
||||
mListener = listener;
|
||||
mRating = rating;
|
||||
mRatingBase = ratingBase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
||||
{
|
||||
if (viewType == VIEW_TYPE_REVIEW)
|
||||
return new ReviewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_comment, parent, false), mListener);
|
||||
|
||||
if (viewType == VIEW_TYPE_MORE)
|
||||
return new MoreHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_more_button, parent, false), mListener);
|
||||
|
||||
return new RatingHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_rating, parent, false), mListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(BaseViewHolder holder, int position)
|
||||
{
|
||||
int positionNoHeader = position - 1;
|
||||
|
||||
if (position == 0)
|
||||
((RatingHolder) holder).bind(mRating, mRatingBase);
|
||||
else if (positionNoHeader < mItems.size())
|
||||
holder.bind(mItems.get(positionNoHeader), positionNoHeader);
|
||||
else
|
||||
holder.bind(null, positionNoHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
if (mItems.size() > MAX_COUNT)
|
||||
// 1 overall rating item + MAX_COUNT user reviews + 1 "more reviews" item
|
||||
return MAX_COUNT + 2;
|
||||
|
||||
// 1 overall rating item + count of user reviews + 1 "more reviews" item
|
||||
return mItems.size() + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position)
|
||||
{
|
||||
int positionNoHeader = position - 1;
|
||||
|
||||
if (position == 0)
|
||||
return VIEW_TYPE_RATING;
|
||||
if (positionNoHeader == mItems.size())
|
||||
return VIEW_TYPE_MORE;
|
||||
|
||||
return VIEW_TYPE_REVIEW;
|
||||
}
|
||||
|
||||
static abstract class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||
{
|
||||
private final RecyclerClickListener mListener;
|
||||
private int mPosition;
|
||||
|
||||
BaseViewHolder(View itemView, RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView);
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mListener != null)
|
||||
mListener.onItemClick(v, mPosition);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void bind(Review item, int position)
|
||||
{
|
||||
mPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReviewHolder extends BaseViewHolder
|
||||
{
|
||||
final View mDivider;
|
||||
final TextView mUserName;
|
||||
final TextView mCommentDate;
|
||||
final TextView mRating;
|
||||
final TextView mReview;
|
||||
final View mPositiveReview;
|
||||
final TextView mTvPositiveReview;
|
||||
final View mNegativeReview;
|
||||
final TextView mTvNegativeReview;
|
||||
|
||||
ReviewHolder(View itemView, RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView, listener);
|
||||
mDivider = itemView.findViewById(R.id.v__divider);
|
||||
mUserName = (TextView) itemView.findViewById(R.id.tv__user_name);
|
||||
mCommentDate = (TextView) itemView.findViewById(R.id.tv__comment_date);
|
||||
mRating = (TextView) itemView.findViewById(R.id.tv__user_rating);
|
||||
mReview = (TextView) itemView.findViewById(R.id.tv__review);
|
||||
mPositiveReview = itemView.findViewById(R.id.ll__positive_review);
|
||||
mTvPositiveReview = (TextView) itemView.findViewById(R.id.tv__positive_review);
|
||||
mNegativeReview = itemView.findViewById(R.id.ll__negative_review);
|
||||
mTvNegativeReview = (TextView) itemView.findViewById(R.id.tv__negative_review);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Review item, int position)
|
||||
{
|
||||
super.bind(item, position);
|
||||
UiUtils.showIf(position > 0, mDivider);
|
||||
mUserName.setText(item.getAuthor());
|
||||
Date date = new Date(item.getDate());
|
||||
mCommentDate.setText(DateFormat.getMediumDateFormat(mCommentDate.getContext()).format(date));
|
||||
mRating.setText(String.format(Locale.getDefault(), "%.1f", item.getRating()));
|
||||
if (TextUtils.isEmpty(item.getReviewPositive()))
|
||||
{
|
||||
UiUtils.hide(mPositiveReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mPositiveReview);
|
||||
mTvPositiveReview.setText(item.getReviewPositive());
|
||||
}
|
||||
if (TextUtils.isEmpty(item.getReviewNegative()))
|
||||
{
|
||||
UiUtils.hide(mNegativeReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mNegativeReview);
|
||||
mTvNegativeReview.setText(item.getReviewNegative());
|
||||
}
|
||||
if (UiUtils.isHidden(mNegativeReview) && UiUtils.isHidden(mPositiveReview))
|
||||
{
|
||||
UiUtils.showIf(!TextUtils.isEmpty(item.getReview()), mReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.hide(mReview);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MoreHolder extends BaseViewHolder
|
||||
{
|
||||
MoreHolder(View itemView, RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView, listener);
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RatingHolder extends BaseViewHolder
|
||||
{
|
||||
final TextView mHotelRating;
|
||||
final TextView mHotelRatingBase;
|
||||
|
||||
RatingHolder(View itemView, RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView, listener);
|
||||
mHotelRating = (TextView) itemView.findViewById(R.id.tv__place_hotel_rating);
|
||||
mHotelRatingBase = (TextView) itemView.findViewById(R.id.tv__place_hotel_rating_base);
|
||||
}
|
||||
|
||||
public void bind(String rating, int ratingBase)
|
||||
{
|
||||
mHotelRating.setText(rating);
|
||||
mHotelRatingBase.setText(mHotelRatingBase.getContext().getResources()
|
||||
.getQuantityString(R.plurals.place_page_booking_rating_base,
|
||||
ratingBase, ratingBase));
|
||||
}
|
||||
}
|
||||
}
|
76
android/src/com/mapswithme/maps/review/ReviewFragment.java
Normal file
76
android/src/com/mapswithme/maps/review/ReviewFragment.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
package com.mapswithme.maps.review;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmFragment;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ReviewFragment extends BaseMwmFragment implements RecyclerClickListener
|
||||
{
|
||||
@Nullable
|
||||
private ArrayList<Review> mItems;
|
||||
@Nullable
|
||||
private String mRating;
|
||||
private int mRatingBase;
|
||||
@Nullable
|
||||
private String mUrl;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
return inflater.inflate(R.layout.fragment_review, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
readArguments();
|
||||
|
||||
if (mItems != null && mRating != null)
|
||||
{
|
||||
RecyclerView rvGallery = (RecyclerView) view.findViewById(R.id.rv__review);
|
||||
rvGallery.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||
rvGallery.setAdapter(new ReviewAdapter(mItems, this, mRating, mRatingBase));
|
||||
}
|
||||
}
|
||||
|
||||
private void readArguments()
|
||||
{
|
||||
final Bundle arguments = getArguments();
|
||||
if (arguments == null)
|
||||
return;
|
||||
|
||||
mItems = arguments.getParcelableArrayList(ReviewActivity.EXTRA_REVIEWS);
|
||||
mRating = arguments.getString(ReviewActivity.EXTRA_RATING);
|
||||
mRatingBase = arguments.getInt(ReviewActivity.EXTRA_RATING_BASE);
|
||||
mUrl = arguments.getString(ReviewActivity.EXTRA_RATING_URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(View v, int position)
|
||||
{
|
||||
if (mUrl == null)
|
||||
return;
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
String url = mUrl;
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://"))
|
||||
url = "http://" + url;
|
||||
intent.setData(Uri.parse(url));
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.mapswithme.maps.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.text.Layout;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class LineCountTextView extends TextView
|
||||
{
|
||||
public interface OnLineCountCalculatedListener
|
||||
{
|
||||
|
||||
void onLineCountCalculated(boolean grater);
|
||||
}
|
||||
|
||||
private OnLineCountCalculatedListener mListener;
|
||||
|
||||
public LineCountTextView(Context context)
|
||||
{
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LineCountTextView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LineCountTextView(Context context, AttributeSet attrs, int defStyleAttr)
|
||||
{
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
super.onDraw(canvas);
|
||||
Layout layout = getLayout();
|
||||
|
||||
if (layout != null)
|
||||
{
|
||||
int textHeight = layout.getHeight();
|
||||
int viewHeight = getHeight();
|
||||
|
||||
if (mListener != null)
|
||||
{
|
||||
mListener.onLineCountCalculated(textHeight > viewHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(OnLineCountCalculatedListener listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
}
|
30
android/src/com/mapswithme/maps/widget/StaticGridView.java
Normal file
30
android/src/com/mapswithme/maps/widget/StaticGridView.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package com.mapswithme.maps.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.GridView;
|
||||
|
||||
public class StaticGridView extends GridView
|
||||
{
|
||||
public StaticGridView(Context context)
|
||||
{
|
||||
super(context);
|
||||
}
|
||||
|
||||
public StaticGridView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public StaticGridView(Context context, AttributeSet attrs, int defStyleAttr)
|
||||
{
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||
{
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST));
|
||||
getLayoutParams().height = getMeasuredHeight();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.mapswithme.maps.widget.placepage;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class FacilitiesAdapter extends BaseAdapter
|
||||
{
|
||||
static final int MAX_COUNT = 6;
|
||||
|
||||
@NonNull
|
||||
private List<SponsoredHotel.FacilityType> mItems = new ArrayList<>();
|
||||
private boolean isShowAll = false;
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
if (mItems.size() > MAX_COUNT && !isShowAll)
|
||||
{
|
||||
return MAX_COUNT;
|
||||
}
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position)
|
||||
{
|
||||
return mItems.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
ViewHolder holder;
|
||||
if (convertView == null)
|
||||
{
|
||||
convertView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_facility, parent, false);
|
||||
holder = new ViewHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.bind(mItems.get(position));
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
public void setItems(@NonNull List<SponsoredHotel.FacilityType> items)
|
||||
{
|
||||
this.mItems = items;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
void setShowAll(boolean showAll)
|
||||
{
|
||||
isShowAll = showAll;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static class ViewHolder
|
||||
{
|
||||
ImageView mIcon;
|
||||
TextView mName;
|
||||
|
||||
public ViewHolder(View view)
|
||||
{
|
||||
mIcon = (ImageView) view.findViewById(R.id.iv__icon);
|
||||
mName = (TextView) view.findViewById(R.id.tv__facility);
|
||||
}
|
||||
|
||||
public void bind(SponsoredHotel.FacilityType facility)
|
||||
{
|
||||
// TODO map facility key to image resource id
|
||||
mIcon.setImageResource(R.drawable.ic_entrance);
|
||||
mName.setText(facility.getName());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
package com.mapswithme.maps.widget.placepage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.gallery.Image;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder>
|
||||
{
|
||||
static final int MAX_COUNT = 5;
|
||||
|
||||
private final Context mContext;
|
||||
@NonNull
|
||||
private ArrayList<Image> mItems = new ArrayList<>();
|
||||
@NonNull
|
||||
private final List<Item> mLoadedItems = new ArrayList<>();
|
||||
@NonNull
|
||||
private final List<Item> mItemsToDownload = new ArrayList<>();
|
||||
@Nullable
|
||||
private RecyclerClickListener mListener;
|
||||
private final int mImageWidth;
|
||||
private final int mImageHeight;
|
||||
|
||||
GalleryAdapter(Context context)
|
||||
{
|
||||
mContext = context;
|
||||
|
||||
mImageWidth = (int) context.getResources().getDimension(R.dimen.placepage_hotel_gallery_width);
|
||||
mImageHeight = (int) context.getResources()
|
||||
.getDimension(R.dimen.placepage_hotel_gallery_height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
||||
{
|
||||
return new ViewHolder(LayoutInflater.from(mContext)
|
||||
.inflate(R.layout.item_gallery, parent, false), mListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position)
|
||||
{
|
||||
Item item = mLoadedItems.get(position);
|
||||
item.setShowMore(position == MAX_COUNT - 1 && mItems.size() > MAX_COUNT);
|
||||
holder.bind(item, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
return mLoadedItems.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ArrayList<Image> getItems()
|
||||
{
|
||||
return mItems;
|
||||
}
|
||||
|
||||
public void setItems(@NonNull ArrayList<Image> items)
|
||||
{
|
||||
mItems = items;
|
||||
|
||||
for (Item item : mItemsToDownload)
|
||||
{
|
||||
item.setCanceled(true);
|
||||
}
|
||||
mItemsToDownload.clear();
|
||||
mLoadedItems.clear();
|
||||
loadImages();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setListener(@Nullable RecyclerClickListener listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
private void loadImages()
|
||||
{
|
||||
int size = Math.min(mItems.size(), MAX_COUNT);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final Item item = new Item(null);
|
||||
mItemsToDownload.add(item);
|
||||
Image image = mItems.get(i);
|
||||
Glide.with(mContext)
|
||||
.load(image.getSmallUrl())
|
||||
.asBitmap()
|
||||
.centerCrop()
|
||||
.into(new SimpleTarget<Bitmap>(mImageWidth, mImageHeight)
|
||||
{
|
||||
@Override
|
||||
public void onResourceReady(Bitmap resource,
|
||||
GlideAnimation<? super Bitmap> glideAnimation)
|
||||
{
|
||||
if (item.isCanceled())
|
||||
return;
|
||||
|
||||
item.setBitmap(resource);
|
||||
int size = mLoadedItems.size();
|
||||
mLoadedItems.add(item);
|
||||
notifyItemInserted(size);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||
{
|
||||
@NonNull
|
||||
private ImageView mImage;
|
||||
@NonNull
|
||||
private View mMore;
|
||||
@Nullable
|
||||
private final RecyclerClickListener mListener;
|
||||
private int mPosition;
|
||||
|
||||
public ViewHolder(View itemView, @Nullable RecyclerClickListener listener)
|
||||
{
|
||||
super(itemView);
|
||||
mListener = listener;
|
||||
mImage = (ImageView) itemView.findViewById(R.id.iv__image);
|
||||
mMore = itemView.findViewById(R.id.tv__more);
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mListener == null)
|
||||
return;
|
||||
|
||||
mListener.onItemClick(v, mPosition);
|
||||
}
|
||||
|
||||
public void bind(Item item, int position)
|
||||
{
|
||||
mPosition = position;
|
||||
mImage.setImageBitmap(item.getBitmap());
|
||||
UiUtils.showIf(item.isShowMore(), mMore);
|
||||
}
|
||||
}
|
||||
|
||||
static class Item
|
||||
{
|
||||
@Nullable
|
||||
private Bitmap mBitmap;
|
||||
private boolean isShowMore;
|
||||
private boolean isCanceled = false;
|
||||
|
||||
Item(@Nullable Bitmap bitmap)
|
||||
{
|
||||
this.mBitmap = bitmap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Bitmap getBitmap()
|
||||
{
|
||||
return mBitmap;
|
||||
}
|
||||
|
||||
void setBitmap(@Nullable Bitmap bitmap)
|
||||
{
|
||||
mBitmap = bitmap;
|
||||
}
|
||||
|
||||
void setShowMore(boolean showMore)
|
||||
{
|
||||
isShowMore = showMore;
|
||||
}
|
||||
|
||||
boolean isShowMore()
|
||||
{
|
||||
return isShowMore;
|
||||
}
|
||||
|
||||
boolean isCanceled()
|
||||
{
|
||||
return isCanceled;
|
||||
}
|
||||
|
||||
void setCanceled(boolean canceled)
|
||||
{
|
||||
isCanceled = canceled;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import com.mapswithme.util.UiUtils;
|
|||
|
||||
class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
||||
{
|
||||
public LeftPlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
LeftPlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
{
|
||||
super(placePage);
|
||||
}
|
||||
|
@ -27,18 +27,21 @@ class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
|||
@Override
|
||||
protected boolean onInterceptTouchEvent(MotionEvent event)
|
||||
{
|
||||
if (mPlacePage.isTouchGallery(event))
|
||||
return false;
|
||||
|
||||
switch (event.getAction())
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mIsDragging = false;
|
||||
mDownCoord = event.getX();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mDownCoord > mPlacePage.getRight())
|
||||
return false;
|
||||
if (Math.abs(mDownCoord - event.getX()) > mTouchSlop)
|
||||
return true;
|
||||
break;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mIsDragging = false;
|
||||
mDownCoord = event.getX();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mDownCoord > mPlacePage.getRight())
|
||||
return false;
|
||||
if (Math.abs(mDownCoord - event.getX()) > mTouchSlop)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -70,7 +73,7 @@ class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
|||
final boolean isInRange = Math.abs(distanceX) > X_MIN && Math.abs(distanceX) < X_MAX;
|
||||
|
||||
if (!isHorizontal || !isInRange)
|
||||
return false;;
|
||||
return false;
|
||||
|
||||
if (!mIsDragging)
|
||||
{
|
||||
|
@ -90,13 +93,13 @@ class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
|||
{
|
||||
switch (newState)
|
||||
{
|
||||
case HIDDEN:
|
||||
hidePlacePage();
|
||||
break;
|
||||
case DETAILS:
|
||||
case PREVIEW:
|
||||
showPlacePage(currentState, newState);
|
||||
break;
|
||||
case HIDDEN:
|
||||
hidePlacePage();
|
||||
break;
|
||||
case DETAILS:
|
||||
case PREVIEW:
|
||||
showPlacePage(currentState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +133,7 @@ class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
|||
tracker.onTrackLeftAnimation(offset + mPlacePage.getDockedWidth());
|
||||
}
|
||||
|
||||
private void showPlacePage(final State currentState, final State newState)
|
||||
private void showPlacePage(final State currentState)
|
||||
{
|
||||
UiUtils.show(mPlacePage);
|
||||
if (currentState != State.HIDDEN)
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
package com.mapswithme.maps.widget.placepage;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.util.ThemeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class NearbyAdapter extends BaseAdapter
|
||||
{
|
||||
@NonNull
|
||||
private List<SponsoredHotel.NearbyObject> mItems = new ArrayList<>();
|
||||
@Nullable
|
||||
private final OnItemClickListener mListener;
|
||||
|
||||
NearbyAdapter(@Nullable OnItemClickListener listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
interface OnItemClickListener
|
||||
{
|
||||
void onItemClick(@NonNull SponsoredHotel.NearbyObject item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position)
|
||||
{
|
||||
return mItems.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
ViewHolder holder;
|
||||
if (convertView == null)
|
||||
{
|
||||
convertView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_nearby, parent, false);
|
||||
holder = new ViewHolder(convertView, mListener);
|
||||
convertView.setTag(holder);
|
||||
} else
|
||||
{
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.bind(mItems.get(position));
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
public void setItems(@NonNull List<SponsoredHotel.NearbyObject> items)
|
||||
{
|
||||
this.mItems = items;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static class ViewHolder implements View.OnClickListener
|
||||
{
|
||||
@Nullable
|
||||
final OnItemClickListener mListener;
|
||||
@NonNull
|
||||
ImageView mIcon;
|
||||
@NonNull
|
||||
TextView mTitle;
|
||||
@NonNull
|
||||
TextView mType;
|
||||
@NonNull
|
||||
TextView mDistance;
|
||||
@Nullable
|
||||
SponsoredHotel.NearbyObject mItem;
|
||||
|
||||
public ViewHolder(View view, @Nullable OnItemClickListener listener)
|
||||
{
|
||||
mListener = listener;
|
||||
mIcon = (ImageView) view.findViewById(R.id.iv__icon);
|
||||
mTitle = (TextView) view.findViewById(R.id.tv__title);
|
||||
mType = (TextView) view.findViewById(R.id.tv__type);
|
||||
mDistance = (TextView) view.findViewById(R.id.tv__distance);
|
||||
view.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mListener != null && mItem != null)
|
||||
mListener.onItemClick(mItem);
|
||||
}
|
||||
|
||||
public void bind(@NonNull SponsoredHotel.NearbyObject item)
|
||||
{
|
||||
mItem = item;
|
||||
String packageName = mType.getContext().getPackageName();
|
||||
final boolean isNightTheme = ThemeUtils.isNightTheme();
|
||||
Resources resources = mType.getResources();
|
||||
int categoryRes = resources.getIdentifier(item.getCategory(), "string", packageName);
|
||||
if (categoryRes == 0)
|
||||
throw new IllegalStateException("Can't get string resource id for category:" + item.getCategory());
|
||||
|
||||
String iconId = "ic_category_" + item.getCategory();
|
||||
if (isNightTheme)
|
||||
iconId = iconId + "_night";
|
||||
int iconRes = resources.getIdentifier(iconId, "drawable", packageName);
|
||||
if (iconRes == 0)
|
||||
throw new IllegalStateException("Can't get icon resource id:" + iconId);
|
||||
mIcon.setImageResource(iconRes);
|
||||
mTitle.setText(item.getTitle());
|
||||
mType.setText(categoryRes);
|
||||
mDistance.setText(item.getDistance());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ import android.os.Build;
|
|||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
|
@ -24,6 +27,7 @@ import android.view.MenuItem;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
|
@ -31,15 +35,6 @@ import android.widget.RelativeLayout;
|
|||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.MwmActivity;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
|
@ -57,12 +52,18 @@ import com.mapswithme.maps.editor.Editor;
|
|||
import com.mapswithme.maps.editor.OpeningHours;
|
||||
import com.mapswithme.maps.editor.data.TimeFormatUtils;
|
||||
import com.mapswithme.maps.editor.data.Timetable;
|
||||
import com.mapswithme.maps.gallery.FullScreenGalleryActivity;
|
||||
import com.mapswithme.maps.gallery.GalleryActivity;
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.maps.review.ReviewActivity;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.maps.widget.ArrowView;
|
||||
import com.mapswithme.maps.widget.BaseShadowController;
|
||||
import com.mapswithme.maps.widget.LineCountTextView;
|
||||
import com.mapswithme.maps.widget.ObservableScrollView;
|
||||
import com.mapswithme.maps.widget.ScrollViewShadowController;
|
||||
import com.mapswithme.maps.widget.recycler.DividerItemDecoration;
|
||||
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
|
||||
import com.mapswithme.util.Graphics;
|
||||
import com.mapswithme.util.StringUtils;
|
||||
import com.mapswithme.util.ThemeUtils;
|
||||
|
@ -73,14 +74,30 @@ import com.mapswithme.util.sharing.ShareOption;
|
|||
import com.mapswithme.util.statistics.AlohaHelper;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlacePageView extends RelativeLayout
|
||||
implements View.OnClickListener,
|
||||
View.OnLongClickListener,
|
||||
SponsoredHotel.OnPriceReceivedListener
|
||||
implements View.OnClickListener,
|
||||
View.OnLongClickListener,
|
||||
SponsoredHotel.OnPriceReceivedListener,
|
||||
SponsoredHotel.OnInfoReceivedListener,
|
||||
LineCountTextView.OnLineCountCalculatedListener,
|
||||
RecyclerClickListener,
|
||||
NearbyAdapter.OnItemClickListener
|
||||
{
|
||||
private static final String PREF_USE_DMS = "use_dms";
|
||||
|
||||
//TODO: remove this after booking_api.cpp will be done
|
||||
private static final boolean USE_OLD_BOOKING = true;
|
||||
|
||||
private boolean mIsDocked;
|
||||
private boolean mIsFloating;
|
||||
|
||||
|
@ -118,7 +135,6 @@ public class PlacePageView extends RelativeLayout
|
|||
private View mEditPlace;
|
||||
private View mAddOrganisation;
|
||||
private View mAddPlace;
|
||||
private View mMoreInfo;
|
||||
// Bookmark
|
||||
private View mBookmarkFrame;
|
||||
private TextView mBookmarkNote;
|
||||
|
@ -126,6 +142,20 @@ public class PlacePageView extends RelativeLayout
|
|||
// Place page buttons
|
||||
private PlacePageButtons mButtons;
|
||||
private ImageView mBookmarkButtonIcon;
|
||||
// Hotel
|
||||
private View mHotelDescription;
|
||||
private LineCountTextView mTvHotelDescription;
|
||||
private View mHotelMoreDescription;
|
||||
private View mHotelFacilities;
|
||||
private View mHotelMoreFacilities;
|
||||
private View mHotelGallery;
|
||||
private RecyclerView mRvHotelGallery;
|
||||
private View mHotelNearby;
|
||||
private View mHotelReview;
|
||||
private TextView mHotelRating;
|
||||
private TextView mHotelRatingBase;
|
||||
//TODO: remove this after booking_api.cpp will be done
|
||||
private View mHotelMore;
|
||||
|
||||
// Animations
|
||||
private BaseShadowController mShadowController;
|
||||
|
@ -136,6 +166,14 @@ public class PlacePageView extends RelativeLayout
|
|||
private SponsoredHotel mSponsoredHotel;
|
||||
private String mSponsoredHotelPrice;
|
||||
private boolean mIsLatLonDms;
|
||||
@NonNull
|
||||
private final FacilitiesAdapter mFacilitiesAdapter = new FacilitiesAdapter();
|
||||
@NonNull
|
||||
private final GalleryAdapter mGalleryAdapter;
|
||||
@NonNull
|
||||
private final NearbyAdapter mNearbyAdapter = new NearbyAdapter(this);
|
||||
@NonNull
|
||||
private final ReviewAdapter mReviewAdapter = new ReviewAdapter();
|
||||
|
||||
// Downloader`s stuff
|
||||
private DownloaderStatusIcon mDownloaderIcon;
|
||||
|
@ -198,12 +236,17 @@ public class PlacePageView extends RelativeLayout
|
|||
super(context, attrs);
|
||||
|
||||
mIsLatLonDms = MwmApplication.prefs().getBoolean(PREF_USE_DMS, false);
|
||||
|
||||
mGalleryAdapter = new GalleryAdapter(context);
|
||||
init(attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public ViewGroup GetPreview() { return mPreview; }
|
||||
|
||||
public boolean isTouchGallery(@NonNull MotionEvent event)
|
||||
{
|
||||
return UiUtils.isViewTouched(event, mHotelGallery);
|
||||
}
|
||||
|
||||
private void initViews()
|
||||
{
|
||||
LayoutInflater.from(getContext()).inflate(R.layout.place_page, this);
|
||||
|
@ -257,8 +300,6 @@ public class PlacePageView extends RelativeLayout
|
|||
mAddOrganisation.setOnClickListener(this);
|
||||
mAddPlace = mDetails.findViewById(R.id.ll__place_add);
|
||||
mAddPlace.setOnClickListener(this);
|
||||
mMoreInfo = mDetails.findViewById(R.id.ll__more);
|
||||
mMoreInfo.setOnClickListener(this);
|
||||
latlon.setOnLongClickListener(this);
|
||||
address.setOnLongClickListener(this);
|
||||
mPhone.setOnLongClickListener(this);
|
||||
|
@ -274,6 +315,16 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
ViewGroup ppButtons = (ViewGroup) findViewById(R.id.pp__buttons);
|
||||
|
||||
// TODO: remove this after booking_api.cpp will be done
|
||||
mHotelMore = findViewById(R.id.ll__more);
|
||||
mHotelMore.setOnClickListener(this);
|
||||
|
||||
initHotelDescriptionView();
|
||||
initHotelFacilitiesView();
|
||||
initHotelGalleryView();
|
||||
initHotelNearbyView();
|
||||
initHotelRatingView();
|
||||
|
||||
mButtons = new PlacePageButtons(this, ppButtons, new PlacePageButtons.ItemListener()
|
||||
{
|
||||
@Override
|
||||
|
@ -283,21 +334,21 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
switch (item)
|
||||
{
|
||||
case BOOKING:
|
||||
frame.setBackgroundResource(R.drawable.button_booking);
|
||||
color = Color.WHITE;
|
||||
break;
|
||||
case BOOKING:
|
||||
frame.setBackgroundResource(R.drawable.button_booking);
|
||||
color = Color.WHITE;
|
||||
break;
|
||||
|
||||
case BOOKMARK:
|
||||
mBookmarkButtonIcon = icon;
|
||||
updateButtons();
|
||||
color = ThemeUtils.getColor(getContext(), R.attr.iconTint);
|
||||
break;
|
||||
case BOOKMARK:
|
||||
mBookmarkButtonIcon = icon;
|
||||
updateButtons();
|
||||
color = ThemeUtils.getColor(getContext(), R.attr.iconTint);
|
||||
break;
|
||||
|
||||
default:
|
||||
color = ThemeUtils.getColor(getContext(), R.attr.iconTint);
|
||||
icon.setColorFilter(color);
|
||||
break;
|
||||
default:
|
||||
color = ThemeUtils.getColor(getContext(), R.attr.iconTint);
|
||||
icon.setColorFilter(color);
|
||||
break;
|
||||
}
|
||||
|
||||
title.setTextColor(color);
|
||||
|
@ -338,62 +389,63 @@ public class PlacePageView extends RelativeLayout
|
|||
hide();
|
||||
break;
|
||||
|
||||
case ROUTE_TO:
|
||||
if (RoutingController.get().isPlanning())
|
||||
{
|
||||
if (RoutingController.get().setEndPoint(mMapObject))
|
||||
hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
getActivity().startLocationToPoint(Statistics.EventName.PP_ROUTE, AlohaHelper.PP_ROUTE, getMapObject());
|
||||
}
|
||||
break;
|
||||
case ROUTE_TO:
|
||||
if (RoutingController.get().isPlanning())
|
||||
{
|
||||
if (RoutingController.get().setEndPoint(mMapObject))
|
||||
hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
getActivity().startLocationToPoint(Statistics.EventName.PP_ROUTE, AlohaHelper.PP_ROUTE, getMapObject());
|
||||
}
|
||||
break;
|
||||
|
||||
case BOOKING:
|
||||
onBookingClick(true /* book */);
|
||||
break;
|
||||
case BOOKING:
|
||||
onBookingClick(true /* book */);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mDownloaderIcon = new DownloaderStatusIcon(mPreview.findViewById(R.id.downloader_status_frame))
|
||||
.setOnIconClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
MapManager.warn3gAndDownload(getActivity(), mCurrentCountry.id, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_ACTION,
|
||||
Statistics.params()
|
||||
.add(Statistics.EventParam.ACTION, "download")
|
||||
.add(Statistics.EventParam.FROM, "placepage")
|
||||
.add("is_auto", "false")
|
||||
.add("scenario", (mCurrentCountry.isExpandable() ? "download_group"
|
||||
: "download")));
|
||||
}
|
||||
});
|
||||
}
|
||||
}).setOnCancelClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
MapManager.nativeCancel(mCurrentCountry.id);
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_CANCEL,
|
||||
Statistics.params().add(Statistics.EventParam.FROM, "placepage"));
|
||||
}
|
||||
});
|
||||
.setOnIconClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
MapManager.warn3gAndDownload(getActivity(), mCurrentCountry.id, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_ACTION,
|
||||
Statistics.params()
|
||||
.add(Statistics.EventParam.ACTION, "download")
|
||||
.add(Statistics.EventParam.FROM, "placepage")
|
||||
.add("is_auto", "false")
|
||||
.add("scenario", (mCurrentCountry.isExpandable() ? "download_group"
|
||||
: "download")));
|
||||
}
|
||||
});
|
||||
}
|
||||
}).setOnCancelClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
MapManager.nativeCancel(mCurrentCountry.id);
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_CANCEL,
|
||||
Statistics.params()
|
||||
.add(Statistics.EventParam.FROM, "placepage"));
|
||||
}
|
||||
});
|
||||
|
||||
mDownloaderInfo = (TextView) mPreview.findViewById(R.id.tv__downloader_details);
|
||||
|
||||
mShadowController = new ScrollViewShadowController((ObservableScrollView) mDetails)
|
||||
.addBottomShadow()
|
||||
.attach();
|
||||
.addBottomShadow()
|
||||
.attach();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
setElevation(UiUtils.dimen(R.dimen.placepage_elevation));
|
||||
|
@ -401,11 +453,62 @@ public class PlacePageView extends RelativeLayout
|
|||
if (UiUtils.isLandscape(getContext()))
|
||||
mDetails.setBackgroundResource(0);
|
||||
|
||||
SponsoredHotel.setListener(this);
|
||||
SponsoredHotel.setPriceListener(this);
|
||||
SponsoredHotel.setInfoListener(this);
|
||||
}
|
||||
|
||||
private void initHotelRatingView()
|
||||
{
|
||||
mHotelReview = findViewById(R.id.ll__place_hotel_rating);
|
||||
GridView gvHotelReview = (GridView) findViewById(R.id.gv__place_hotel_review);
|
||||
gvHotelReview.setAdapter(mReviewAdapter);
|
||||
mHotelRating = (TextView) findViewById(R.id.tv__place_hotel_rating);
|
||||
mHotelRatingBase = (TextView) findViewById(R.id.tv__place_hotel_rating_base);
|
||||
View hotelMoreReviews = findViewById(R.id.tv__place_hotel_reviews_more);
|
||||
hotelMoreReviews.setOnClickListener(this);
|
||||
}
|
||||
|
||||
private void initHotelNearbyView()
|
||||
{
|
||||
mHotelNearby = findViewById(R.id.ll__place_hotel_nearby);
|
||||
GridView gvHotelNearby = (GridView) findViewById(R.id.gv__place_hotel_nearby);
|
||||
gvHotelNearby.setAdapter(mNearbyAdapter);
|
||||
}
|
||||
|
||||
private void initHotelGalleryView()
|
||||
{
|
||||
mHotelGallery = findViewById(R.id.ll__place_hotel_gallery);
|
||||
mRvHotelGallery = (RecyclerView) findViewById(
|
||||
R.id.rv__place_hotel_gallery);
|
||||
mRvHotelGallery.setLayoutManager(new LinearLayoutManager(getContext(),
|
||||
LinearLayoutManager.HORIZONTAL, false));
|
||||
mRvHotelGallery.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(getContext(),
|
||||
R.drawable.divider_transparent)));
|
||||
mGalleryAdapter.setListener(this);
|
||||
mRvHotelGallery.setAdapter(mGalleryAdapter);
|
||||
}
|
||||
|
||||
private void initHotelFacilitiesView()
|
||||
{
|
||||
mHotelFacilities = findViewById(R.id.ll__place_hotel_facilities);
|
||||
GridView gvHotelFacilities = (GridView) findViewById(R.id.gv__place_hotel_facilities);
|
||||
mHotelMoreFacilities = findViewById(R.id.tv__place_hotel_facilities_more);
|
||||
gvHotelFacilities.setAdapter(mFacilitiesAdapter);
|
||||
mHotelMoreFacilities.setOnClickListener(this);
|
||||
}
|
||||
|
||||
private void initHotelDescriptionView()
|
||||
{
|
||||
mHotelDescription = findViewById(R.id.ll__place_hotel_description);
|
||||
mTvHotelDescription = (LineCountTextView) findViewById(R.id.tv__place_hotel_details);
|
||||
mHotelMoreDescription = findViewById(R.id.tv__place_hotel_more);
|
||||
mTvHotelDescription.setListener(this);
|
||||
mHotelMoreDescription.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPriceReceived(String id, String price, String currencyCode)
|
||||
public void onPriceReceived(@NonNull String id, @NonNull String price,
|
||||
@NonNull String currencyCode)
|
||||
{
|
||||
if (mSponsoredHotel == null || !TextUtils.equals(id, mSponsoredHotel.getId()))
|
||||
return;
|
||||
|
@ -424,6 +527,110 @@ public class PlacePageView extends RelativeLayout
|
|||
refreshPreview();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoReceived(@NonNull String id, @NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
if (mSponsoredHotel == null || !TextUtils.equals(id, mSponsoredHotel.getId()))
|
||||
return;
|
||||
|
||||
updateHotelDetails(info);
|
||||
updateHotelFacilities(info);
|
||||
updateHotelGallery(info);
|
||||
updateHotelNearby(info);
|
||||
updateHotelRating(info);
|
||||
}
|
||||
|
||||
private void updateHotelRating(@NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
if (info.mReviews == null || info.mReviews.length == 0)
|
||||
{
|
||||
UiUtils.hide(mHotelReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mHotelReview);
|
||||
mReviewAdapter.setItems(new ArrayList<>(Arrays.asList(info.mReviews)));
|
||||
mHotelRating.setText(mSponsoredHotel.mRating);
|
||||
mHotelRatingBase.setText(getResources().getQuantityString(R.plurals.place_page_booking_rating_base,
|
||||
info.mReviews.length, info.mReviews.length));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHotelNearby(@NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
if (info.mNearby == null || info.mNearby.length == 0)
|
||||
{
|
||||
UiUtils.hide(mHotelNearby);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mHotelNearby);
|
||||
mNearbyAdapter.setItems(Arrays.asList(info.mNearby));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHotelGallery(@NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
if (info.mPhotos == null || info.mPhotos.length == 0)
|
||||
{
|
||||
UiUtils.hide(mHotelGallery);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mHotelGallery);
|
||||
mGalleryAdapter.setItems(new ArrayList<>(Arrays.asList(info.mPhotos)));
|
||||
mRvHotelGallery.scrollToPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHotelFacilities(@NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
if (info.mFacilities == null || info.mFacilities.length == 0)
|
||||
{
|
||||
UiUtils.hide(mHotelFacilities);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mHotelFacilities);
|
||||
mFacilitiesAdapter.setShowAll(false);
|
||||
mFacilitiesAdapter.setItems(Arrays.asList(info.mFacilities));
|
||||
mHotelMoreFacilities.setVisibility(info.mFacilities.length > FacilitiesAdapter.MAX_COUNT
|
||||
? VISIBLE : GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHotelDetails(@NonNull SponsoredHotel.HotelInfo info)
|
||||
{
|
||||
mTvHotelDescription.setMaxLines(getResources().getInteger(R.integer.pp_hotel_description_lines));
|
||||
refreshMetadataOrHide(info.mDescription, mHotelDescription, mTvHotelDescription);
|
||||
mHotelMoreDescription.setVisibility(GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLineCountCalculated(boolean grater)
|
||||
{
|
||||
UiUtils.showIf(grater, mHotelMoreDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(View v, int position)
|
||||
{
|
||||
if (position == GalleryAdapter.MAX_COUNT - 1)
|
||||
{
|
||||
GalleryActivity.start(getContext(), mGalleryAdapter.getItems(), mMapObject.getTitle());
|
||||
}
|
||||
else
|
||||
{
|
||||
FullScreenGalleryActivity.start(getContext(), mGalleryAdapter.getItems(), position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(@NonNull SponsoredHotel.NearbyObject item)
|
||||
{
|
||||
// TODO go to selected object on map
|
||||
}
|
||||
|
||||
private void onBookingClick(final boolean book)
|
||||
{
|
||||
// TODO (trashkalmar): Set correct text
|
||||
|
@ -453,7 +660,7 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
try
|
||||
{
|
||||
followUrl(book ? info.urlBook : info.urlDescription);
|
||||
followUrl(book ? info.mUrlBook : info.mUrlDescription);
|
||||
} catch (ActivityNotFoundException e)
|
||||
{
|
||||
AlohaHelper.logException(e);
|
||||
|
@ -482,7 +689,7 @@ public class PlacePageView extends RelativeLayout
|
|||
public void restore()
|
||||
{
|
||||
// if (mMapObject != null)
|
||||
// FIXME query map object again
|
||||
// FIXME query map object again
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -539,7 +746,7 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
/**
|
||||
* @param mapObject new MapObject
|
||||
* @param force if true, new object'll be set without comparison with the old one
|
||||
* @param force if true, new object'll be set without comparison with the old one
|
||||
*/
|
||||
public void setMapObject(MapObject mapObject, boolean force)
|
||||
{
|
||||
|
@ -555,10 +762,14 @@ public class PlacePageView extends RelativeLayout
|
|||
if (mSponsoredHotel != null)
|
||||
{
|
||||
mSponsoredHotel.updateId(mMapObject);
|
||||
mSponsoredHotelPrice = mSponsoredHotel.price;
|
||||
mSponsoredHotelPrice = mSponsoredHotel.mPrice;
|
||||
|
||||
Currency currency = Currency.getInstance(Locale.getDefault());
|
||||
Locale locale = Locale.getDefault();
|
||||
Currency currency = Currency.getInstance(locale);
|
||||
SponsoredHotel.requestPrice(mSponsoredHotel.getId(), currency.getCurrencyCode());
|
||||
// TODO: remove this after booking_api.cpp will be done
|
||||
if (!USE_OLD_BOOKING)
|
||||
SponsoredHotel.requestInfo(mSponsoredHotel.getId(), locale.toString());
|
||||
}
|
||||
|
||||
String country = MapManager.nativeGetSelectedCountry();
|
||||
|
@ -580,27 +791,27 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
switch (mMapObject.getMapObjectType())
|
||||
{
|
||||
case MapObject.BOOKMARK:
|
||||
refreshDistanceToObject(loc);
|
||||
showBookmarkDetails();
|
||||
setButtons(false, true);
|
||||
break;
|
||||
case MapObject.POI:
|
||||
case MapObject.SEARCH:
|
||||
refreshDistanceToObject(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(false, true);
|
||||
break;
|
||||
case MapObject.API_POINT:
|
||||
refreshDistanceToObject(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(true, true);
|
||||
break;
|
||||
case MapObject.MY_POSITION:
|
||||
refreshMyPosition(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(false, false);
|
||||
break;
|
||||
case MapObject.BOOKMARK:
|
||||
refreshDistanceToObject(loc);
|
||||
showBookmarkDetails();
|
||||
setButtons(false, true);
|
||||
break;
|
||||
case MapObject.POI:
|
||||
case MapObject.SEARCH:
|
||||
refreshDistanceToObject(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(false, true);
|
||||
break;
|
||||
case MapObject.API_POINT:
|
||||
refreshDistanceToObject(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(true, true);
|
||||
break;
|
||||
case MapObject.MY_POSITION:
|
||||
refreshMyPosition(loc);
|
||||
hideBookmarkDetails();
|
||||
setButtons(false, false);
|
||||
break;
|
||||
}
|
||||
|
||||
UiThread.runLater(new Runnable()
|
||||
|
@ -645,7 +856,7 @@ public class PlacePageView extends RelativeLayout
|
|||
UiUtils.showIf(sponsored, mHotelInfo);
|
||||
if (sponsored)
|
||||
{
|
||||
mTvHotelRating.setText(mSponsoredHotel.rating);
|
||||
mTvHotelRating.setText(mSponsoredHotel.mRating);
|
||||
UiUtils.setTextAndHideIfEmpty(mTvHotelPrice, mSponsoredHotelPrice);
|
||||
}
|
||||
}
|
||||
|
@ -658,9 +869,21 @@ public class PlacePageView extends RelativeLayout
|
|||
{
|
||||
final String website = mMapObject.getMetadata(Metadata.MetadataType.FMD_WEBSITE);
|
||||
refreshMetadataOrHide(TextUtils.isEmpty(website) ? mMapObject.getMetadata(Metadata.MetadataType.FMD_URL) : website, mWebsite, mTvWebsite);
|
||||
UiUtils.hide(mHotelDescription);
|
||||
UiUtils.hide(mHotelFacilities);
|
||||
UiUtils.hide(mHotelGallery);
|
||||
UiUtils.hide(mHotelNearby);
|
||||
UiUtils.hide(mHotelReview);
|
||||
// TODO: remove this after booking_api.cpp will be done
|
||||
UiUtils.hide(mHotelMore);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.hide(mWebsite);
|
||||
// TODO: remove this after booking_api.cpp will be done
|
||||
if (!USE_OLD_BOOKING)
|
||||
UiUtils.hide(mHotelMore);
|
||||
}
|
||||
|
||||
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER), mPhone, mTvPhone);
|
||||
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_EMAIL), mEmail, mTvEmail);
|
||||
|
@ -683,8 +906,6 @@ public class PlacePageView extends RelativeLayout
|
|||
UiUtils.showIf(Editor.nativeShouldShowAddBusiness(), mAddOrganisation);
|
||||
UiUtils.showIf(Editor.nativeShouldShowAddPlace(), mAddPlace);
|
||||
}
|
||||
|
||||
UiUtils.showIf(mSponsoredHotel != null, mMoreInfo);
|
||||
}
|
||||
|
||||
private void refreshOpeningHours()
|
||||
|
@ -824,8 +1045,11 @@ public class PlacePageView extends RelativeLayout
|
|||
return;
|
||||
|
||||
mTvDistance.setVisibility(View.VISIBLE);
|
||||
DistanceAndAzimut distanceAndAzimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), mMapObject.getLon(),
|
||||
l.getLatitude(), l.getLongitude(), 0.0);
|
||||
DistanceAndAzimut distanceAndAzimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject
|
||||
.getLat(), mMapObject
|
||||
.getLon(),
|
||||
l.getLatitude(), l
|
||||
.getLongitude(), 0.0);
|
||||
mTvDistance.setText(distanceAndAzimuth.getDistance());
|
||||
}
|
||||
|
||||
|
@ -853,16 +1077,18 @@ public class PlacePageView extends RelativeLayout
|
|||
public void refreshAzimuth(double northAzimuth)
|
||||
{
|
||||
if (isHidden() ||
|
||||
mMapObject == null ||
|
||||
MapObject.isOfType(MapObject.MY_POSITION, mMapObject))
|
||||
mMapObject == null ||
|
||||
MapObject.isOfType(MapObject.MY_POSITION, mMapObject))
|
||||
return;
|
||||
|
||||
final Location location = LocationHelper.INSTANCE.getSavedLocation();
|
||||
if (location == null)
|
||||
return;
|
||||
|
||||
final double azimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), mMapObject.getLon(),
|
||||
location.getLatitude(), location.getLongitude(),
|
||||
final double azimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), mMapObject
|
||||
.getLon(),
|
||||
location.getLatitude(), location
|
||||
.getLongitude(),
|
||||
northAzimuth)
|
||||
.getAzimuth();
|
||||
if (azimuth >= 0)
|
||||
|
@ -880,7 +1106,8 @@ public class PlacePageView extends RelativeLayout
|
|||
private void addOrganisation()
|
||||
{
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.EDITOR_ADD_CLICK,
|
||||
Statistics.params().add(Statistics.EventParam.FROM, "placepage"));
|
||||
Statistics.params()
|
||||
.add(Statistics.EventParam.FROM, "placepage"));
|
||||
getActivity().showPositionChooser(true, false);
|
||||
}
|
||||
|
||||
|
@ -895,56 +1122,69 @@ public class PlacePageView extends RelativeLayout
|
|||
{
|
||||
switch (v.getId())
|
||||
{
|
||||
case R.id.ll__place_editor:
|
||||
getActivity().showEditor();
|
||||
break;
|
||||
case R.id.ll__add_organisation:
|
||||
addOrganisation();
|
||||
break;
|
||||
case R.id.ll__place_add:
|
||||
addPlace();
|
||||
break;
|
||||
case R.id.ll__more:
|
||||
onBookingClick(false /* book */);
|
||||
break;
|
||||
case R.id.ll__place_latlon:
|
||||
mIsLatLonDms = !mIsLatLonDms;
|
||||
MwmApplication.prefs().edit().putBoolean(PREF_USE_DMS, mIsLatLonDms).commit();
|
||||
refreshLatLon();
|
||||
break;
|
||||
case R.id.ll__place_phone:
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:" + mTvPhone.getText()));
|
||||
try
|
||||
{
|
||||
case R.id.ll__place_editor:
|
||||
getActivity().showEditor();
|
||||
break;
|
||||
case R.id.ll__add_organisation:
|
||||
addOrganisation();
|
||||
break;
|
||||
case R.id.ll__place_add:
|
||||
addPlace();
|
||||
break;
|
||||
case R.id.ll__more:
|
||||
onBookingClick(false /* book */);
|
||||
break;
|
||||
case R.id.ll__place_latlon:
|
||||
mIsLatLonDms = !mIsLatLonDms;
|
||||
MwmApplication.prefs().edit().putBoolean(PREF_USE_DMS, mIsLatLonDms).commit();
|
||||
refreshLatLon();
|
||||
break;
|
||||
case R.id.ll__place_phone:
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:" + mTvPhone.getText()));
|
||||
try
|
||||
{
|
||||
getContext().startActivity(intent);
|
||||
} catch (ActivityNotFoundException e)
|
||||
{
|
||||
AlohaHelper.logException(e);
|
||||
}
|
||||
break;
|
||||
case R.id.ll__place_website:
|
||||
followUrl(mTvWebsite.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_wiki:
|
||||
// TODO: Refactor and use separate getters for Wiki and all other PP meta info too.
|
||||
followUrl(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA));
|
||||
break;
|
||||
case R.id.direction_frame:
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_DIRECTION_ARROW);
|
||||
AlohaHelper.logClick(AlohaHelper.PP_DIRECTION_ARROW);
|
||||
showBigDirection();
|
||||
break;
|
||||
case R.id.ll__place_email:
|
||||
intent = new Intent(Intent.ACTION_SENDTO);
|
||||
intent.setData(Utils.buildMailUri(mTvEmail.getText().toString(), "", ""));
|
||||
getContext().startActivity(intent);
|
||||
} catch (ActivityNotFoundException e)
|
||||
{
|
||||
AlohaHelper.logException(e);
|
||||
}
|
||||
break;
|
||||
case R.id.ll__place_website:
|
||||
followUrl(mTvWebsite.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_wiki:
|
||||
// TODO: Refactor and use separate getters for Wiki and all other PP meta info too.
|
||||
followUrl(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA));
|
||||
break;
|
||||
case R.id.direction_frame:
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_DIRECTION_ARROW);
|
||||
AlohaHelper.logClick(AlohaHelper.PP_DIRECTION_ARROW);
|
||||
showBigDirection();
|
||||
break;
|
||||
case R.id.ll__place_email:
|
||||
intent = new Intent(Intent.ACTION_SENDTO);
|
||||
intent.setData(Utils.buildMailUri(mTvEmail.getText().toString(), "", ""));
|
||||
getContext().startActivity(intent);
|
||||
break;
|
||||
case R.id.tv__bookmark_edit:
|
||||
Bookmark bookmark = (Bookmark) mMapObject;
|
||||
EditBookmarkFragment.editBookmark(bookmark.getCategoryId(), bookmark.getBookmarkId(),
|
||||
getActivity(), getActivity().getSupportFragmentManager());
|
||||
break;
|
||||
break;
|
||||
case R.id.tv__bookmark_edit:
|
||||
Bookmark bookmark = (Bookmark) mMapObject;
|
||||
EditBookmarkFragment.editBookmark(bookmark.getCategoryId(), bookmark.getBookmarkId(),
|
||||
getActivity(), getActivity().getSupportFragmentManager());
|
||||
break;
|
||||
case R.id.tv__place_hotel_more:
|
||||
UiUtils.hide(mHotelMoreDescription);
|
||||
mTvHotelDescription.setMaxLines(Integer.MAX_VALUE);
|
||||
break;
|
||||
case R.id.tv__place_hotel_facilities_more:
|
||||
UiUtils.hide(mHotelMoreFacilities);
|
||||
mFacilitiesAdapter.setShowAll(true);
|
||||
break;
|
||||
case R.id.tv__place_hotel_reviews_more:
|
||||
ReviewActivity.start(getContext(), mReviewAdapter.getItems(), mMapObject.getTitle(),
|
||||
mSponsoredHotel.mRating, mReviewAdapter.getItems()
|
||||
.size(), mSponsoredHotel.mUrlBook);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -976,7 +1216,8 @@ public class PlacePageView extends RelativeLayout
|
|||
|
||||
private void showBigDirection()
|
||||
{
|
||||
final DirectionFragment fragment = (DirectionFragment) Fragment.instantiate(getActivity(), DirectionFragment.class.getName(), null);
|
||||
final DirectionFragment fragment = (DirectionFragment) Fragment.instantiate(getActivity(), DirectionFragment.class
|
||||
.getName(), null);
|
||||
fragment.setMapObject(mMapObject);
|
||||
fragment.show(getActivity().getSupportFragmentManager(), null);
|
||||
}
|
||||
|
@ -993,30 +1234,30 @@ public class PlacePageView extends RelativeLayout
|
|||
final List<String> items = new ArrayList<>();
|
||||
switch (v.getId())
|
||||
{
|
||||
case R.id.ll__place_latlon:
|
||||
final double lat = mMapObject.getLat();
|
||||
final double lon = mMapObject.getLon();
|
||||
items.add(Framework.nativeFormatLatLon(lat, lon, false));
|
||||
items.add(Framework.nativeFormatLatLon(lat, lon, true));
|
||||
break;
|
||||
case R.id.ll__place_website:
|
||||
items.add(mTvWebsite.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_email:
|
||||
items.add(mTvEmail.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_phone:
|
||||
items.add(mTvPhone.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_schedule:
|
||||
items.add(mFullOpeningHours.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_operator:
|
||||
items.add(mTvOperator.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_wiki:
|
||||
items.add(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA));
|
||||
break;
|
||||
case R.id.ll__place_latlon:
|
||||
final double lat = mMapObject.getLat();
|
||||
final double lon = mMapObject.getLon();
|
||||
items.add(Framework.nativeFormatLatLon(lat, lon, false));
|
||||
items.add(Framework.nativeFormatLatLon(lat, lon, true));
|
||||
break;
|
||||
case R.id.ll__place_website:
|
||||
items.add(mTvWebsite.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_email:
|
||||
items.add(mTvEmail.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_phone:
|
||||
items.add(mTvPhone.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_schedule:
|
||||
items.add(mFullOpeningHours.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_operator:
|
||||
items.add(mTvOperator.getText().toString());
|
||||
break;
|
||||
case R.id.ll__place_wiki:
|
||||
items.add(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA));
|
||||
break;
|
||||
}
|
||||
|
||||
final String copyText = getResources().getString(android.R.string.copy);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package com.mapswithme.maps.widget.placepage;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.review.Review;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
class ReviewAdapter extends BaseAdapter
|
||||
{
|
||||
private static final int MAX_COUNT = 3;
|
||||
|
||||
@NonNull
|
||||
private ArrayList<Review> mItems = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return Math.min(mItems.size(), MAX_COUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position)
|
||||
{
|
||||
return mItems.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
ViewHolder holder;
|
||||
if (convertView == null)
|
||||
{
|
||||
convertView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_comment, parent, false);
|
||||
holder = new ViewHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.bind(mItems.get(position), position > 0);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
public void setItems(@NonNull ArrayList<Review> items)
|
||||
{
|
||||
this.mItems = items;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ArrayList<Review> getItems()
|
||||
{
|
||||
return mItems;
|
||||
}
|
||||
|
||||
private static class ViewHolder
|
||||
{
|
||||
@NonNull
|
||||
final View mDivider;
|
||||
@NonNull
|
||||
final TextView mUserName;
|
||||
@NonNull
|
||||
final TextView mCommentDate;
|
||||
@NonNull
|
||||
final TextView mRating;
|
||||
@NonNull
|
||||
final View mPositiveReview;
|
||||
@NonNull
|
||||
final TextView mTvPositiveReview;
|
||||
@NonNull
|
||||
final View mNegativeReview;
|
||||
@NonNull
|
||||
final TextView mTvNegativeReview;
|
||||
|
||||
public ViewHolder(View view)
|
||||
{
|
||||
mDivider = view.findViewById(R.id.v__divider);
|
||||
mUserName = (TextView) view.findViewById(R.id.tv__user_name);
|
||||
mCommentDate = (TextView) view.findViewById(R.id.tv__comment_date);
|
||||
mRating = (TextView) view.findViewById(R.id.tv__user_rating);
|
||||
mPositiveReview = view.findViewById(R.id.ll__positive_review);
|
||||
mTvPositiveReview = (TextView) view.findViewById(R.id.tv__positive_review);
|
||||
mNegativeReview = view.findViewById(R.id.ll__negative_review);
|
||||
mTvNegativeReview = (TextView) view.findViewById(R.id.tv__negative_review);
|
||||
}
|
||||
|
||||
public void bind(Review item, boolean isShowDivider)
|
||||
{
|
||||
UiUtils.showIf(isShowDivider, mDivider);
|
||||
mUserName.setText(item.getAuthor());
|
||||
Date date = new Date(item.getDate());
|
||||
mCommentDate.setText(DateFormat.getMediumDateFormat(mCommentDate.getContext()).format(date));
|
||||
mRating.setText(String.format(Locale.getDefault(), "%.1f", item.getRating()));
|
||||
if (TextUtils.isEmpty(item.getReviewPositive()))
|
||||
{
|
||||
UiUtils.hide(mPositiveReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mPositiveReview);
|
||||
mTvPositiveReview.setText(item.getReviewPositive());
|
||||
}
|
||||
if (TextUtils.isEmpty(item.getReviewNegative()))
|
||||
{
|
||||
UiUtils.hide(mNegativeReview);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mNegativeReview);
|
||||
mTvNegativeReview.setText(item.getReviewNegative());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +1,194 @@
|
|||
package com.mapswithme.maps.widget.placepage;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mapswithme.maps.bookmarks.data.MapObject;
|
||||
import com.mapswithme.maps.bookmarks.data.Metadata;
|
||||
import com.mapswithme.maps.gallery.Image;
|
||||
import com.mapswithme.maps.review.Review;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mapswithme.maps.bookmarks.data.MapObject;
|
||||
import com.mapswithme.maps.bookmarks.data.Metadata;
|
||||
|
||||
@UiThread
|
||||
public final class SponsoredHotel
|
||||
{
|
||||
private static class Price
|
||||
{
|
||||
final String price;
|
||||
final String currency;
|
||||
@NonNull
|
||||
final String mPrice;
|
||||
@NonNull
|
||||
final String mCurrency;
|
||||
|
||||
private Price(String price, String currency)
|
||||
private Price(@NonNull String price, @NonNull String currency)
|
||||
{
|
||||
this.price = price;
|
||||
this.currency = currency;
|
||||
mPrice = price;
|
||||
mCurrency = currency;
|
||||
}
|
||||
}
|
||||
|
||||
static class FacilityType
|
||||
{
|
||||
@NonNull
|
||||
private final String mKey;
|
||||
@NonNull
|
||||
private final String mName;
|
||||
|
||||
public FacilityType(@NonNull String key, @NonNull String name)
|
||||
{
|
||||
mKey = key;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getKey()
|
||||
{
|
||||
return mKey;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
|
||||
static class NearbyObject
|
||||
{
|
||||
@NonNull
|
||||
private final String mCategory;
|
||||
@NonNull
|
||||
private final String mTitle;
|
||||
@NonNull
|
||||
private final String mDistance;
|
||||
private final double mLatitude;
|
||||
private final double mLongitude;
|
||||
|
||||
public NearbyObject(@NonNull String category, @NonNull String title,
|
||||
@NonNull String distance, double lat, double lon)
|
||||
{
|
||||
mCategory = category;
|
||||
mTitle = title;
|
||||
mDistance = distance;
|
||||
mLatitude = lat;
|
||||
mLongitude = lon;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getCategory()
|
||||
{
|
||||
return mCategory;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getTitle()
|
||||
{
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getDistance()
|
||||
{
|
||||
return mDistance;
|
||||
}
|
||||
|
||||
public double getLatitude()
|
||||
{
|
||||
return mLatitude;
|
||||
}
|
||||
|
||||
public double getLongitude()
|
||||
{
|
||||
return mLongitude;
|
||||
}
|
||||
}
|
||||
|
||||
static class HotelInfo
|
||||
{
|
||||
@Nullable
|
||||
final String mDescription;
|
||||
@Nullable
|
||||
final Image[] mPhotos;
|
||||
@Nullable
|
||||
final FacilityType[] mFacilities;
|
||||
@Nullable
|
||||
final Review[] mReviews;
|
||||
@Nullable
|
||||
final NearbyObject[] mNearby;
|
||||
|
||||
public HotelInfo(@Nullable String description, @Nullable Image[] photos,
|
||||
@Nullable FacilityType[] facilities, @Nullable Review[] reviews,
|
||||
@Nullable NearbyObject[] nearby)
|
||||
{
|
||||
mDescription = description;
|
||||
mPhotos = photos;
|
||||
mFacilities = facilities;
|
||||
mReviews = reviews;
|
||||
mNearby = nearby;
|
||||
}
|
||||
}
|
||||
|
||||
interface OnPriceReceivedListener
|
||||
{
|
||||
void onPriceReceived(String id, String price, String currency);
|
||||
/**
|
||||
* This method is called from the native core on the UI thread
|
||||
* when the Hotel price will be obtained
|
||||
*
|
||||
* @param id A hotel id
|
||||
* @param price A price
|
||||
* @param currency A price currency
|
||||
*/
|
||||
@UiThread
|
||||
void onPriceReceived(@NonNull String id, @NonNull String price, @NonNull String currency);
|
||||
}
|
||||
|
||||
interface OnInfoReceivedListener
|
||||
{
|
||||
/**
|
||||
* This method is called from the native core on the UI thread
|
||||
* when the Hotel information will be obtained
|
||||
*
|
||||
* @param id A hotel id
|
||||
* @param info A hotel info
|
||||
*/
|
||||
@UiThread
|
||||
void onInfoReceived(@NonNull String id, @NonNull HotelInfo info);
|
||||
}
|
||||
|
||||
// Hotel ID -> Price
|
||||
@NonNull
|
||||
private static final Map<String, Price> sPriceCache = new HashMap<>();
|
||||
private static WeakReference<OnPriceReceivedListener> sListener;
|
||||
// Hotel ID -> Description
|
||||
@NonNull
|
||||
private static final Map<String, HotelInfo> sInfoCache = new HashMap<>();
|
||||
@NonNull
|
||||
private static WeakReference<OnPriceReceivedListener> sPriceListener = new WeakReference<>(null);
|
||||
@NonNull
|
||||
private static WeakReference<OnInfoReceivedListener> sInfoListener = new WeakReference<>(null);
|
||||
|
||||
@Nullable
|
||||
private String mId;
|
||||
|
||||
final String rating;
|
||||
final String price;
|
||||
final String urlBook;
|
||||
final String urlDescription;
|
||||
@NonNull
|
||||
final String mRating;
|
||||
@NonNull
|
||||
final String mPrice;
|
||||
@NonNull
|
||||
final String mUrlBook;
|
||||
@NonNull
|
||||
final String mUrlDescription;
|
||||
|
||||
public SponsoredHotel(String rating, String price, String urlBook, String urlDescription)
|
||||
public SponsoredHotel(@NonNull String rating, @NonNull String price, @NonNull String urlBook,
|
||||
@NonNull String urlDescription)
|
||||
{
|
||||
this.rating = rating;
|
||||
this.price = price;
|
||||
this.urlBook = urlBook;
|
||||
this.urlDescription = urlDescription;
|
||||
mRating = rating;
|
||||
mPrice = price;
|
||||
mUrlBook = urlBook;
|
||||
mUrlDescription = urlDescription;
|
||||
}
|
||||
|
||||
void updateId(MapObject point)
|
||||
|
@ -55,61 +196,107 @@ public final class SponsoredHotel
|
|||
mId = point.getMetadata(Metadata.MetadataType.FMD_SPONSORED_ID);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getId()
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getRating()
|
||||
{
|
||||
return rating;
|
||||
return mRating;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getPrice()
|
||||
{
|
||||
return price;
|
||||
return mPrice;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getUrlBook()
|
||||
{
|
||||
return urlBook;
|
||||
return mUrlBook;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getUrlDescription()
|
||||
{
|
||||
return urlDescription;
|
||||
return mUrlDescription;
|
||||
}
|
||||
|
||||
public static void setListener(OnPriceReceivedListener listener)
|
||||
static void setPriceListener(@NonNull OnPriceReceivedListener listener)
|
||||
{
|
||||
sListener = new WeakReference<>(listener);
|
||||
sPriceListener = new WeakReference<>(listener);
|
||||
}
|
||||
|
||||
static void setInfoListener(@NonNull OnInfoReceivedListener listener)
|
||||
{
|
||||
sInfoListener = new WeakReference<>(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request to obtain hotel price information.
|
||||
* This method also checks cache for requested hotel id
|
||||
* and if cache exists - call {@link #onPriceReceived(String, String, String) onPriceReceived} immediately
|
||||
*
|
||||
* @param id A Hotel id
|
||||
* @param currencyCode A user currency
|
||||
*/
|
||||
static void requestPrice(String id, String currencyCode)
|
||||
{
|
||||
Price p = sPriceCache.get(id);
|
||||
if (p != null)
|
||||
onPriceReceived(id, p.price, p.currency);
|
||||
onPriceReceived(id, p.mPrice, p.mCurrency);
|
||||
|
||||
nativeRequestPrice(id, currencyCode);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void onPriceReceived(String id, String price, String currency)
|
||||
/**
|
||||
* Make request to obtain hotel information.
|
||||
* This method also checks cache for requested hotel id
|
||||
* and if cache exists - call {@link #onInfoReceived(String, HotelInfo) onInfoReceived} immediately
|
||||
*
|
||||
* @param id A Hotel id
|
||||
* @param locale A user locale
|
||||
*/
|
||||
static void requestInfo(String id, String locale)
|
||||
{
|
||||
HotelInfo info = sInfoCache.get(id);
|
||||
if (info != null)
|
||||
onInfoReceived(id, info);
|
||||
|
||||
nativeRequestInfo(id, locale);
|
||||
}
|
||||
|
||||
private static void onPriceReceived(@NonNull String id, @NonNull String price,
|
||||
@NonNull String currency)
|
||||
{
|
||||
if (TextUtils.isEmpty(price))
|
||||
return;
|
||||
|
||||
sPriceCache.put(id, new Price(price, currency));
|
||||
|
||||
OnPriceReceivedListener listener = sListener.get();
|
||||
if (listener == null)
|
||||
sListener = null;
|
||||
else
|
||||
|
||||
OnPriceReceivedListener listener = sPriceListener.get();
|
||||
if (listener != null)
|
||||
listener.onPriceReceived(id, price, currency);
|
||||
}
|
||||
|
||||
private static void onInfoReceived(@NonNull String id, @NonNull HotelInfo info)
|
||||
{
|
||||
sInfoCache.put(id, info);
|
||||
|
||||
OnInfoReceivedListener listener = sInfoListener.get();
|
||||
if (listener != null)
|
||||
listener.onInfoReceived(id, info);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static native SponsoredHotel nativeGetCurrent();
|
||||
private static native void nativeRequestPrice(String id, String currencyCode);
|
||||
|
||||
private static native void nativeRequestPrice(@NonNull String id, @NonNull String currencyCode);
|
||||
|
||||
private static native void nativeRequestInfo(@NonNull String id, @NonNull String locale);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package com.mapswithme.maps.widget.recycler;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Adds interior dividers to a RecyclerView with a LinearLayoutManager or its
|
||||
* subclass.
|
||||
*/
|
||||
public class DividerItemDecoration extends RecyclerView.ItemDecoration
|
||||
{
|
||||
|
||||
@NonNull
|
||||
private final Drawable mDivider;
|
||||
private int mOrientation;
|
||||
|
||||
/**
|
||||
* Sole constructor. Takes in a {@link Drawable} to be used as the interior
|
||||
* divider.
|
||||
*
|
||||
* @param divider A divider {@code Drawable} to be drawn on the RecyclerView
|
||||
*/
|
||||
public DividerItemDecoration(@NonNull Drawable divider)
|
||||
{
|
||||
mDivider = divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws horizontal or vertical dividers onto the parent RecyclerView.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which dividers will be drawn
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
* @param state The current RecyclerView.State of the RecyclerView
|
||||
*/
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state)
|
||||
{
|
||||
if (mOrientation == LinearLayoutManager.HORIZONTAL)
|
||||
drawHorizontalDividers(canvas, parent);
|
||||
else if (mOrientation == LinearLayoutManager.VERTICAL)
|
||||
drawVerticalDividers(canvas, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the size and location of offsets between items in the parent
|
||||
* RecyclerView.
|
||||
*
|
||||
* @param outRect The {@link Rect} of offsets to be added around the child
|
||||
* view
|
||||
* @param view The child view to be decorated with an offset
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
* @param state The current RecyclerView.State of the RecyclerView
|
||||
*/
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
|
||||
{
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
|
||||
if (parent.getChildAdapterPosition(view) == 0)
|
||||
return;
|
||||
|
||||
mOrientation = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
|
||||
if (mOrientation == LinearLayoutManager.HORIZONTAL)
|
||||
outRect.left = mDivider.getIntrinsicWidth();
|
||||
else if (mOrientation == LinearLayoutManager.VERTICAL)
|
||||
outRect.top = mDivider.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds dividers to a RecyclerView with a LinearLayoutManager or its
|
||||
* subclass oriented horizontally.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which horizontal dividers will be
|
||||
* drawn
|
||||
* @param parent The RecyclerView onto which horizontal dividers are being
|
||||
* added
|
||||
*/
|
||||
private void drawHorizontalDividers(Canvas canvas, RecyclerView parent)
|
||||
{
|
||||
int parentTop = parent.getPaddingTop();
|
||||
int parentBottom = parent.getHeight() - parent.getPaddingBottom();
|
||||
|
||||
int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount - 1; i++)
|
||||
{
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int parentLeft = child.getRight() + params.rightMargin;
|
||||
int parentRight = parentLeft + mDivider.getIntrinsicWidth();
|
||||
|
||||
mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||
mDivider.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds dividers to a RecyclerView with a LinearLayoutManager or its
|
||||
* subclass oriented vertically.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which vertical dividers will be
|
||||
* drawn
|
||||
* @param parent The RecyclerView onto which vertical dividers are being
|
||||
* added
|
||||
*/
|
||||
private void drawVerticalDividers(Canvas canvas, RecyclerView parent)
|
||||
{
|
||||
int parentLeft = parent.getPaddingLeft();
|
||||
int parentRight = parent.getWidth() - parent.getPaddingRight();
|
||||
|
||||
int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount - 1; i++)
|
||||
{
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int parentTop = child.getBottom() + params.bottomMargin;
|
||||
int parentBottom = parentTop + mDivider.getIntrinsicHeight();
|
||||
|
||||
mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||
mDivider.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.mapswithme.maps.widget.recycler;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Adds interior dividers to a RecyclerView with a GridLayoutManager.
|
||||
*/
|
||||
public class GridDividerItemDecoration extends RecyclerView.ItemDecoration
|
||||
{
|
||||
|
||||
@NonNull
|
||||
private final Drawable mHorizontalDivider;
|
||||
@NonNull
|
||||
private final Drawable mVerticalDivider;
|
||||
private final int mNumColumns;
|
||||
|
||||
/**
|
||||
* Sole constructor. Takes in {@link Drawable} objects to be used as
|
||||
* horizontal and vertical dividers.
|
||||
*
|
||||
* @param horizontalDivider A divider {@code Drawable} to be drawn on the
|
||||
* rows of the grid of the RecyclerView
|
||||
* @param verticalDivider A divider {@code Drawable} to be drawn on the
|
||||
* columns of the grid of the RecyclerView
|
||||
* @param numColumns The number of columns in the grid of the RecyclerView
|
||||
*/
|
||||
public GridDividerItemDecoration(@NonNull Drawable horizontalDivider,
|
||||
@NonNull Drawable verticalDivider, int numColumns)
|
||||
{
|
||||
mHorizontalDivider = horizontalDivider;
|
||||
mVerticalDivider = verticalDivider;
|
||||
mNumColumns = numColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws horizontal and/or vertical dividers onto the parent RecyclerView.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which dividers will be drawn
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
* @param state The current RecyclerView.State of the RecyclerView
|
||||
*/
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state)
|
||||
{
|
||||
drawHorizontalDividers(canvas, parent);
|
||||
drawVerticalDividers(canvas, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the size and location of offsets between items in the parent
|
||||
* RecyclerView.
|
||||
*
|
||||
* @param outRect The {@link Rect} of offsets to be added around the child view
|
||||
* @param view The child view to be decorated with an offset
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
* @param state The current RecyclerView.State of the RecyclerView
|
||||
*/
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
|
||||
{
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
|
||||
boolean childIsInLeftmostColumn = (parent.getChildAdapterPosition(view) % mNumColumns) == 0;
|
||||
if (!childIsInLeftmostColumn)
|
||||
outRect.left = mHorizontalDivider.getIntrinsicWidth();
|
||||
|
||||
boolean childIsInFirstRow = (parent.getChildAdapterPosition(view)) < mNumColumns;
|
||||
if (!childIsInFirstRow)
|
||||
outRect.top = mVerticalDivider.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds horizontal dividers to a RecyclerView with a GridLayoutManager or
|
||||
* its subclass.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which dividers will be drawn
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
*/
|
||||
private void drawHorizontalDividers(Canvas canvas, RecyclerView parent)
|
||||
{
|
||||
int parentTop = parent.getPaddingTop();
|
||||
int parentBottom = parent.getHeight() - parent.getPaddingBottom();
|
||||
|
||||
for (int i = 0; i < mNumColumns; i++)
|
||||
{
|
||||
View child = parent.getChildAt(i);
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int parentLeft = child.getRight() + params.rightMargin;
|
||||
int parentRight = parentLeft + mHorizontalDivider.getIntrinsicWidth();
|
||||
|
||||
mHorizontalDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||
mHorizontalDivider.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds vertical dividers to a RecyclerView with a GridLayoutManager or its
|
||||
* subclass.
|
||||
*
|
||||
* @param canvas The {@link Canvas} onto which dividers will be drawn
|
||||
* @param parent The RecyclerView onto which dividers are being added
|
||||
*/
|
||||
private void drawVerticalDividers(Canvas canvas, RecyclerView parent)
|
||||
{
|
||||
int parentLeft = parent.getPaddingLeft();
|
||||
int parentRight = parent.getWidth() - parent.getPaddingRight();
|
||||
|
||||
int childCount = parent.getChildCount();
|
||||
int numRows = (childCount + (mNumColumns - 1)) / mNumColumns;
|
||||
for (int i = 0; i < numRows - 1; i++)
|
||||
{
|
||||
View child = parent.getChildAt(i * mNumColumns);
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int parentTop = child.getBottom() + params.bottomMargin;
|
||||
int parentBottom = parentTop + mVerticalDivider.getIntrinsicHeight();
|
||||
|
||||
mVerticalDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||
mVerticalDivider.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.AnyRes;
|
||||
|
@ -19,6 +20,7 @@ import android.support.design.widget.TextInputLayout;
|
|||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
@ -339,6 +341,24 @@ public final class UiUtils
|
|||
return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
|
||||
public static boolean isViewTouched(@NonNull MotionEvent event, @NonNull View view)
|
||||
{
|
||||
if (UiUtils.isHidden(view))
|
||||
return false;
|
||||
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
int[] location = new int[2];
|
||||
view.getLocationOnScreen(location);
|
||||
int viewX = location[0];
|
||||
int viewY = location[1];
|
||||
int width = view.getWidth();
|
||||
int height = view.getHeight();
|
||||
Rect viewRect = new Rect(viewX, viewY, viewX + width, viewY + height);
|
||||
|
||||
return viewRect.contains(x, y);
|
||||
}
|
||||
|
||||
// utility class
|
||||
private UiUtils() {}
|
||||
}
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "المزيد";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "حجز";
|
||||
|
||||
"placepage_call_button" = "اتصال";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "توفير عند حجز الفنادق";
|
||||
|
||||
"whats_new_booking_improve_message" = "تحتوي نتائج البحث عن الفنادق الآن على فئة السعر.\nوأضفنا أيضًا أكثر من 110000 فندق.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Více";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Rezervace";
|
||||
|
||||
"placepage_call_button" = "Volat";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Ušetřete při rezervaci hotelů";
|
||||
|
||||
"whats_new_booking_improve_message" = "Výsledky hledání hotelů nyní obsahují cenové kategorie. \nTaké jsme přidali více než 110 000 hotelů.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mere";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Bog";
|
||||
|
||||
"placepage_call_button" = "Ring";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Spar penge når du bestiller hotelværelser";
|
||||
|
||||
"whats_new_booking_improve_message" = "Søgeresultater for hoteller viser nu også priskategorien.\nVi har desuden tilføjet mere end 110.000 hoteller.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mehr";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Buchen";
|
||||
|
||||
"placepage_call_button" = "Anruf";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Beim Buchen von Hotels sparen";
|
||||
|
||||
"whats_new_booking_improve_message" = "Suchergebnisse für Hotels enthalten jetzt die Kategorie Preis.\nAußerdem haben wir über 110.000 Hotels hinzugefügt.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "More";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Book";
|
||||
|
||||
"placepage_call_button" = "Call";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Save when booking hotels";
|
||||
|
||||
"whats_new_booking_improve_message" = "Search results for hotels now contain the price category.\nWe also added more than 110,000 hotels.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "More";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Book";
|
||||
|
||||
"placepage_call_button" = "Call";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Save when booking hotels";
|
||||
|
||||
"whats_new_booking_improve_message" = "Search results for hotels now contain the price category.\nWe also added more than 110,000 hotels.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Más";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Reservar";
|
||||
|
||||
"placepage_call_button" = "Llamar";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Ahorrar al reservar hoteles";
|
||||
|
||||
"whats_new_booking_improve_message" = "La búsqueda de resultados de hoteles ahora contiene la categoría de precios.\nHemos añadido más de 110 000 hoteles.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Lisää";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Varaa";
|
||||
|
||||
"placepage_call_button" = "Soita";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Säästä hotellivarauksissa";
|
||||
|
||||
"whats_new_booking_improve_message" = "Hotellien hakutuloksissa näkyy nyt hintakategoria.\nLisäsimme myös yli 110 000 hotellia.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Plus";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Réserver";
|
||||
|
||||
"placepage_call_button" = "Appeler";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Économisez de l'argent en réservant des hôtels";
|
||||
|
||||
"whats_new_booking_improve_message" = "Les résultats des recherches d'hôtels comprennent maintenant la catégorie de prix.\nNous avons aussi ajouté plus de 110.000 hôtels.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Még";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Foglalás";
|
||||
|
||||
"placepage_call_button" = "Hívás";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Takarékoskodjon szálláshely foglalásakor";
|
||||
|
||||
"whats_new_booking_improve_message" = "A szálláshely keresési eredménye már tartalmazza az árkategóriát. \nEmellett kiegészítettük több mint 110.000 szálláshellyel.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Lainnya";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Pesan";
|
||||
|
||||
"placepage_call_button" = "Hubungi";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Berhemat saat memesan hotel";
|
||||
|
||||
"whats_new_booking_improve_message" = "Hasil pencarian untuk hotel kini disertai kategori harga.\nKami juga menambahkan lebih dari 110.000 hotel.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Altro";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Prenota";
|
||||
|
||||
"placepage_call_button" = "Chiama";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Risparmia alla prenotazione degli hotel";
|
||||
|
||||
"whats_new_booking_improve_message" = "I risultati della ricerca per gli hotel contengono ora la categoria di prezzo.\nInoltre, abbiamo aggiunto più di 110.000 hotel.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "さらに詳しく";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "予約";
|
||||
|
||||
"placepage_call_button" = "コール";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "ホテル予約時に節約しましょう";
|
||||
|
||||
"whats_new_booking_improve_message" = "ホテルの検索結果に価格のカテゴリーが表示されるようになりました。\nさらに、 110,000 軒を超えるホテルを追加しました。";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "자세히";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "예약";
|
||||
|
||||
"placepage_call_button" = "전화";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "호텔 예약 시 절약";
|
||||
|
||||
"whats_new_booking_improve_message" = "이제 가격 범주를 포함하는 호텔에 대한 결과를 검색하세요.\n또한 110,000곳 이상의 호텔이 추가되었습니다.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mer";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Bestill";
|
||||
|
||||
"placepage_call_button" = "Ring";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Spar penger når du bestiller hotell";
|
||||
|
||||
"whats_new_booking_improve_message" = "Søkeresultatene for hoteller inneholder nå priskategori.\nVi har også lagt til flere enn 110.000 hoteller.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Meer";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Boeken";
|
||||
|
||||
"placepage_call_button" = "Bellen";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Bespaar op het boeken van hotels";
|
||||
|
||||
"whats_new_booking_improve_message" = "Zoekresultaten voor hotels bevatten nu de prijscategorie.\nWe hebben ook meer dan 110.000 hotels toegevoegd.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Więcej";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Zarezerwuj";
|
||||
|
||||
"placepage_call_button" = "Zadzwoń";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Oszczędzaj przy rezerwacji hotelów";
|
||||
|
||||
"whats_new_booking_improve_message" = "Wyniki wyszukiwania hoteli zawierają teraz kategorię cenową. \nDodaliśmy też ponad 110 000 hoteli.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mais";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Livro";
|
||||
|
||||
"placepage_call_button" = "Chamada";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Poupe nas reservas de hotéis";
|
||||
|
||||
"whats_new_booking_improve_message" = "Agora, os resultados da pesquisa de hotéis contêm a categoria de preços.\nAdicinámos mais de 110.000 hotéis.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mai multe";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Rezervare";
|
||||
|
||||
"placepage_call_button" = "Apel";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Economisiți bani când rezervați hoteluri";
|
||||
|
||||
"whats_new_booking_improve_message" = "Rezultatele de căutare pentru hoteluri conțin acum categoria de preț. \nAm mai adăugat și peste 110.000 de hoteluri.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Ещё";
|
||||
|
||||
"placepage_more_reviews_button" = "Ещё отзывы";
|
||||
|
||||
"bookingcom_book_button" = "Забронировать";
|
||||
|
||||
"placepage_call_button" = "Позвонить";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Экономь на бронировании отеля";
|
||||
|
||||
"whats_new_booking_improve_message" = "Результаты поиска отелей на карте показывают ценовую категорию.\nОтелей для бронирования стало на 110 000 больше.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Удобства";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Рядом";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Viac";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Rezervovať";
|
||||
|
||||
"placepage_call_button" = "Zavolať";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Ušetriť pri rezervácii hotelov";
|
||||
|
||||
"whats_new_booking_improve_message" = "Výsledky vyhľadávania hotelov odteraz obsahujú aj cenové kategórie. \nTiež sme pridali viac ako 110 000 hotelov.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Mer";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Boka";
|
||||
|
||||
"placepage_call_button" = "Ring";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Spara pengar när du bokar hotell";
|
||||
|
||||
"whats_new_booking_improve_message" = "Sökresultat för hotell innehåller nu priskategorin.\nVi har även lagt till över 110 000 hotell.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "เพิ่มเติม";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "จอง";
|
||||
|
||||
"placepage_call_button" = "โทร";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "ประหยัดเมื่อจองโรงแรม";
|
||||
|
||||
"whats_new_booking_improve_message" = "การค้นหาโรงแรมตอนนี้มีหมวดหมู่ราคาแล้ว\nเรายังได้เพิ่มโรงแรมเข้ามากว่า 110,000 โรงแรมอีกด้วย";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
|
@ -1474,6 +1474,8 @@
|
|||
|
||||
"placepage_more_button" = "Diğer";
|
||||
|
||||
"placepage_more_reviews_button" = "More Reviews";
|
||||
|
||||
"bookingcom_book_button" = "Rezervasyon";
|
||||
|
||||
"placepage_call_button" = "Çağrı";
|
||||
|
@ -1626,3 +1628,9 @@
|
|||
"whats_new_booking_improve_title" = "Otel rezervasyonlarınızdan tasarruf edin";
|
||||
|
||||
"whats_new_booking_improve_message" = "Artık otel arama sonuçlarında fiyat kategorisi de gösteriliyor.\nVe 110,000'den fazla oteli sistemimize ekledik.";
|
||||
|
||||
/* For place page hotel facilities block */
|
||||
"placepage_hotel_facilities" = "Facilities";
|
||||
|
||||
/* For place page hotel nearby block */
|
||||
"placepage_hotel_nearby" = "Nearby";
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue