Merge pull request #6541 from osmandapp/TrackerUiImprovements

Add privacy policy screen
This commit is contained in:
Alexey 2019-02-12 18:29:08 +03:00 committed by GitHub
commit 2eae199d44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 238 additions and 23 deletions

View file

@ -352,6 +352,125 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/privacy_policy_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/content_padding_standard"
android:visibility="gone"
tools:visibility="gone">
<TextView
android:id="@+id/privacy_policy_telegram_descr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginTop="@dimen/dialog_description_margin"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_marginBottom="@dimen/content_padding_standard"
android:letterSpacing="@dimen/text_description_letter_spacing"
android:lineSpacingMultiplier="@dimen/text_description_line_spacing_multiplier"
android:text="@string/privacy_policy_telegram_client"
android:textColor="@color/app_bar_title_light"
android:textSize="@dimen/descr_text_size" />
<TextView
android:id="@+id/privacy_policy_agree"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginTop="@dimen/dialog_description_margin"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_marginBottom="@dimen/content_padding_standard"
android:letterSpacing="@dimen/text_description_letter_spacing"
android:lineSpacingMultiplier="@dimen/text_description_line_spacing_multiplier"
android:text="@string/privacy_policy_agree"
android:textColor="@color/app_bar_title_light"
android:textSize="@dimen/descr_text_size"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/telegram_privacy_policy_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_half"
android:background="@drawable/btn_border_bg"
android:gravity="center_vertical"
android:visibility="visible">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/telegram_privacy_policy_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginTop="10dp"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:letterSpacing="@dimen/text_description_letter_spacing"
android:text="@string/do_not_have_telegram"
android:textColor="@color/text_bold_highlight"
android:textSize="@dimen/hint_text_size"
android:textStyle="bold" />
<ImageView
android:id="@+id/telegram_privacy_policy_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:contentDescription="@string/do_not_have_telegram"
android:scaleType="centerInside"
tools:src="@drawable/ic_arrow_forward"
tools:tint="@color/text_bold_highlight" />
</LinearLayout>
<LinearLayout
android:id="@+id/osmand_privacy_policy_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_half"
android:background="@drawable/btn_border_bg"
android:gravity="center_vertical"
android:visibility="visible">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/osmand_privacy_policy_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginTop="10dp"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:letterSpacing="@dimen/text_description_letter_spacing"
android:text="@string/do_not_have_telegram"
android:textColor="@color/text_bold_highlight"
android:textSize="@dimen/hint_text_size"
android:textStyle="bold" />
<ImageView
android:id="@+id/osmand_privacy_policy_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:contentDescription="@string/do_not_have_telegram"
android:scaleType="centerInside"
tools:src="@drawable/ic_arrow_forward"
tools:tint="@color/text_bold_highlight" />
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/progress_layout" android:id="@+id/progress_layout"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -1,5 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="privacy_policy_use_telegram">Мы используем Telegram (messaging app), чтобы соединять людей и чтобы вам было проще общаться с ними.</string>
<string name="privacy_policy_telegram_client">Telegram открытая платформа и OsmAnd Tracker является одним из клиентов. Ваши контакты могут использовать любой другой Telegram client.</string>
<string name="privacy_policy_agree">Нажимая продолжить, вы соглашаетесь с Telegram Privacy Policy и OsmAnd Privacy Policy.</string>
<string name="timeline_description">Включите мониторинг, для сбора данных о перемещении в фоновом режиме.</string> <string name="timeline_description">Включите мониторинг, для сбора данных о перемещении в фоновом режиме.</string>
<string name="last_update_from_telegram">Последнее обновление в Telegram</string> <string name="last_update_from_telegram">Последнее обновление в Telegram</string>
<string name="device_name">Имя устройства</string> <string name="device_name">Имя устройства</string>

View file

@ -41,4 +41,6 @@
<color name="sharing_status_icon_error">#ee5622</color> <color name="sharing_status_icon_error">#ee5622</color>
<color name="sharing_status_icon_success">#78cc5c</color> <color name="sharing_status_icon_success">#78cc5c</color>
<color name="text_bold_highlight">#5959FF</color>
</resources> </resources>

