Added user licence agreement confirmation for welcome screen

This commit is contained in:
Dmitry Donskoy 2019-11-20 17:37:15 +03:00 committed by Aleksandr Zatsepin
parent 0da3864615
commit 58e7ca5691
29 changed files with 225 additions and 37 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

BIN
android/res/drawable-hdpi/img_welcome.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

BIN
android/res/drawable-mdpi/img_welcome.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

BIN
android/res/drawable-xhdpi/img_welcome.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

BIN
android/res/drawable-xxhdpi/img_welcome.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

BIN
android/res/drawable-xxxhdpi/img_welcome.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -0,0 +1,10 @@
<?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="match_parent">
<include
layout="@layout/info_page"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

View file

@ -25,16 +25,17 @@
android:gravity="center_horizontal"
android:orientation="vertical">
<include
android:id="@+id/button_container"
layout="@layout/welcome_buttons_horizontal_container"
android:id="@+id/bottom_container"
layout="@layout/info_page_horizontal_bottom_container"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
android:layout_height="wrap_content">
</include>
<LinearLayout
android:id="@+id/text_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/button_container"
android:layout_above="@id/bottom_container"
android:orientation="vertical">
<TextView
android:id="@+id/tv__title"
@ -42,6 +43,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_half_double_plus"
android:fontFamily="@string/robotoMedium"
android:textSize="@dimen/text_size_toolbar"
android:textAppearance="@style/MwmTextAppearance.Title"
tools:targetApi="jelly_bean"
tools:text="@string/onboarding_welcome_title" />
@ -50,6 +52,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:textSize="@dimen/text_size_body_3"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
tools:text="@string/onboarding_welcome_first_subtitle" />
</LinearLayout>

View file

@ -25,13 +25,14 @@
android:layout_margin="@dimen/margin_base_plus"
android:layout_weight="1">
<include
android:id="@+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bottom_container"
layout="@layout/info_page_horizontal_bottom_container"
android:layout_alignParentBottom="true"
layout="@layout/welcome_buttons_horizontal_container"/>
android:layout_width="match_parent"
android:layout_height="wrap_content">
</include>
<LinearLayout
android:layout_above="@+id/button_container"
android:layout_above="@+id/bottom_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -40,6 +41,7 @@
android:layout_marginTop="@dimen/margin_half_double_plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_toolbar"
android:textAppearance="@style/MwmTextAppearance.Title"
android:fontFamily="@string/robotoMedium"
tools:text="@string/onboarding_welcome_title"
@ -49,6 +51,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:textSize="@dimen/text_size_body_3"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
tools:text="@string/onboarding_welcome_first_subtitle"/>
</LinearLayout>

View file

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapswithme.maps.widget.HeightLimitedFrameLayout
android:layout_above="@id/btn_frame"
android:layout_above="@id/button_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -27,6 +27,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base"
android:textSize="@dimen/text_size_toolbar"
android:textAppearance="@style/MwmTextAppearance.Title"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
@ -39,13 +40,14 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
android:textSize="@dimen/text_size_body_3"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
tools:text="@string/onboarding_welcome_first_subtitle"/>
</LinearLayout>
</com.mapswithme.maps.widget.HeightLimitedFrameLayout>
<include
android:id="@+id/btn_frame"
android:id="@+id/button_container"
layout="@layout/welcome_buttons_vertical_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -6,5 +6,14 @@
<include
layout="@layout/info_page"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
android:layout_alignWithParentIfMissing="true"
android:layout_above="@id/user_agreement_block" />
<include
android:id="@+id/user_agreement_block"
layout="@layout/user_agreement_block"
android:layout_marginBottom="@dimen/margin_base_plus"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>

View file

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapswithme.maps.widget.HeightLimitedFrameLayout
android:layout_above="@id/btn_frame"
android:layout_above="@id/button_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -29,6 +29,7 @@
android:layout_marginLeft="@dimen/margin_double"
android:layout_marginRight="@dimen/margin_double"
android:layout_marginBottom="@dimen/margin_base"
android:textSize="@dimen/text_size_toolbar"
android:textAppearance="@style/MwmTextAppearance.Title"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
@ -42,6 +43,7 @@
android:layout_marginLeft="@dimen/margin_double"
android:layout_marginRight="@dimen/margin_double"
android:layout_marginBottom="@dimen/margin_base"
android:textSize="@dimen/text_size_body_3"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
@ -49,7 +51,7 @@
</LinearLayout>
</com.mapswithme.maps.widget.HeightLimitedFrameLayout>
<include
android:id="@+id/btn_frame"
android:id="@+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/welcome_buttons_horizontal_container"/>
<include
android:id="@+id/user_agreement_block"
layout="@layout/user_agreement_block"
android:visibility="gone"
android:paddingBottom="@dimen/margin_base_plus"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>

View file