View file

@ -1,4 +1,12 @@
<resources> <resources>
<string name="shared_string_telegram">Telegram</string>
<string name="privacy_policy_use_telegram">We use a Telegram (messaging app) to connect people and make it easier for you to communicate with them.</string>
<string name="privacy_policy_telegram_client">Telegram open platform and OsmAnd Tracker is one of the customers. Your contacts can use any other Telegram client.</string>
<string name="privacy_policy_agree">By clicking continue you agree to the Telegram Privacy Policy and the OsmAnd Privacy Policy.</string>
<string name="shared_string_accept">Accept</string>
<string name="telegram_privacy_policy">Telegram Privacy Policy</string>
<string name="osmand_privacy_policy">OsmAnd Privacy Policy</string>
<string name="how_it_works">How it works</string>
<string name="received_gps_points">Received GPX points: %1$s</string> <string name="received_gps_points">Received GPX points: %1$s</string>
<string name="shared_string_appearance">Appearance</string> <string name="shared_string_appearance">Appearance</string>
<string name="show_gps_points">Show GPS points</string> <string name="show_gps_points">Show GPS points</string>

View file

@ -2,17 +2,18 @@ package net.osmand.telegram.ui
import android.app.Dialog import android.app.Dialog
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.graphics.Rect import android.graphics.Rect
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.support.annotation.StringRes import android.support.annotation.StringRes
import android.support.v4.app.FragmentManager import android.support.v4.app.FragmentManager
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
import android.support.v7.widget.AppCompatImageView import android.support.v7.widget.AppCompatImageView
import android.text.Editable import android.text.*
import android.text.Html import android.text.style.ForegroundColorSpan
import android.text.TextUtils import android.text.style.StyleSpan
import android.text.TextWatcher
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -39,7 +40,10 @@ class LoginDialogFragment : BaseDialogFragment() {
private const val LOGIN_DIALOG_TYPE_PARAM_KEY = "login_dialog_type_param" private const val LOGIN_DIALOG_TYPE_PARAM_KEY = "login_dialog_type_param"
private const val SHOW_PROGRESS_PARAM_KEY = "show_progress_param" private const val SHOW_PROGRESS_PARAM_KEY = "show_progress_param"
private const val SHOW_WELCOME_DIALOG_PARAM_KEY = "show_welcome_dialog_param" private const val SHOW_WELCOME_DIALOG_PARAM_KEY = "show_welcome_dialog_param"
private const val PRIVACY_POLICY_AGREED_PARAM_KEY = "privacy_policy_agreed_param"
private const val TELEGRAM_PACKAGE = "org.telegram.messenger" private const val TELEGRAM_PACKAGE = "org.telegram.messenger"
private const val TELEGRAM_PRIVACY_POLICY = "https://telegram.org/privacy"
private const val OSMAND_PRIVACY_POLICY = "https://osmand.net/help-online/privacy-policy"
private const val SOFT_KEYBOARD_MIN_DETECTION_SIZE = 0.15 private const val SOFT_KEYBOARD_MIN_DETECTION_SIZE = 0.15
var welcomeDialogShown = false var welcomeDialogShown = false
@ -52,7 +56,7 @@ class LoginDialogFragment : BaseDialogFragment() {
showDialog(fragmentManager, welcomeDialog = true) showDialog(fragmentManager, welcomeDialog = true)
} }
fun showDialog(fragmentManager: FragmentManager, loginDialogType: LoginDialogType? = null, welcomeDialog: Boolean = false) { fun showDialog(fragmentManager: FragmentManager, loginDialogType: LoginDialogType? = null, welcomeDialog: Boolean = false, privacyPolicyAgreed: Boolean = false) {
try { try {
/* /*
@ -70,6 +74,7 @@ class LoginDialogFragment : BaseDialogFragment() {
args.putString(LOGIN_DIALOG_TYPE_PARAM_KEY, loginDialogType.name) args.putString(LOGIN_DIALOG_TYPE_PARAM_KEY, loginDialogType.name)
} }
args.putBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, welcomeDialog) args.putBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, welcomeDialog)
args.putBoolean(PRIVACY_POLICY_AGREED_PARAM_KEY, privacyPolicyAgreed)
fragment.arguments = args fragment.arguments = args
fragment.show(fragmentManager, TAG) fragment.show(fragmentManager, TAG)
} else { } else {
@ -98,6 +103,7 @@ class LoginDialogFragment : BaseDialogFragment() {
private var loginDialogActiveType: LoginDialogType? = null private var loginDialogActiveType: LoginDialogType? = null
private var showWelcomeDialog = false private var showWelcomeDialog = false
private var privacyPolicyAgreed = false
private var showProgress = false private var showProgress = false
private var dismissedManually = false private var dismissedManually = false
private lateinit var continueButton: Button private lateinit var continueButton: Button
@ -112,7 +118,8 @@ class LoginDialogFragment : BaseDialogFragment() {
ENTER_PASSWORD(R.id.enter_password_layout, R.id.password_edit_text, ENTER_PASSWORD(R.id.enter_password_layout, R.id.password_edit_text,
R.string.enter_password, R.string.password_descr, R.string.enter_password), R.string.enter_password, R.string.password_descr, R.string.enter_password),
GET_TELEGRAM(R.id.get_telegram_layout, 0, GET_TELEGRAM(R.id.get_telegram_layout, 0,
R.string.get_telegram_title, R.string.get_telegram_account_first, 0); R.string.get_telegram_title, R.string.get_telegram_account_first, 0),
PRIVACY_POLICY(R.id.privacy_policy_layout, 0, R.string.how_it_works, R.string.privacy_policy_use_telegram, 0);
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -129,6 +136,7 @@ class LoginDialogFragment : BaseDialogFragment() {
} }
showProgress = args.getBoolean(SHOW_PROGRESS_PARAM_KEY, false) showProgress = args.getBoolean(SHOW_PROGRESS_PARAM_KEY, false)
showWelcomeDialog = args.getBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, false) showWelcomeDialog = args.getBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, false)
privacyPolicyAgreed = args.getBoolean(PRIVACY_POLICY_AGREED_PARAM_KEY, false)
} }
val view = inflater.inflate(R.layout.login_dialog, container) val view = inflater.inflate(R.layout.login_dialog, container)
continueButton = view.findViewById(R.id.continue_button) continueButton = view.findViewById(R.id.continue_button)
@ -151,12 +159,13 @@ class LoginDialogFragment : BaseDialogFragment() {
return view return view
} }
private fun transformContinueButton(expanded: Boolean) { private fun transformContinueButton(expanded: Boolean, acceptMode: Boolean = false) {
val params = continueButton.layoutParams as ViewGroup.MarginLayoutParams val params = continueButton.layoutParams as ViewGroup.MarginLayoutParams
val margin = if (expanded) 16f else 40f val bottomMargin = if (expanded || acceptMode) 16f else 40f
val width = if (expanded) ViewGroup.LayoutParams.MATCH_PARENT else ViewGroup.LayoutParams.WRAP_CONTENT val width = if (expanded) ViewGroup.LayoutParams.MATCH_PARENT else ViewGroup.LayoutParams.WRAP_CONTENT
params.apply { params.apply {
setMargins(leftMargin, topMargin, rightMargin, AndroidUtils.dpToPx(context!!, margin)) val horizontalMargin = app.resources.getDimensionPixelSize(if (acceptMode) R.dimen.dialog_welcome_padding_horizontal else R.dimen.content_padding_half)
setMargins(horizontalMargin, topMargin, horizontalMargin, AndroidUtils.dpToPx(context!!, bottomMargin))
this.width = width this.width = width
} }
continueButton.requestLayout() continueButton.requestLayout()
@ -197,7 +206,10 @@ class LoginDialogFragment : BaseDialogFragment() {
val continueButton = view?.findViewById<Button>(R.id.welcome_continue_button) val continueButton = view?.findViewById<Button>(R.id.welcome_continue_button)
continueButton?.setOnClickListener { continueButton?.setOnClickListener {
showWelcomeDialog = false showWelcomeDialog = false
if (loginDialogActiveType == null) { if (!privacyPolicyAgreed) {
loginDialogActiveType = LoginDialogType.PRIVACY_POLICY
showProgress = false
} else if (loginDialogActiveType == null) {
loginDialogActiveType = LoginDialogType.ENTER_PHONE_NUMBER loginDialogActiveType = LoginDialogType.ENTER_PHONE_NUMBER
showProgress = true showProgress = true
} }
@ -235,7 +247,10 @@ class LoginDialogFragment : BaseDialogFragment() {
layout.visibility = View.VISIBLE layout.visibility = View.VISIBLE
val editText: ExtendedEditText? = layout.findViewById(t.editorId) val editText: ExtendedEditText? = layout.findViewById(t.editorId)
if (editText != null && !showWelcomeDialog) { if (editText != null && !showWelcomeDialog) {
editText.setOnEditorActionListener { _, actionId, _ -> if (loginDialogActiveType == LoginDialogType.ENTER_PHONE_NUMBER) {
editText.setText("+")
}
editText.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) { if (actionId == EditorInfo.IME_ACTION_DONE) {
applyAuthParam(t, editText.text.toString()) applyAuthParam(t, editText.text.toString())
return@setOnEditorActionListener true return@setOnEditorActionListener true
@ -251,10 +266,10 @@ class LoginDialogFragment : BaseDialogFragment() {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(s: Editable) { override fun afterTextChanged(s: Editable) {
changeContinueButtonEnabled(!s.isEmpty()) changeContinueButtonEnabled(s.length > 1)
} }
}) })
changeContinueButtonEnabled(!editText.text.isEmpty()) changeContinueButtonEnabled(editText.text.length > 1)
editText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16F) editText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16F)
} }
@ -293,6 +308,67 @@ class LoginDialogFragment : BaseDialogFragment() {
getTelegramViewContainer?.visibility = View.GONE getTelegramViewContainer?.visibility = View.GONE
view.findViewById<Button>(R.id.continue_button).visibility = View.VISIBLE view.findViewById<Button>(R.id.continue_button).visibility = View.VISIBLE
} }
val privacyPolicyContainer: LinearLayout? = view.findViewById(R.id.privacy_policy_layout)
if (loginDialogActiveType == LoginDialogType.PRIVACY_POLICY) {
titleView?.setTextColor(ContextCompat.getColor(app, R.color.text_bold_highlight))
val useTelegramDescr = getString(R.string.privacy_policy_use_telegram)
descriptionView?.text = SpannableString(useTelegramDescr).apply {
val telegram = getString(R.string.shared_string_telegram)
val start = useTelegramDescr.indexOf(telegram)
if (start != -1) {
setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.text_bold_highlight)), start, start + telegram.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
setSpan(StyleSpan(android.graphics.Typeface.BOLD), start, start + telegram.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
view.findViewById<TextView>(R.id.privacy_policy_agree).apply {
val policyAgreeDescr = getString(R.string.privacy_policy_agree)
text = SpannableString(policyAgreeDescr).apply {
val telegramPrivacyPolicy = getString(R.string.telegram_privacy_policy)
val osmAndPrivacyPolicy = getString(R.string.osmand_privacy_policy)
var start = policyAgreeDescr.indexOf(telegramPrivacyPolicy)
if (start != -1) {
setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.text_bold_highlight)), start, start + telegramPrivacyPolicy.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
start = policyAgreeDescr.indexOf(osmAndPrivacyPolicy)
if (start != -1) {
setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.text_bold_highlight)), start, start + osmAndPrivacyPolicy.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
view.findViewById<LinearLayout>(R.id.telegram_privacy_policy_btn).apply {
findViewById<TextView>(R.id.telegram_privacy_policy_title).text = getText(R.string.telegram_privacy_policy)
findViewById<ImageView>(R.id.telegram_privacy_policy_icon)?.setImageDrawable(app.uiUtils.getIcon(R.drawable.ic_arrow_forward, R.color.text_bold_highlight))
setOnClickListener {
context?.also {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(TELEGRAM_PRIVACY_POLICY))
if (AndroidUtils.isIntentSafe(context, intent)) {
startActivity(intent)
}
}
}
}
view.findViewById<LinearLayout>(R.id.osmand_privacy_policy_btn).apply {
findViewById<TextView>(R.id.osmand_privacy_policy_title).text = getText(R.string.osmand_privacy_policy)
findViewById<ImageView>(R.id.osmand_privacy_policy_icon)?.setImageDrawable(app.uiUtils.getIcon(R.drawable.ic_arrow_forward, R.color.text_bold_highlight))
setOnClickListener {
context?.also {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(OSMAND_PRIVACY_POLICY))
if (AndroidUtils.isIntentSafe(context, intent)) {
startActivity(intent)
}
}
}
}
view.findViewById<Button>(R.id.continue_button).text = getText(R.string.shared_string_accept)
changeContinueButtonEnabled(true)
transformContinueButton(true, acceptMode = true)
privacyPolicyContainer?.visibility = View.VISIBLE
} else {
privacyPolicyContainer?.visibility = View.GONE
titleView?.setTextColor(ContextCompat.getColor(app, R.color.ctrl_active_light))
view.findViewById<Button>(R.id.continue_button).text = getText(R.string.shared_string_continue)
}
} }
} }
else -> layout?.visibility = View.GONE else -> layout?.visibility = View.GONE
@ -304,21 +380,27 @@ class LoginDialogFragment : BaseDialogFragment() {
progressView?.visibility = View.GONE progressView?.visibility = View.GONE
} }
} }
continueButton.isEnabled = !showProgress && continueButton.isEnabled continueButton.isEnabled = !showProgress && continueButton.isEnabled || loginDialogActiveType == LoginDialogType.PRIVACY_POLICY
if (showProgress) { if (showProgress) {
continueButton.setOnClickListener(null) continueButton.setOnClickListener(null)
} else { } else {
continueButton.setOnClickListener { continueButton.setOnClickListener {
showWelcomeDialog = false showWelcomeDialog = false
for (t in LoginDialogType.values()) { if (loginDialogActiveType == LoginDialogType.PRIVACY_POLICY) {
val layout: View? = view?.findViewById(t.viewId) this.loginDialogActiveType = LoginDialogType.ENTER_PHONE_NUMBER
val contains = t == loginDialogActiveType privacyPolicyAgreed = true
if (contains && layout != null) { buildDialog(view)
val editText: ExtendedEditText? = layout.findViewById(t.editorId) } else {
val text = editText?.text.toString() for (t in LoginDialogType.values()) {
if (!TextUtils.isEmpty(text) && text.length > 1) { val layout: View? = view?.findViewById(t.viewId)
continueButton.setTextColor(ContextCompat.getColor(context!!, R.color.secondary_text_light)) val contains = t == loginDialogActiveType
applyAuthParam(t, text) if (contains && layout != null) {
val editText: ExtendedEditText? = layout.findViewById(t.editorId)
val text = editText?.text.toString()
if (!TextUtils.isEmpty(text) && text.length > 1) {
continueButton.setTextColor(ContextCompat.getColor(context!!, R.color.secondary_text_light))
applyAuthParam(t, text)
}
} }
} }
} }
@ -360,6 +442,7 @@ class LoginDialogFragment : BaseDialogFragment() {
} }
outState.putBoolean(SHOW_PROGRESS_PARAM_KEY, showProgress) outState.putBoolean(SHOW_PROGRESS_PARAM_KEY, showProgress)
outState.putBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, showWelcomeDialog) outState.putBoolean(SHOW_WELCOME_DIALOG_PARAM_KEY, showWelcomeDialog)
outState.putBoolean(PRIVACY_POLICY_AGREED_PARAM_KEY, privacyPolicyAgreed)
} }
private fun getMainActivity(): MainActivity? { private fun getMainActivity(): MainActivity? {