@ -0,0 +1,51 @@
<?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"
android:gravity="center"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base">
<LinearLayout
android:id="@+id/privacy_policy_checkbox_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<CheckBox
android:id="@+id/privacy_policy_welcome_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/privacy_policy_welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base_plus"
android:gravity="center_vertical"
android:text="@string/sign_agree_pp_gdpr"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
android:textColor="?android:textColorPrimary" />
</LinearLayout>
<LinearLayout
android:layout_below="@id/privacy_policy_checkbox_container"
android:id="@+id/term_of_use_checkbox_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<CheckBox
android:id="@+id/term_of_use_welcome_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/term_of_use_welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base_plus"
android:gravity="center_vertical"
android:text="@string/sign_agree_tof_gdpr"
android:textAppearance="@style/MwmTextAppearance.Body1.Secondary"
android:textColor="?android:textColorPrimary" />
</LinearLayout>
</RelativeLayout>

View file

@ -4,21 +4,17 @@ import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import android.text.Html;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.TextView;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
@ -32,6 +28,7 @@ import com.mapswithme.maps.Framework;
import com.mapswithme.maps.PrivateVariables;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmDialogFragment;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.statistics.Statistics;
@ -145,11 +142,11 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
R.id.google_button, R.id.facebook_button, R.id.phone_button);
});
linkifyPolicyView(view, R.id.privacyPolicyLink, R.string.sign_agree_pp_gdpr,
Framework.nativeGetPrivacyPolicyLink());
UiUtils.linkifyPolicyView(view, R.id.privacyPolicyLink, R.string.sign_agree_pp_gdpr,
Framework.nativeGetPrivacyPolicyLink());
linkifyPolicyView(view, R.id.termOfUseLink, R.string.sign_agree_tof_gdpr,
Framework.nativeGetTermsOfUseLink());
UiUtils.linkifyPolicyView(view, R.id.termOfUseLink, R.string.sign_agree_tof_gdpr,
Framework.nativeGetTermsOfUseLink());
setButtonAvailability(view, false, R.id.google_button, R.id.facebook_button,
R.id.phone_button);
@ -163,15 +160,6 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
button.setOnClickListener(clickListener);
}
private static void linkifyPolicyView(@NonNull View root, @IdRes int id, @StringRes int stringId,
@NonNull String link)
{
TextView policyView = root.findViewById(id);
Resources rs = policyView.getResources();
policyView.setText(Html.fromHtml(rs.getString(stringId, link)));
policyView.setMovementMethod(LinkMovementMethod.getInstance());
}
private static void setButtonAvailability(@NonNull View root, boolean available, @IdRes int... ids)
{
for (int id : ids)

View file

@ -51,7 +51,7 @@ public enum WelcomeScreenBindingType
R.string.visible,
R.string.view_campaign_button,
R.string.visible,
R.drawable.img_permission_explanation);
R.drawable.img_welcome);
@StringRes
private final int mAcceptButtonResId;

View file

@ -2,10 +2,13 @@ package com.mapswithme.maps.onboarding;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
@ -15,10 +18,13 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.mapswithme.maps.BuildConfig;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmDialogFragment;
import com.mapswithme.maps.news.WelcomeScreenBindingType;
import com.mapswithme.util.Counters;
import com.mapswithme.util.SharedPropertiesUtils;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
@ -52,6 +58,14 @@ public class WelcomeDialogFragment extends BaseMwmDialogFragment implements View
@NonNull
private TextView mAcceptBtn;
@SuppressWarnings("NullableProblems")
@NonNull
private CheckBox mTermOfUseCheckbox;
@SuppressWarnings("NullableProblems")
@NonNull
private CheckBox mPrivacyPolicyCheckbox;
public static void show(@NonNull FragmentActivity activity)
{
create(activity);
@ -63,6 +77,9 @@ public class WelcomeDialogFragment extends BaseMwmDialogFragment implements View
if (Counters.getFirstInstallVersion() < BuildConfig.VERSION_CODE)
return false;
if (isAgreementDenied(activity))
return true;
FragmentManager fm = activity.getSupportFragmentManager();
if (fm.isDestroyed())
return false;
@ -139,22 +156,80 @@ public class WelcomeDialogFragment extends BaseMwmDialogFragment implements View
mTitle.setText(R.string.onboarding_welcome_title);
mSubtitle = mContentView.findViewById(R.id.tv__subtitle1);
mSubtitle.setText(R.string.onboarding_welcome_first_subtitle);
mContentView.findViewById(R.id.privacy_policy_welcome);
initUserAgreementViews();
bindWelcomeScreenType();
return res;
}
private void initUserAgreementViews()
{
SharedPreferences prefs = MwmApplication.prefs(requireContext());
mTermOfUseCheckbox = mContentView.findViewById(R.id.term_of_use_welcome_checkbox);
mTermOfUseCheckbox.setChecked(prefs.getBoolean(SharedPropertiesUtils.USER_AGREEMENT_TERM_OF_USE, false));
mPrivacyPolicyCheckbox = mContentView.findViewById(R.id.privacy_policy_welcome_checkbox);
mPrivacyPolicyCheckbox.setChecked(prefs.getBoolean(SharedPropertiesUtils.USER_AGREEMENT_PRIVACY_POLICY, false));
mTermOfUseCheckbox.setOnCheckedChangeListener(
(buttonView, isChecked) -> onTermsOfUseViewChanged(isChecked));
mPrivacyPolicyCheckbox.setOnCheckedChangeListener(
(buttonView, isChecked) -> onPrivacyPolicyViewChanged(isChecked));
UiUtils.linkifyPolicyView(mContentView, R.id.privacy_policy_welcome,
R.string.sign_agree_pp_gdpr, Framework.nativeGetPrivacyPolicyLink());
UiUtils.linkifyPolicyView(mContentView, R.id.term_of_use_welcome,
R.string.sign_agree_tof_gdpr, Framework.nativeGetTermsOfUseLink());
}
private void onPrivacyPolicyViewChanged(boolean isChecked)
{
onCheckedValueChanged(isChecked, mTermOfUseCheckbox.isChecked(),
SharedPropertiesUtils.USER_AGREEMENT_PRIVACY_POLICY);
}
private void onTermsOfUseViewChanged(boolean isChecked)
{
onCheckedValueChanged(isChecked, mPrivacyPolicyCheckbox.isChecked(),
SharedPropertiesUtils.USER_AGREEMENT_TERM_OF_USE);
}
private void onCheckedValueChanged(boolean isChecked,
boolean isAnotherConditionChecked,
@NonNull String key)
{
applyPreferenceChanges(key, isChecked);
boolean isAgreementGranted = isChecked && isAnotherConditionChecked;
if (!isAgreementGranted)
return;
if (mListener != null)
mListener.onPolicyAgreementApplied();
dismiss();
}
private void bindWelcomeScreenType()
{
boolean hasDeclineBtn = mWelcomeScreenBindingType != null
boolean hasBindingType = mWelcomeScreenBindingType != null;
UiUtils.showIf(hasBindingType, mContentView, R.id.button_container);
boolean hasDeclineBtn = hasBindingType
&& mWelcomeScreenBindingType.hasDeclinedButton();
TextView declineBtn = mContentView.findViewById(R.id.decline_btn);
UiUtils.showIf(hasDeclineBtn, declineBtn);
View userAgreementBlock = mContentView.findViewById(R.id.user_agreement_block);
UiUtils.hideIf(hasBindingType, userAgreementBlock);
if (hasDeclineBtn)
declineBtn.setText(mWelcomeScreenBindingType.getDeclinedButtonResId());
if (mWelcomeScreenBindingType == null)
if (!hasBindingType)
return;
mTitle.setText(mWelcomeScreenBindingType.getTitle());
@ -188,6 +263,20 @@ public class WelcomeDialogFragment extends BaseMwmDialogFragment implements View
requireActivity().finish();
}
private void applyPreferenceChanges(@NonNull String key, boolean value)
{
SharedPreferences.Editor editor = MwmApplication.prefs(requireContext()).edit();
editor.putBoolean(key, value).apply();
}
private static boolean isAgreementDenied(@NonNull Context context)
{
SharedPreferences prefs = MwmApplication.prefs(context);
return !prefs.getBoolean(SharedPropertiesUtils.USER_AGREEMENT_TERM_OF_USE, false)
|| !prefs.getBoolean(SharedPropertiesUtils.USER_AGREEMENT_PRIVACY_POLICY, false);
}
public interface PolicyAgreementListener
{
void onPolicyAgreementApplied();

View file

@ -36,7 +36,7 @@ public class PermissionsDialogFragment extends BasePermissionsDialogFragment
@Override
protected int getImageRes()
{
return R.drawable.img_permission_explanation;
return R.drawable.img_welcome;
}
@StringRes

View file

@ -14,6 +14,8 @@ import static com.mapswithme.util.Config.KEY_PREF_STATISTICS;
public final class SharedPropertiesUtils
{
public static final String USER_AGREEMENT_TERM_OF_USE = "user_agreement_term_of_use";
public static final String USER_AGREEMENT_PRIVACY_POLICY = "user_agreement_privacy_policy";
private static final String PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING = "ShowEmulateBadStorageSetting";
private static final String PREFS_BACKUP_WIDGET_EXPANDED = "BackupWidgetExpanded";
private static final String PREFS_WHATS_NEW_TITLE_CONCATENATION = "WhatsNewTitleConcatenation";

View file

@ -11,7 +11,9 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.text.Html;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
@ -63,6 +65,15 @@ public final class UiUtils
frontView.bringToFront();
}
public static void linkifyPolicyView(@NonNull View root, @IdRes int id, @StringRes int stringId,
@NonNull String link)
{
TextView policyView = root.findViewById(id);
Resources rs = policyView.getResources();
policyView.setText(Html.fromHtml(rs.getString(stringId, link)));
policyView.setMovementMethod(LinkMovementMethod.getInstance());
}
public static class SimpleAnimationListener implements AnimationListener
{
@Override