From 551a7a00ac65cb102bde330f023505214e0560fd Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Thu, 24 Aug 2017 14:08:42 +0300 Subject: [PATCH 01/37] update Kotlin to 1.1.4-2 https://blog.jetbrains.com/kotlin/2017/08/kotlin-1-1-4-is-out/ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9cfaf6db85..62c4f53e3b 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply from: 'buildsystem/secret.gradle' buildscript { - ext.kotlin_version = '1.1.3' + ext.kotlin_version = '1.1.4-2' repositories { jcenter() maven { url 'https://maven.google.com' } From 4ec8a3813d8ae240e0409bf8d91421005dc1f497 Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Thu, 24 Aug 2017 14:29:08 +0300 Subject: [PATCH 02/37] extract params to projects build.gradle change teamcity_init.sh (tested in https://www.jdoodle.com/test-bash-shell-script-online) --- app/build.gradle | 4 ++-- build.gradle | 4 ++-- buildsystem/teamcity_init.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d778fd3d9f..215e977346 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ apply plugin: 'kotlin-android-extensions' def globalConf = rootProject.ext android { - compileSdkVersion 26 - buildToolsVersion "26.0.1" + compileSdkVersion rootProject.androidCompileSdkVersion + buildToolsVersion rootProject.androidBuildToolsVersion signingConfigs { debug { diff --git a/build.gradle b/build.gradle index 62c4f53e3b..ba34ac0917 100644 --- a/build.gradle +++ b/build.gradle @@ -26,10 +26,10 @@ allprojects { ext { //Android - androidBuildToolsVersion = "25.0.1" + androidBuildToolsVersion = "26.0.1" androidMinSdkVersion = 15 androidTargetSdkVersion = 25 - androidCompileSdkVersion = 25 + androidCompileSdkVersion = 26 } task clean(type: Delete) { diff --git a/buildsystem/teamcity_init.sh b/buildsystem/teamcity_init.sh index df75e55731..614caf3d8c 100755 --- a/buildsystem/teamcity_init.sh +++ b/buildsystem/teamcity_init.sh @@ -1,8 +1,8 @@ #!/bin/bash -SDK_VERSION=`grep compileSdkVersion app/build.gradle | awk '{ print $2 }'` +SDK_VERSION=`grep androidCompileSdkVersion build.gradle | awk '{ print $3 }'` SDK_DIR=$ANDROID_HOME/platforms/android-$SDK_VERSION -TOOLS_VERSION=`grep buildToolsVersion app/build.gradle | cut -d \" -f 2` +TOOLS_VERSION=`grep androidBuildToolsVersion build.gradle | cut -d \" -f 2` TOOLS_DIR=$ANDROID_HOME/build-tools/$TOOLS_VERSION if [ ! -d "$SDK_DIR" ]; then From 9e82beeecc6ba8294dc45df14210ce18f0cba387 Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Thu, 24 Aug 2017 17:56:31 +0300 Subject: [PATCH 03/37] add Notification channels to android O --- .../main/java/org/stepic/droid/base/App.kt | 6 ++- .../StepikNotificationManagerImpl.kt | 9 ++--- .../droid/notifications/model/Notification.kt | 21 ++++++---- .../model/StepikNotificationChannel.kt | 39 ++++++++++++++++++ .../util/NotificationChannelInitializer.kt | 40 +++++++++++++++++++ app/src/main/res/values-ru/strings.xml | 16 ++++++++ app/src/main/res/values/colors.xml | 3 ++ app/src/main/res/values/strings.xml | 17 ++++++++ 8 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/org/stepic/droid/notifications/model/StepikNotificationChannel.kt create mode 100644 app/src/main/java/org/stepic/droid/util/NotificationChannelInitializer.kt diff --git a/app/src/main/java/org/stepic/droid/base/App.kt b/app/src/main/java/org/stepic/droid/base/App.kt index 828d177008..af26ca428c 100644 --- a/app/src/main/java/org/stepic/droid/base/App.kt +++ b/app/src/main/java/org/stepic/droid/base/App.kt @@ -18,6 +18,7 @@ import org.stepic.droid.di.storage.DaggerStorageComponent import org.stepic.droid.fonts.FontType import org.stepic.droid.fonts.FontsProvider import org.stepic.droid.storage.InitialDownloadUpdater +import org.stepic.droid.util.NotificationChannelInitializer import timber.log.Timber import uk.co.chrisjenx.calligraphy.CalligraphyConfig import javax.inject.Inject @@ -96,9 +97,10 @@ class App : Application() { // init AppMetrica SDK YandexMetrica.activate(applicationContext, "fd479031-bdf4-419e-8d8f-6895aab23502") YandexMetrica.enableActivityAutoTracking(this) + initChannels() } - override fun attachBaseContext(base: Context) { - super.attachBaseContext(base) + private fun initChannels() { + NotificationChannelInitializer.initNotificationChannels(this) } } diff --git a/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt b/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt index 0e3b525bba..18ecf9aa2a 100644 --- a/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt +++ b/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt @@ -22,6 +22,7 @@ import org.stepic.droid.core.ScreenManager import org.stepic.droid.model.Course import org.stepic.droid.notifications.model.Notification import org.stepic.droid.notifications.model.NotificationType +import org.stepic.droid.notifications.model.StepikNotificationChannel import org.stepic.droid.preferences.SharedPreferenceHelper import org.stepic.droid.preferences.UserPreferences import org.stepic.droid.storage.operations.DatabaseFacade @@ -381,8 +382,6 @@ class StepikNotificationManagerImpl analytic.reportEventWithIdName(Analytic.Notification.NOTIFICATION_SHOWN, id.toString(), stepikNotification.type?.name) showSimpleNotification(stepikNotification, justText, taskBuilder, title, id = id) } else { - - val courseId: Long = HtmlHelper.parseCourseIdFromNotification(stepikNotification) ?: 0L if (courseId == 0L) { analytic.reportEvent(Analytic.Notification.CANT_PARSE_COURSE_ID, stepikNotification.id.toString()) @@ -423,7 +422,7 @@ class StepikNotificationManagerImpl val title = context.getString(R.string.app_name) val justText: String = textResolver.fromHtml(rawMessageHtml).toString() - val notification = NotificationCompat.Builder(context) + val notification = NotificationCompat.Builder(context, stepikNotification.type.channel.channelId) .setLargeIcon(largeIcon) .setSmallIcon(R.drawable.ic_notification_icon_1) // 1 is better .setContentTitle(title) @@ -463,7 +462,7 @@ class StepikNotificationManagerImpl addSoundIfNeed(notification) } - analytic.reportEventWithIdName(Analytic.Notification.NOTIFICATION_SHOWN, stepikNotification.id?.toString() ?: "", stepikNotification.type?.name) + analytic.reportEventWithIdName(Analytic.Notification.NOTIFICATION_SHOWN, stepikNotification.id?.toString() ?: "", stepikNotification.type.name) notificationManager.notify(courseId.toInt(), notification.build()) } } @@ -475,7 +474,7 @@ class StepikNotificationManagerImpl val pendingIntent = taskBuilder.getPendingIntent(id.toInt(), PendingIntent.FLAG_ONE_SHOT) //fixme if it will overlay courses id -> bug val colorArgb = ColorUtil.getColorArgb(R.color.stepic_brand_primary) - val notification = NotificationCompat.Builder(context) + val notification = NotificationCompat.Builder(context, stepikNotification?.type?.channel?.channelId ?: StepikNotificationChannel.user.channelId) .setSmallIcon(R.drawable.ic_notification_icon_1) .setContentTitle(title) .setContentText(justText) diff --git a/app/src/main/java/org/stepic/droid/notifications/model/Notification.kt b/app/src/main/java/org/stepic/droid/notifications/model/Notification.kt index 6ed1f2de40..db4996f208 100644 --- a/app/src/main/java/org/stepic/droid/notifications/model/Notification.kt +++ b/app/src/main/java/org/stepic/droid/notifications/model/Notification.kt @@ -11,24 +11,29 @@ data class Notification( @SerializedName("is_favorite") var isFavourite: Boolean? = null, var time: String? = null, - var type: NotificationType? = null, + var type: NotificationType = NotificationType.other, var level: String? = null, var priority: String? = null, @SerializedName("html_text") var htmlText: String? = null, var action: String? = null, - var course_id : Long? = null + var course_id: Long? = null ) -enum class NotificationType { +enum class NotificationType(val channel: StepikNotificationChannel) { + @SerializedName("comments") - comments, + comments(StepikNotificationChannel.comments), + @SerializedName("review") - review, + review(StepikNotificationChannel.review), + @SerializedName("teach") - teach, + teach(StepikNotificationChannel.teach), + @SerializedName("learn") - learn, + learn(StepikNotificationChannel.learn), + @SerializedName("default") - other + other(StepikNotificationChannel.other) } \ No newline at end of file diff --git a/app/src/main/java/org/stepic/droid/notifications/model/StepikNotificationChannel.kt b/app/src/main/java/org/stepic/droid/notifications/model/StepikNotificationChannel.kt new file mode 100644 index 0000000000..286bebcd49 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/notifications/model/StepikNotificationChannel.kt @@ -0,0 +1,39 @@ +package org.stepic.droid.notifications.model + +import android.app.NotificationManager +import android.os.Build +import android.support.annotation.StringRes +import org.stepic.droid.R + +private fun getImportanceCompat(): Int = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + NotificationManager.IMPORTANCE_HIGH + } else { + //it is -1 because channel should not be used for previous versions + -1 + } + +private val commentId = "commentChannel" +private val reviewId = "reviewChannel" +private val teachId = "teachChannel" +private val learnId = "learnChannel" +private val otherId = "otherChannel" +private val userId = "userChannel" + +enum class StepikNotificationChannel +( + val channelId: String, + @StringRes + val visibleChannelNameRes: Int, + @StringRes + val visibleChannelDescriptionRes: Int, + val importance: Int = getImportanceCompat()) { + //order is important! + + comments(commentId, R.string.comments_channel_name, R.string.comments_channel_description), + review(reviewId, R.string.review_channel_name, R.string.review_channel_description), + teach(teachId, R.string.teach_channel_name, R.string.teach_channel_description), + learn(learnId, R.string.learn_channel_name, R.string.learn_channel_description), + other(otherId, R.string.other_channel_name, R.string.other_channel_name), + user(userId, R.string.user_channel_name, R.string.user_channel_description) +} diff --git a/app/src/main/java/org/stepic/droid/util/NotificationChannelInitializer.kt b/app/src/main/java/org/stepic/droid/util/NotificationChannelInitializer.kt new file mode 100644 index 0000000000..8df4d0ad18 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/util/NotificationChannelInitializer.kt @@ -0,0 +1,40 @@ +package org.stepic.droid.util + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.os.Build +import android.support.annotation.RequiresApi +import org.stepic.droid.R +import org.stepic.droid.notifications.model.StepikNotificationChannel + +object NotificationChannelInitializer { + fun initNotificationChannels(context: Context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + //channels were introduced only in O. Before we had used in-app channels + return + } + + val stepikNotificationChannels = StepikNotificationChannel.values() + val androidChannels = ArrayList(stepikNotificationChannels.size) + stepikNotificationChannels.forEach { + androidChannels.add(initChannel(context, it)) + } + + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannels(androidChannels) + } + + + @RequiresApi(Build.VERSION_CODES.O) + private fun initChannel(context: Context, + stepikChannel: StepikNotificationChannel): NotificationChannel { + val channelName = context.getString(stepikChannel.visibleChannelNameRes) + val channel = NotificationChannel(stepikChannel.channelId, channelName, stepikChannel.importance) + channel.description = context.getString(stepikChannel.visibleChannelDescriptionRes) + channel.enableLights(true) + channel.enableVibration(true) + channel.lightColor = ColorUtil.getColorArgb(R.color.dots_color, context) + return channel + } +} diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1b6a61fafc..4f8f56535d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -476,4 +476,20 @@ Каталог + + + + Комментарии + Рецензии + Преподавание + Обучение + Прочее + Пользовательские уведомления + + Уведомления о получении ответов на ваши комментарии + Уведомления о получении рецензий на ваши решения + Уведомления о преподавательской деятельности на платформе + Уведомления о дедлайнах, открытии новых модулей в курсах + Уведомления о прочих действиях на платформе + Локальные уведомления пользователя \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7f2e0fff3e..6b327724ad 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -82,4 +82,7 @@ @color/new_accent_color_alpha_40 @color/white + + #F82401 + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 586444d7f0..8b7bf400c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -481,4 +481,21 @@ Catalog + + + + Comments + Reviews + Teaching + Learning + Other + User\'s Notifications + + Notifications about replying on your comments + Notifications about getting peer-review + Notifications about teaching activities at platform + Notifications about deadlines and opening new modules + Notifications about other actions at platform + Notifications which user set locally + From 69d9b4ddaf6297ba2b05b07d475d2f5d8c74b2ab Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Thu, 24 Aug 2017 19:03:27 +0300 Subject: [PATCH 04/37] remove app notification settings from SDK>=26. Extract to another activity notification settings for avoiding opening Settings on SDK>=26 from System Settings. This activity is just disabled on SDK>=26 --- app/src/main/AndroidManifest.xml | 7 ++ .../org/stepic/droid/analytic/Analytic.java | 1 + .../org/stepic/droid/core/ScreenManager.java | 2 + .../stepic/droid/core/ScreenManagerImpl.java | 21 +++++ .../NotificationSettingsActivity.kt | 16 ++++ .../droid/ui/activities/SettingsActivity.kt | 4 +- .../fragments/NotificationSettingsFragment.kt | 70 ++++++++++++++ .../ui/fragments/NotificationsFragment.java | 2 +- .../droid/ui/fragments/SettingsFragment.kt | 52 ++--------- .../layout/fragment_notification_settings.xml | 91 +++++++++++++++++++ app/src/main/res/layout/fragment_settings.xml | 68 +++----------- app/src/main/res/values-ru/strings.xml | 5 + .../values-v26/notification_activity_bool.xml | 4 + .../res/values/notification_activity_bool.xml | 4 + app/src/main/res/values/strings.xml | 5 + 15 files changed, 253 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/org/stepic/droid/ui/activities/NotificationSettingsActivity.kt create mode 100644 app/src/main/java/org/stepic/droid/ui/fragments/NotificationSettingsFragment.kt create mode 100644 app/src/main/res/layout/fragment_notification_settings.xml create mode 100644 app/src/main/res/values-v26/notification_activity_bool.xml create mode 100644 app/src/main/res/values/notification_activity_bool.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4725478f7c..b53c3a38d8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -285,13 +285,20 @@ + + + + = Build.VERSION_CODES.O) { + //show system settings + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, sourceActivity.getPackageName()); + sourceActivity.startActivity(intent); + } else { + //show app notification settings + //(SDK < 26) + Intent intent = new Intent(sourceActivity, NotificationSettingsActivity.class); + sourceActivity.startActivity(intent); + sourceActivity.overridePendingTransition(org.stepic.droid.R.anim.push_up, org.stepic.droid.R.anim.no_transition); + } + } + @Override public void showStorageManagement(Activity activity) { analytic.reportEvent(Analytic.Screens.SHOW_STORAGE_MANAGEMENT); diff --git a/app/src/main/java/org/stepic/droid/ui/activities/NotificationSettingsActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/NotificationSettingsActivity.kt new file mode 100644 index 0000000000..908b5d0cfe --- /dev/null +++ b/app/src/main/java/org/stepic/droid/ui/activities/NotificationSettingsActivity.kt @@ -0,0 +1,16 @@ +package org.stepic.droid.ui.activities + +import android.support.v4.app.Fragment +import org.stepic.droid.R +import org.stepic.droid.ui.fragments.NotificationSettingsFragment +import org.stepic.droid.ui.util.initCenteredToolbar + +class NotificationSettingsActivity : SettingsActivity() { + override fun createFragment(): Fragment = NotificationSettingsFragment.newInstance() + + override fun setUpToolbar() { + initCenteredToolbar(R.string.notification_settings_title, + true, + closeIconDrawableRes) + } +} diff --git a/app/src/main/java/org/stepic/droid/ui/activities/SettingsActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/SettingsActivity.kt index a56aabf162..680172fcaa 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/SettingsActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/SettingsActivity.kt @@ -12,9 +12,7 @@ open class SettingsActivity : SingleFragmentActivity() { override fun createFragment(): Fragment = SettingsFragment.newInstance() - override fun getLayoutResId(): Int { - return R.layout.activity_container_with_bar - } + override fun getLayoutResId(): Int = R.layout.activity_container_with_bar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationSettingsFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationSettingsFragment.kt new file mode 100644 index 0000000000..d0f62d3466 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationSettingsFragment.kt @@ -0,0 +1,70 @@ +package org.stepic.droid.ui.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import kotlinx.android.synthetic.main.fragment_notification_settings.* +import org.stepic.droid.R +import org.stepic.droid.base.FragmentBase +import org.stepic.droid.notifications.model.NotificationType + +class NotificationSettingsFragment : FragmentBase() { + companion object { + fun newInstance(): NotificationSettingsFragment = NotificationSettingsFragment() + } + + override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? + = inflater?.inflate(R.layout.fragment_notification_settings, container, false) + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + nullifyActivityBackground() + setUpNotificationVibration() + setUpNotifications() + setUpSound() + + } + + override fun onDestroyView() { + super.onDestroyView() + fragmentSettingsNotificationLearnSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationCommentSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationTeachingSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationOtherSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationReviewSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationVibrationSwitch.setOnCheckedChangeListener(null) + fragmentSettingsNotificationSoundSwitch.setOnCheckedChangeListener(null) + } + + + private fun setUpNotificationVibration() { + fragmentSettingsNotificationVibrationSwitch.isChecked = userPreferences.isVibrateNotificationEnabled + fragmentSettingsNotificationVibrationSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.isVibrateNotificationEnabled = isChecked } + } + + private fun setUpSound() { + fragmentSettingsNotificationSoundSwitch.isChecked = userPreferences.isSoundNotificationEnabled + fragmentSettingsNotificationSoundSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationSoundEnabled(isChecked) } + } + + private fun setUpNotifications() { + fragmentSettingsNotificationLearnSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.learn) + fragmentSettingsNotificationLearnSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.learn, isChecked) } + + fragmentSettingsNotificationCommentSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.comments) + fragmentSettingsNotificationCommentSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.comments, isChecked) } + + fragmentSettingsNotificationReviewSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.review) + fragmentSettingsNotificationReviewSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.review, isChecked) } + + fragmentSettingsNotificationTeachingSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.teach) + fragmentSettingsNotificationTeachingSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.teach, isChecked) } + + fragmentSettingsNotificationOtherSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.other) + fragmentSettingsNotificationOtherSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.other, isChecked) } + + } + + +} diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java index 038f174341..06e78736b6 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java @@ -110,7 +110,7 @@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_settings: getAnalytic().reportEvent(Analytic.Interaction.CLICK_SETTINGS_FROM_NOTIFICATION); - getScreenManager().showSettings(getActivity()); + getScreenManager().showNotificationSettings(getActivity()); return true; case android.R.id.home: // Respond to the action bar's Up/Home button diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt index d53eca1de6..0dd41d633c 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt @@ -1,5 +1,6 @@ package org.stepic.droid.ui.fragments +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -7,7 +8,6 @@ import android.view.ViewGroup import kotlinx.android.synthetic.main.fragment_settings.* import org.stepic.droid.R import org.stepic.droid.base.FragmentBase -import org.stepic.droid.notifications.model.NotificationType import org.stepic.droid.ui.dialogs.AllowMobileDataDialogFragment import org.stepic.droid.ui.dialogs.VideoQualityDialog @@ -32,11 +32,14 @@ class SettingsFragment : FragmentBase(), AllowMobileDataDialogFragment.Callback nullifyActivityBackground() - setUpNotificationVibration() - - setUpNotifications() - - setUpSound() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notificationContainer.visibility = View.GONE + } else { + notificationContainer.visibility = View.VISIBLE + notificationActionButton.setOnClickListener { + screenManager.showNotificationSettings(activity) + } + } fragmentSettingsWifiEnableSwitch.isChecked = !sharedPreferenceHelper.isMobileInternetAlsoAllowed//if first time it is true @@ -90,17 +93,6 @@ class SettingsFragment : FragmentBase(), AllowMobileDataDialogFragment.Callback } storageManagementButton.setOnClickListener { screenManager.showStorageManagement(activity) } - - } - - private fun setUpNotificationVibration() { - fragmentSettingsSotificationVibrationSwitch.isChecked = userPreferences.isVibrateNotificationEnabled - fragmentSettingsSotificationVibrationSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.isVibrateNotificationEnabled = isChecked } - } - - private fun setUpSound() { - fragmentSettingsNotificationSoundSwitch.isChecked = userPreferences.isSoundNotificationEnabled - fragmentSettingsNotificationSoundSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationSoundEnabled(isChecked) } } override fun onDestroyView() { @@ -109,14 +101,8 @@ class SettingsFragment : FragmentBase(), AllowMobileDataDialogFragment.Callback fragmentSettingsCalendarWidgetSwitch.setOnCheckedChangeListener(null) fragmentSettingsWifiEnableSwitch.setOnCheckedChangeListener(null) fragmentSettingsExternalPlayerSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationLearnSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationCommentSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationTeachingSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationOtherSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationReviewSwitch.setOnCheckedChangeListener(null) - fragmentSettingsSotificationVibrationSwitch.setOnCheckedChangeListener(null) - fragmentSettingsNotificationSoundSwitch.setOnCheckedChangeListener(null) storageManagementButton.setOnClickListener(null) + notificationActionButton.setOnClickListener(null) super.onDestroyView() } @@ -124,24 +110,6 @@ class SettingsFragment : FragmentBase(), AllowMobileDataDialogFragment.Callback sharedPreferenceHelper.setMobileInternetAndWifiAllowed(isMobileAllowed) } - private fun setUpNotifications() { - fragmentSettingsNotificationLearnSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.learn) - fragmentSettingsNotificationLearnSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.learn, isChecked) } - - fragmentSettingsNotificationCommentSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.comments) - fragmentSettingsNotificationCommentSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.comments, isChecked) } - - fragmentSettingsNotificationReviewSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.review) - fragmentSettingsNotificationReviewSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.review, isChecked) } - - fragmentSettingsNotificationTeachingSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.teach) - fragmentSettingsNotificationTeachingSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.teach, isChecked) } - - fragmentSettingsNotificationOtherSwitch.isChecked = userPreferences.isNotificationEnabled(NotificationType.other) - fragmentSettingsNotificationOtherSwitch.setOnCheckedChangeListener { _, isChecked -> userPreferences.setNotificationEnabled(NotificationType.other, isChecked) } - - } - override fun onMobileDataStateChanged(isMobileAllowed: Boolean) { fragmentSettingsWifiEnableSwitch.isChecked = !isMobileAllowed storeMobileState(isMobileAllowed) diff --git a/app/src/main/res/layout/fragment_notification_settings.xml b/app/src/main/res/layout/fragment_notification_settings.xml new file mode 100644 index 0000000000..1b88d1fc15 --- /dev/null +++ b/app/src/main/res/layout/fragment_notification_settings.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 3100aaf37f..1b0d6d87cc 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -2,6 +2,7 @@ + android:visibility="gone" + app:cardBackgroundColor="@color/white" + tools:visibility="visible"> - - - - - - - - - - - + android:clickable="true" + android:focusable="true"> + + - diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4f8f56535d..e5b2183f0a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -492,4 +492,9 @@ Уведомления о дедлайнах, открытии новых модулей в курсах Уведомления о прочих действиях на платформе Локальные уведомления пользователя + + + Настройки уведомлений + + Управлять уведомлениями \ No newline at end of file diff --git a/app/src/main/res/values-v26/notification_activity_bool.xml b/app/src/main/res/values-v26/notification_activity_bool.xml new file mode 100644 index 0000000000..edd8a3905a --- /dev/null +++ b/app/src/main/res/values-v26/notification_activity_bool.xml @@ -0,0 +1,4 @@ + + + false + \ No newline at end of file diff --git a/app/src/main/res/values/notification_activity_bool.xml b/app/src/main/res/values/notification_activity_bool.xml new file mode 100644 index 0000000000..a4ccd81b2a --- /dev/null +++ b/app/src/main/res/values/notification_activity_bool.xml @@ -0,0 +1,4 @@ + + + true + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8b7bf400c1..455f172673 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -498,4 +498,9 @@ Notifications about other actions at platform Notifications which user set locally + + Notification Settings + + Manage notifications + From 3aa373c0a8eebdf5f771feef5bc53e902813ff28 Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Sat, 26 Aug 2017 18:44:35 +0300 Subject: [PATCH 05/37] show "Manage notifications" for all users. API>=26: open system notification settings, API<26: open stepik activity fix not needed null check in notification manager --- .../notifications/StepikNotificationManagerImpl.kt | 2 +- .../org/stepic/droid/ui/fragments/SettingsFragment.kt | 10 ++-------- app/src/main/res/layout/fragment_settings.xml | 4 +--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt b/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt index 18ecf9aa2a..1bf6f74e40 100644 --- a/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt +++ b/app/src/main/java/org/stepic/droid/notifications/StepikNotificationManagerImpl.kt @@ -379,7 +379,7 @@ class StepikNotificationManagerImpl val taskBuilder: TaskStackBuilder = TaskStackBuilder.create(context) taskBuilder.addNextIntent(intent) - analytic.reportEventWithIdName(Analytic.Notification.NOTIFICATION_SHOWN, id.toString(), stepikNotification.type?.name) + analytic.reportEventWithIdName(Analytic.Notification.NOTIFICATION_SHOWN, id.toString(), stepikNotification.type.name) showSimpleNotification(stepikNotification, justText, taskBuilder, title, id = id) } else { val courseId: Long = HtmlHelper.parseCourseIdFromNotification(stepikNotification) ?: 0L diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt index 0dd41d633c..5a0e0e09ce 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/SettingsFragment.kt @@ -1,6 +1,5 @@ package org.stepic.droid.ui.fragments -import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -32,13 +31,8 @@ class SettingsFragment : FragmentBase(), AllowMobileDataDialogFragment.Callback nullifyActivityBackground() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - notificationContainer.visibility = View.GONE - } else { - notificationContainer.visibility = View.VISIBLE - notificationActionButton.setOnClickListener { - screenManager.showNotificationSettings(activity) - } + notificationActionButton.setOnClickListener { + screenManager.showNotificationSettings(activity) } fragmentSettingsWifiEnableSwitch.isChecked = !sharedPreferenceHelper.isMobileInternetAlsoAllowed//if first time it is true diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 1b0d6d87cc..d41b8f1219 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -88,9 +88,7 @@ style="@style/SettingCardStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:visibility="gone" - app:cardBackgroundColor="@color/white" - tools:visibility="visible"> + app:cardBackgroundColor="@color/white"> Date: Mon, 28 Aug 2017 15:37:38 +0300 Subject: [PATCH 06/37] prefill email on social_auth_with_existing_email for social providers with SDK --- .../ui/activities/LaunchActivity.kt | 6 +++++- .../java/org/stepic/droid/core/ScreenManager.java | 2 +- .../org/stepic/droid/core/ScreenManagerImpl.java | 5 ++++- .../stepic/droid/core/presenters/LoginPresenter.kt | 13 +++++++++++++ .../droid/core/presenters/contracts/LoginView.kt | 2 ++ .../org/stepic/droid/ui/activities/LoginActivity.kt | 10 +++++++++- .../stepic/droid/ui/activities/RegisterActivity.kt | 2 ++ .../java/org/stepic/droid/util/AppConstants.java | 1 + .../java/org/stepic/droid/web/SocialAuthError.kt | 7 +++++++ 9 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/stepic/droid/web/SocialAuthError.kt diff --git a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt index 2bcf81b708..a56840c36e 100644 --- a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt +++ b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt @@ -90,7 +90,7 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { signInWithEmail.setOnClickListener { analytic.reportEvent(Analytic.Interaction.CLICK_SIGN_IN) - screenManager.showLogin(this@LaunchActivity, courseFromExtra) + screenManager.showLogin(this@LaunchActivity, courseFromExtra, null) } @@ -371,6 +371,10 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { openMainFeed() } + override fun onSocialLoginWithExistingEmail(email: String) { + screenManager.showLogin(this, courseFromExtra, email) + } + private fun openMainFeed() { screenManager.showMainFeed(this, courseFromExtra) } diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManager.java b/app/src/main/java/org/stepic/droid/core/ScreenManager.java index aa908121ef..ea46544262 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManager.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManager.java @@ -32,7 +32,7 @@ public interface ScreenManager { void showRegistration(Activity sourceActivity, @Nullable Course course); - void showLogin(Activity sourceActivity, @Nullable Course course); + void showLogin(Activity sourceActivity, @Nullable Course course, @Nullable String email); void showMainFeed(Context sourceActivity, @Nullable Course course); diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java index 4f7ea0ae80..7094b91746 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java @@ -157,12 +157,15 @@ public void showRegistration(Activity sourceActivity, @Nullable Course course) { } @Override - public void showLogin(Activity sourceActivity, @Nullable Course course) { + public void showLogin(Activity sourceActivity, @Nullable Course course, @Nullable String email) { analytic.reportEvent(Analytic.Screens.SHOW_LOGIN); Intent loginIntent = new Intent(sourceActivity, LoginActivity.class); if (course != null) { loginIntent.putExtra(AppConstants.KEY_COURSE_BUNDLE, (Parcelable) course); } + if (email != null) { + loginIntent.putExtra(AppConstants.KEY_EMAIL_BUNDLE, email); + } sourceActivity.startActivity(loginIntent); } diff --git a/app/src/main/java/org/stepic/droid/core/presenters/LoginPresenter.kt b/app/src/main/java/org/stepic/droid/core/presenters/LoginPresenter.kt index e0d79ebe96..a71dafe32d 100644 --- a/app/src/main/java/org/stepic/droid/core/presenters/LoginPresenter.kt +++ b/app/src/main/java/org/stepic/droid/core/presenters/LoginPresenter.kt @@ -2,6 +2,7 @@ package org.stepic.droid.core.presenters import android.support.annotation.MainThread import com.google.android.gms.auth.api.credentials.Credential +import com.google.gson.Gson import org.stepic.droid.analytic.Analytic import org.stepic.droid.concurrency.MainHandler import org.stepic.droid.core.LoginFailType @@ -12,6 +13,7 @@ import org.stepic.droid.preferences.SharedPreferenceHelper import org.stepic.droid.social.SocialManager import org.stepic.droid.web.Api import org.stepic.droid.web.AuthenticationStepicResponse +import org.stepic.droid.web.SocialAuthError import retrofit2.Call import java.util.concurrent.ThreadPoolExecutor import javax.inject.Inject @@ -70,6 +72,17 @@ class LoginPresenter } else if (response.code() == 429) { onFail(LoginFailType.tooManyAttempts) } else if (response.code() == 401 && type == Type.social) { + val errorBody = response.errorBody().string() + + Gson().fromJson(errorBody, SocialAuthError::class.java).let { + val email = it.email + if (email != null) { + mainHandler.post { + view?.onSocialLoginWithExistingEmail(email) + } + } + } + onFail(LoginFailType.emailAlreadyUsed) } else { onFail(LoginFailType.emailPasswordInvalid) diff --git a/app/src/main/java/org/stepic/droid/core/presenters/contracts/LoginView.kt b/app/src/main/java/org/stepic/droid/core/presenters/contracts/LoginView.kt index 05e8d28dfc..4e2441cffa 100644 --- a/app/src/main/java/org/stepic/droid/core/presenters/contracts/LoginView.kt +++ b/app/src/main/java/org/stepic/droid/core/presenters/contracts/LoginView.kt @@ -10,5 +10,7 @@ interface LoginView { fun onFailLogin(type: LoginFailType, credential: Credential?) + fun onSocialLoginWithExistingEmail(email: String) + fun onSuccessLogin(authData : AuthData?) } diff --git a/app/src/main/java/org/stepic/droid/ui/activities/LoginActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/LoginActivity.kt index 6836127b71..b54cba9e59 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/LoginActivity.kt @@ -25,6 +25,7 @@ import org.stepic.droid.core.presenters.LoginPresenter import org.stepic.droid.core.presenters.contracts.LoginView import org.stepic.droid.model.AuthData import org.stepic.droid.ui.dialogs.LoadingProgressDialog +import org.stepic.droid.util.AppConstants import org.stepic.droid.util.ProgressHelper import org.stepic.droid.util.getMessageFor import org.stepic.droid.util.toBundle @@ -139,6 +140,11 @@ class LoginActivity : FragmentActivityBase(), LoginView { loginPresenter.attachView(this) onNewIntent(intent) + + if (savedInstanceState == null && intent.hasExtra(AppConstants.KEY_EMAIL_BUNDLE)) { + loginText.setText(intent.getStringExtra(AppConstants.KEY_EMAIL_BUNDLE)) + passwordEditText.requestFocus() + } } override fun onNewIntent(intent: Intent?) { @@ -222,7 +228,7 @@ class LoginActivity : FragmentActivityBase(), LoginView { } else { analytic.reportEvent(Analytic.SmartLock.LOGIN_NOT_SAVED) } - openMainFeed(); + openMainFeed() } } @@ -235,4 +241,6 @@ class LoginActivity : FragmentActivityBase(), LoginView { progressHandler.activate() } + override fun onSocialLoginWithExistingEmail(email: String) {} + } diff --git a/app/src/main/java/org/stepic/droid/ui/activities/RegisterActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/RegisterActivity.kt index 99a6f9fb59..8e7b65ed78 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/RegisterActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/RegisterActivity.kt @@ -321,4 +321,6 @@ class RegisterActivity : FragmentActivityBase(), LoginView { ProgressHelper.activate(progressBar) } + override fun onSocialLoginWithExistingEmail(email: String) {} + } diff --git a/app/src/main/java/org/stepic/droid/util/AppConstants.java b/app/src/main/java/org/stepic/droid/util/AppConstants.java index a02d2a50d3..bc08bdcd51 100644 --- a/app/src/main/java/org/stepic/droid/util/AppConstants.java +++ b/app/src/main/java/org/stepic/droid/util/AppConstants.java @@ -10,6 +10,7 @@ public class AppConstants { public static final String SVG_EXTENSION = ".svg"; public static final String USER_LOG_IN = "user_login_clicked"; + public static final String KEY_EMAIL_BUNDLE = "email"; public static final String KEY_COURSE_BUNDLE = "course"; public static final String KEY_COURSE_LONG_ID = "course_id_key"; public static final String KEY_SECTION_BUNDLE = "section"; diff --git a/app/src/main/java/org/stepic/droid/web/SocialAuthError.kt b/app/src/main/java/org/stepic/droid/web/SocialAuthError.kt new file mode 100644 index 0000000000..128d39af64 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/web/SocialAuthError.kt @@ -0,0 +1,7 @@ +package org.stepic.droid.web + +data class SocialAuthError( + var error: String?, + var email: String?, + var provider: String? +) \ No newline at end of file From f318386e569916edbe72ceb384041d01a1c597b4 Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Mon, 28 Aug 2017 16:08:21 +0300 Subject: [PATCH 07/37] disable mShiftingMode for Bottom navigation view via reflection (!follow the future updates of support library, may be google will change this behaviour and we will drop reflection). Proguard already have this change --- .../droid/ui/activities/MainFeedActivity.kt | 2 ++ .../droid/ui/util/BottomNavigationUtil.java | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 app/src/main/java/org/stepic/droid/ui/util/BottomNavigationUtil.java diff --git a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt index 2aef580b45..3986495060 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt @@ -40,6 +40,7 @@ import org.stepic.droid.ui.fragments.FindCoursesFragment import org.stepic.droid.ui.fragments.MyCoursesFragment import org.stepic.droid.ui.fragments.ProfileFragment import org.stepic.droid.ui.util.BottomNavigationBehavior +import org.stepic.droid.ui.util.BottomNavigationUtil import org.stepic.droid.util.AppConstants import org.stepic.droid.util.DateTimeHelper import org.stepic.droid.util.ProgressHelper @@ -186,6 +187,7 @@ class MainFeedActivity : BackToExitActivityBase(), private fun initNavigation() { + BottomNavigationUtil.disableMenuShiftMode(navigationView) navigationView.setOnNavigationItemSelectedListener(this) navigationView.setOnNavigationItemReselectedListener(this) } diff --git a/app/src/main/java/org/stepic/droid/ui/util/BottomNavigationUtil.java b/app/src/main/java/org/stepic/droid/ui/util/BottomNavigationUtil.java new file mode 100644 index 0000000000..da6668e2b2 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/ui/util/BottomNavigationUtil.java @@ -0,0 +1,32 @@ +package org.stepic.droid.ui.util; + +import android.support.design.internal.BottomNavigationItemView; +import android.support.design.internal.BottomNavigationMenuView; +import android.support.design.widget.BottomNavigationView; +import android.util.Log; + +import java.lang.reflect.Field; + +public class BottomNavigationUtil { + public static void disableMenuShiftMode(BottomNavigationView view) { + BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); + try { + Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); + shiftingMode.setAccessible(true); + shiftingMode.setBoolean(menuView, false); + shiftingMode.setAccessible(false); + for (int i = 0; i < menuView.getChildCount(); i++) { + BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); + //noinspection RestrictedApi + item.setShiftingMode(false); + // set once again checked value, so view will be updated + //noinspection RestrictedApi + item.setChecked(item.getItemData().isChecked()); + } + } catch (NoSuchFieldException e) { + Log.e("BNVHelper", "Unable to get shift mode field", e); + } catch (IllegalAccessException e) { + Log.e("BNVHelper", "Unable to change value of shift mode", e); + } + } +} From e8b49cd9df522dd3646dc8a4970ddda783717f04 Mon Sep 17 00:00:00 2001 From: Ruslan Davletshin Date: Mon, 28 Aug 2017 16:40:30 +0300 Subject: [PATCH 08/37] auth with webView for social providers without sdk and prefill email for existing emails --- .../ui/activities/LaunchActivity.kt | 14 ++++ app/src/main/AndroidManifest.xml | 4 ++ .../droid/core/presenters/LoginPresenter.kt | 3 +- .../droid/ui/activities/SocialAuthActivity.kt | 70 +++++++++++++++++++ .../org/stepic/droid/util/AppConstants.java | 4 ++ .../java/org/stepic/droid/web/ApiImpl.java | 6 +- .../main/res/layout/activity_social_auth.xml | 18 +++++ 7 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt create mode 100644 app/src/main/res/layout/activity_social_auth.xml diff --git a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt index a56840c36e..dae2123035 100644 --- a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt +++ b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt @@ -52,6 +52,8 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { private val TAG = "LaunchActivity" val wasLogoutKey = "wasLogoutKey" private val resolvingAccountKey = "resolvingAccountKey" + + const val REQUEST_CODE_SOCIAL_AUTH = 377 } private val requestFromSmartLockCode = 314 @@ -315,6 +317,18 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { onInternetProblems() } } + + if (requestCode == REQUEST_CODE_SOCIAL_AUTH && data != null) { + if (resultCode == Activity.RESULT_OK) { + redirectFromSocial(data) + } else if (resultCode == Activity.RESULT_CANCELED) { + val email = data.data?.getQueryParameter(AppConstants.KEY_EMAIL_BUNDLE) + if (email != null) { + onFailLogin(LoginFailType.emailAlreadyUsed, null) + onSocialLoginWithExistingEmail(email) + } + } + } } private fun onInternetProblems() { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b53c3a38d8..40dbeb8dcb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -84,6 +84,10 @@ android:launchMode="singleTop" android:theme="@style/StepikTheme.LoginLaunchRegistration"/> + + (R.id.actionbarCloseButtonLayout).setOnClickListener { finish() } + } + + override fun finish() { + super.finish() + overridePendingTransition(R.anim.no_transition, R.anim.slide_out_to_bottom) + } + + override fun onSaveInstanceState(outState: Bundle?) { + authWebView.saveState(outState) + } + + override fun onBackPressed() { + if (authWebView.canGoBack()) { + authWebView.goBack() + } else { + super.onBackPressed() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/stepic/droid/util/AppConstants.java b/app/src/main/java/org/stepic/droid/util/AppConstants.java index bc08bdcd51..fcbaa0e375 100644 --- a/app/src/main/java/org/stepic/droid/util/AppConstants.java +++ b/app/src/main/java/org/stepic/droid/util/AppConstants.java @@ -9,6 +9,10 @@ public class AppConstants { public static final String FILE_SCHEME_PREFIX = "file://"; public static final String SVG_EXTENSION = ".svg"; + public static final String APP_SCHEME = "stepic://"; + public static final String QUERY_ERROR = "error"; + public static final String ERROR_SOCIAL_AUTH_WITH_EXISTING_EMAIL = "social_signup_with_existing_email"; + public static final String USER_LOG_IN = "user_login_clicked"; public static final String KEY_EMAIL_BUNDLE = "email"; public static final String KEY_COURSE_BUNDLE = "course"; diff --git a/app/src/main/java/org/stepic/droid/web/ApiImpl.java b/app/src/main/java/org/stepic/droid/web/ApiImpl.java index 23f25989a5..c1f0dd918e 100644 --- a/app/src/main/java/org/stepic/droid/web/ApiImpl.java +++ b/app/src/main/java/org/stepic/droid/web/ApiImpl.java @@ -47,6 +47,8 @@ import org.stepic.droid.serializers.ReplySerializer; import org.stepic.droid.social.ISocialType; import org.stepic.droid.social.SocialManager; +import org.stepic.droid.ui.activities.LaunchActivity; +import org.stepic.droid.ui.activities.SocialAuthActivity; import org.stepic.droid.util.AppConstants; import org.stepic.droid.util.DeviceInfoUtil; import org.stepic.droid.util.RWLocks; @@ -475,8 +477,8 @@ public void loginWithSocial(final FragmentActivity activity, ISocialType type) { String socialIdentifier = type.getIdentifier(); String url = config.getBaseUrl() + "/accounts/" + socialIdentifier + "/login?next=/oauth2/authorize/?" + Uri.encode("client_id=" + config.getOAuthClientId(TokenType.social) + "&response_type=code"); Uri uri = Uri.parse(url); - final Intent intent = new Intent(Intent.ACTION_VIEW).setData(uri); - activity.startActivity(intent); + final Intent intent = new Intent(activity, SocialAuthActivity.class).setData(uri); + activity.startActivityForResult(intent, LaunchActivity.REQUEST_CODE_SOCIAL_AUTH); } @Override diff --git a/app/src/main/res/layout/activity_social_auth.xml b/app/src/main/res/layout/activity_social_auth.xml new file mode 100644 index 0000000000..c49fe76e48 --- /dev/null +++ b/app/src/main/res/layout/activity_social_auth.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file From 08027c15d426d83a1f62685039aadf75c673607f Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Mon, 28 Aug 2017 18:16:39 +0300 Subject: [PATCH 09/37] add certificate fragment to menu (open certificate from notifications work). --- .../java/org/stepic/droid/core/ScreenManagerImpl.java | 6 +----- .../stepic/droid/ui/activities/MainFeedActivity.kt | 11 +++++++---- .../droid/ui/fragments/CertificatesFragment.java | 2 +- .../org/stepic/droid/util/ProfileSettingsHelper.kt | 9 --------- app/src/main/res/menu/drawer_menu.xml | 6 ++++++ 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java index 4f7ea0ae80..82ab8c8d84 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java @@ -254,11 +254,7 @@ public Intent getCertificateIntent() { @Override public void showCertificates(Context context) { - Intent intent = new Intent(context, CertificatesActivity.class); - if (!(context instanceof Activity)) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - } - context.startActivity(intent); + showMainFeed(context, MainFeedActivity.Companion.getCertificateIndex()); } @Override diff --git a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt index 3986495060..2c4b8fc936 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt @@ -36,6 +36,7 @@ import org.stepic.droid.ui.activities.contracts.RootScreen import org.stepic.droid.ui.dialogs.LoadingProgressDialogFragment import org.stepic.droid.ui.dialogs.LogoutAreYouSureDialog import org.stepic.droid.ui.dialogs.NeedUpdatingDialog +import org.stepic.droid.ui.fragments.CertificatesFragment import org.stepic.droid.ui.fragments.FindCoursesFragment import org.stepic.droid.ui.fragments.MyCoursesFragment import org.stepic.droid.ui.fragments.ProfileFragment @@ -64,14 +65,11 @@ class MainFeedActivity : BackToExitActivityBase(), const val defaultIndex: Int = 0 val defaultTag: String = MyCoursesFragment::class.java.simpleName private val progressLogoutTag = "progressLogoutTag" - // FIXME: 10.08.17 remove it - val certificateFragmentIndex: Int + val certificateIndex: Int get() = 4 - // FIXME: 10.08.17 remove it val myCoursesIndex: Int get() = 1 - // FIXME: 10.08.17 remove it val findCoursesIndex: Int get() = 2 @@ -160,6 +158,7 @@ class MainFeedActivity : BackToExitActivityBase(), val wantedIndex = intent?.getIntExtra(currentIndexKey, -1) ?: -1 when (wantedIndex) { findCoursesIndex -> navigationView.selectedItemId = R.id.find_courses + certificateIndex -> navigationView.selectedItemId = R.id.certificates else -> { //do nothing } @@ -296,6 +295,10 @@ class MainFeedActivity : BackToExitActivityBase(), R.id.profile -> { getNextFragmentOrNull(currentFragmentTag, ProfileFragment::class.java.simpleName, ProfileFragment.Companion::newInstance) } + R.id.certificates -> { + analytic.reportEvent(Analytic.Screens.USER_OPEN_CERTIFICATES) + getNextFragmentOrNull(currentFragmentTag, CertificatesFragment::class.java.simpleName, CertificatesFragment::newInstance) + } else -> { null } diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java index 0cff9c3e01..c270322df3 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java @@ -91,7 +91,7 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { nullifyActivityBackground(); super.onViewCreated(view, savedInstanceState); - ToolbarHelperKt.initCenteredToolbar(this, R.string.certificates_title, true, getCloseIconDrawableRes()); + ToolbarHelperKt.initCenteredToolbar(this, R.string.certificates_title, false); adapter = new CertificatesAdapter(certificatePresenter, getActivity()); certificateRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); diff --git a/app/src/main/java/org/stepic/droid/util/ProfileSettingsHelper.kt b/app/src/main/java/org/stepic/droid/util/ProfileSettingsHelper.kt index 827b67ace3..26fe7fc776 100644 --- a/app/src/main/java/org/stepic/droid/util/ProfileSettingsHelper.kt +++ b/app/src/main/java/org/stepic/droid/util/ProfileSettingsHelper.kt @@ -28,9 +28,6 @@ private val aboutTitleRes = R.string.about_app_title @StringRes private val logoutTitleRes = R.string.logout_title -@StringRes -private val certificatesTitleRes = R.string.certificates_title - object ProfileSettingsHelper { fun getProfileSettings(): List { @@ -38,7 +35,6 @@ object ProfileSettingsHelper { list.add(ProfileSettingsViewModel(settingsTitleRes)) list.add(ProfileSettingsViewModel(downloadsTitleRes)) - list.add(ProfileSettingsViewModel(certificatesTitleRes)) list.add(ProfileSettingsViewModel(notificationsTitleRes)) list.add(ProfileSettingsViewModel(feedbackTitleRes)) list.add(ProfileSettingsViewModel(aboutTitleRes)) @@ -62,11 +58,6 @@ fun ProfileSettingsViewModel?.clickProfileSettings(activity: Activity, screenManager.showSettings(activity) } - certificatesTitleRes -> { - analytic.reportEvent(Analytic.Screens.USER_OPEN_CERTIFICATES) - screenManager.showCertificates(activity) - } - downloadsTitleRes -> { analytic.reportEvent(Analytic.Screens.USER_OPEN_DOWNLOADS) screenManager.showDownloads(activity) diff --git a/app/src/main/res/menu/drawer_menu.xml b/app/src/main/res/menu/drawer_menu.xml index 7d709755b2..a5def98cd3 100644 --- a/app/src/main/res/menu/drawer_menu.xml +++ b/app/src/main/res/menu/drawer_menu.xml @@ -15,4 +15,10 @@ android:checkable="false" android:icon="@drawable/ic_profile" android:title="@string/profile_title"/> + + \ No newline at end of file From f422c444171ff69ea9e418575afff4844a36c63a Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Mon, 28 Aug 2017 18:31:10 +0300 Subject: [PATCH 10/37] Convert Certificates Fragment to Kotlin and make don't hide bottom bar on scroll certificates --- .../org/stepic/droid/base/FragmentBase.kt | 14 ++ .../droid/ui/activities/MainFeedActivity.kt | 2 +- .../CertificateShareDialogFragment.java | 1 - .../ui/fragments/CertificatesFragment.java | 213 ------------------ .../ui/fragments/CertificatesFragment.kt | 178 +++++++++++++++ .../droid/ui/fragments/CommentsFragment.kt | 4 +- .../ui/fragments/CourseListFragmentBase.java | 2 +- .../droid/ui/fragments/DownloadsFragment.java | 2 +- .../droid/ui/fragments/LessonFragment.java | 4 +- .../fragments/NotificationListFragment.java | 2 +- .../ui/fragments/NotificationsFragment.java | 2 +- .../droid/ui/fragments/ProfileFragment.kt | 10 - .../droid/ui/fragments/SectionsFragment.java | 2 +- .../droid/ui/fragments/UnitsFragment.java | 2 +- .../main/res/layout/empty_certificates.xml | 2 +- .../main/res/layout/fragment_certificates.xml | 4 +- .../main/res/layout/need_auth_placeholder.xml | 2 +- .../layout/progress_bar_on_empty_screen.xml | 2 +- 18 files changed, 208 insertions(+), 240 deletions(-) delete mode 100644 app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java create mode 100644 app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt diff --git a/app/src/main/java/org/stepic/droid/base/FragmentBase.kt b/app/src/main/java/org/stepic/droid/base/FragmentBase.kt index 0967bd4bbd..f25f34ab0f 100644 --- a/app/src/main/java/org/stepic/droid/base/FragmentBase.kt +++ b/app/src/main/java/org/stepic/droid/base/FragmentBase.kt @@ -8,8 +8,11 @@ import android.support.v4.app.Fragment import android.view.View import android.view.animation.Animation import android.view.inputmethod.InputMethodManager +import android.widget.LinearLayout import butterknife.ButterKnife import butterknife.Unbinder +import kotlinx.android.synthetic.main.fragment_profile_new.* +import org.stepic.droid.R import org.stepic.droid.analytic.Analytic import org.stepic.droid.concurrency.MainHandler import org.stepic.droid.configuration.Config @@ -21,6 +24,7 @@ import org.stepic.droid.preferences.UserPreferences import org.stepic.droid.storage.CancelSniffer import org.stepic.droid.storage.IDownloadManager import org.stepic.droid.storage.operations.DatabaseFacade +import org.stepic.droid.ui.activities.contracts.BottomNavigationViewRoot import org.stepic.droid.ui.util.CloseIconHolder import org.stepic.droid.util.resolvers.CoursePropertyResolver import org.stepic.droid.util.resolvers.text.TextResolver @@ -168,4 +172,14 @@ open class FragmentBase : Fragment() { protected fun nullifyActivityBackground() { activity?.window?.decorView?.background = null } + + /** + * Apply margin if activity has bottom navigation bar + */ + protected fun applyBottomMarginForRootView() { + activity as? BottomNavigationViewRoot ?: return + + val layoutParams = profileRootView.layoutParams as LinearLayout.LayoutParams + layoutParams.bottomMargin = resources.getDimensionPixelSize(R.dimen.bottom_navigation_height) + } } \ No newline at end of file diff --git a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt index 2c4b8fc936..bb53b1eb90 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt @@ -297,7 +297,7 @@ class MainFeedActivity : BackToExitActivityBase(), } R.id.certificates -> { analytic.reportEvent(Analytic.Screens.USER_OPEN_CERTIFICATES) - getNextFragmentOrNull(currentFragmentTag, CertificatesFragment::class.java.simpleName, CertificatesFragment::newInstance) + getNextFragmentOrNull(currentFragmentTag, CertificatesFragment::class.java.simpleName, CertificatesFragment.Companion::newInstance) } else -> { null diff --git a/app/src/main/java/org/stepic/droid/ui/dialogs/CertificateShareDialogFragment.java b/app/src/main/java/org/stepic/droid/ui/dialogs/CertificateShareDialogFragment.java index d518569bb8..e5acdfd472 100644 --- a/app/src/main/java/org/stepic/droid/ui/dialogs/CertificateShareDialogFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/dialogs/CertificateShareDialogFragment.java @@ -13,7 +13,6 @@ public class CertificateShareDialogFragment extends DialogFragment { private static final String CERTIFICATE_VIEW_ITEM_KEY = "certificateViewItemKey"; public static DialogFragment newInstance(@NotNull CertificateViewItem viewItem) { - Bundle args = new Bundle(); args.putParcelable(CERTIFICATE_VIEW_ITEM_KEY, viewItem); DialogFragment fragment = new CertificateShareDialogFragment(); diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java deleted file mode 100644 index c270322df3..0000000000 --- a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.stepic.droid.ui.fragments; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ProgressBar; -import android.widget.Toast; - -import org.stepic.droid.R; -import org.stepic.droid.base.App; -import org.stepic.droid.base.FragmentBase; -import org.stepic.droid.core.presenters.CertificatePresenter; -import org.stepic.droid.core.presenters.contracts.CertificateView; -import org.stepic.droid.model.CertificateViewItem; -import org.stepic.droid.ui.adapters.CertificatesAdapter; -import org.stepic.droid.ui.dialogs.CertificateShareDialogFragment; -import org.stepic.droid.ui.util.ToolbarHelperKt; -import org.stepic.droid.util.ProgressHelper; - -import java.util.List; - -import javax.inject.Inject; - -import butterknife.BindView; - -public class CertificatesFragment extends FragmentBase implements CertificateView, SwipeRefreshLayout.OnRefreshListener { - - private CertificatesAdapter adapter; - - public static Fragment newInstance() { - return new CertificatesFragment(); - } - - @Inject - CertificatePresenter certificatePresenter; - - @BindView(R.id.certificates_recycler_view) - RecyclerView certificateRecyclerView; - - @BindView(R.id.loadProgressbar) - ProgressBar progressBarOnCenter; - - @BindView(R.id.reportProblem) - View reportInternetProblem; - - @BindView(R.id.report_empty) - View reportEmpty; - - @BindView(R.id.certificate_swipe_refresh) - SwipeRefreshLayout swipeRefreshLayout; - - @BindView(R.id.need_auth_view) - View needAuthRootView; - - @BindView(R.id.authAction) - Button authUserButton; - - @Override - protected void injectComponent() { - App.Companion - .component() - .certificateComponentBuilder() - .build() - .inject(this); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setRetainInstance(true); - setHasOptionsMenu(true); - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_certificates, container, false); - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - nullifyActivityBackground(); - super.onViewCreated(view, savedInstanceState); - - ToolbarHelperKt.initCenteredToolbar(this, R.string.certificates_title, false); - - adapter = new CertificatesAdapter(certificatePresenter, getActivity()); - certificateRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - certificateRecyclerView.setAdapter(adapter); - - authUserButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getScreenManager().showLaunchScreen(getActivity()); - } - }); - - swipeRefreshLayout.setOnRefreshListener(this); - swipeRefreshLayout.setColorSchemeResources( - R.color.stepic_brand_primary, - R.color.stepic_orange_carrot, - R.color.stepic_blue_ribbon); - - certificatePresenter.attachView(this); - - loadAndShowCertificates(); - } - - @Override - public void onDestroyView() { - certificatePresenter.detachView(this); - authUserButton.setOnClickListener(null); - super.onDestroyView(); - } - - private void loadAndShowCertificates() { - certificatePresenter.showCertificates(false); - } - - @Override - public void onLoading() { - if (certificatePresenter.size() <= 0) { - reportInternetProblem.setVisibility(View.GONE); - reportEmpty.setVisibility(View.GONE); - ProgressHelper.activate(progressBarOnCenter); - } - } - - @Override - public void showEmptyState() { - needAuthRootView.setVisibility(View.GONE); - ProgressHelper.dismiss(swipeRefreshLayout); - ProgressHelper.dismiss(progressBarOnCenter); - reportInternetProblem.setVisibility(View.GONE); - if (certificatePresenter.size() <= 0) { - reportEmpty.setVisibility(View.VISIBLE); - } - } - - @Override - public void onInternetProblem() { - ProgressHelper.dismiss(swipeRefreshLayout); - ProgressHelper.dismiss(progressBarOnCenter); - reportEmpty.setVisibility(View.GONE); - needAuthRootView.setVisibility(View.GONE); - if (certificatePresenter.size() <= 0) { - reportInternetProblem.setVisibility(View.VISIBLE); - } else { - Toast.makeText(getContext(), R.string.connectionProblems, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onDataLoaded(List certificateViewItems) { - ProgressHelper.dismiss(progressBarOnCenter); - ProgressHelper.dismiss(swipeRefreshLayout); - reportEmpty.setVisibility(View.GONE); - reportInternetProblem.setVisibility(View.GONE); - needAuthRootView.setVisibility(View.GONE); - swipeRefreshLayout.setVisibility(View.VISIBLE); - certificateRecyclerView.setVisibility(View.VISIBLE); - adapter.updateCertificates(certificateViewItems); - } - - @Override - public void onNeedShowShareDialog(@org.jetbrains.annotations.Nullable CertificateViewItem certificateViewItem) { - if (certificateViewItem == null) { - return; - } - DialogFragment bottomSheetDialogFragment = CertificateShareDialogFragment.newInstance(certificateViewItem); - if (bottomSheetDialogFragment != null && !bottomSheetDialogFragment.isAdded()) { - bottomSheetDialogFragment.show(getFragmentManager(), null); - } - - } - - @Override - public void onAnonymousUser() { - ProgressHelper.dismiss(swipeRefreshLayout); - ProgressHelper.dismiss(progressBarOnCenter); - reportEmpty.setVisibility(View.GONE); - reportInternetProblem.setVisibility(View.GONE); - certificateRecyclerView.setVisibility(View.GONE); - swipeRefreshLayout.setVisibility(View.GONE); - needAuthRootView.setVisibility(View.VISIBLE); - } - - @Override - public void onRefresh() { - certificatePresenter.showCertificates(true); - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - getActivity().finish(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } -} diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt new file mode 100644 index 0000000000..4d58d47061 --- /dev/null +++ b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt @@ -0,0 +1,178 @@ +package org.stepic.droid.ui.fragments + +import android.os.Bundle +import android.support.v4.app.Fragment +import android.support.v4.widget.SwipeRefreshLayout +import android.support.v7.widget.LinearLayoutManager +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import kotlinx.android.synthetic.main.empty_certificates.* +import kotlinx.android.synthetic.main.fragment_certificates.* +import kotlinx.android.synthetic.main.need_auth_placeholder.* +import kotlinx.android.synthetic.main.progress_bar_on_empty_screen.* +import kotlinx.android.synthetic.main.report_problem_layout.* +import org.stepic.droid.R +import org.stepic.droid.base.App +import org.stepic.droid.base.FragmentBase +import org.stepic.droid.core.presenters.CertificatePresenter +import org.stepic.droid.core.presenters.contracts.CertificateView +import org.stepic.droid.model.CertificateViewItem +import org.stepic.droid.ui.activities.contracts.BottomNavigationViewRoot +import org.stepic.droid.ui.adapters.CertificatesAdapter +import org.stepic.droid.ui.dialogs.CertificateShareDialogFragment +import org.stepic.droid.ui.util.initCenteredToolbar +import org.stepic.droid.util.ProgressHelper +import javax.inject.Inject + +class CertificatesFragment : FragmentBase(), + CertificateView, + SwipeRefreshLayout.OnRefreshListener { + + private var adapter: CertificatesAdapter? = null + + @Inject + lateinit var certificatePresenter: CertificatePresenter + + override fun injectComponent() { + App + .component() + .certificateComponentBuilder() + .build() + .inject(this) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + retainInstance = true + setHasOptionsMenu(true) + } + + override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?) = + inflater?.inflate(R.layout.fragment_certificates, container, false) + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + nullifyActivityBackground() + super.onViewCreated(view, savedInstanceState) + applyBottomMarginForRootView() + + initCenteredToolbar(R.string.certificates_title, false) + + adapter = CertificatesAdapter(certificatePresenter, activity) + certificateRecyclerView.layoutManager = LinearLayoutManager(context) + certificateRecyclerView.adapter = adapter + + authAction.setOnClickListener { screenManager.showLaunchScreen(activity) } + + certificateSwipeRefresh.setOnRefreshListener(this) + certificateSwipeRefresh.setColorSchemeResources( + R.color.stepic_brand_primary, + R.color.stepic_orange_carrot, + R.color.stepic_blue_ribbon) + + certificatePresenter.attachView(this) + + loadAndShowCertificates() + } + + override fun onDestroyView() { + certificatePresenter.detachView(this) + authAction.setOnClickListener(null) + super.onDestroyView() + } + + private fun loadAndShowCertificates() { + certificatePresenter.showCertificates(false) + } + + override fun onLoading() { + if (certificatePresenter.size() <= 0) { + reportProblem.visibility = View.GONE + reportEmptyCertificates.visibility = View.GONE + ProgressHelper.activate(loadProgressbarOnEmptyScreen) + } + } + + override fun showEmptyState() { + needAuthView.visibility = View.GONE + ProgressHelper.dismiss(certificateSwipeRefresh) + ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) + reportProblem.visibility = View.GONE + if (certificatePresenter.size() <= 0) { + reportEmptyCertificates.visibility = View.VISIBLE + } + } + + override fun onInternetProblem() { + ProgressHelper.dismiss(certificateSwipeRefresh) + ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) + reportEmptyCertificates.visibility = View.GONE + needAuthView.visibility = View.GONE + if (certificatePresenter.size() <= 0) { + reportProblem.visibility = View.VISIBLE + } else { + Toast.makeText(context, R.string.connectionProblems, Toast.LENGTH_SHORT).show() + } + } + + override fun onDataLoaded(certificateViewItems: List) { + ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) + ProgressHelper.dismiss(certificateSwipeRefresh) + reportEmptyCertificates.visibility = View.GONE + reportProblem.visibility = View.GONE + needAuthView.visibility = View.GONE + certificateSwipeRefresh.visibility = View.VISIBLE + certificateRecyclerView.visibility = View.VISIBLE + adapter?.updateCertificates(certificateViewItems) + } + + override fun onNeedShowShareDialog(certificateViewItem: CertificateViewItem?) { + if (certificateViewItem == null) { + return + } + val bottomSheetDialogFragment = CertificateShareDialogFragment.newInstance(certificateViewItem) + if (!bottomSheetDialogFragment.isAdded) { + bottomSheetDialogFragment.show(fragmentManager, null) + } + } + + override fun onAnonymousUser() { + ProgressHelper.dismiss(certificateSwipeRefresh) + ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) + reportEmptyCertificates.visibility = View.GONE + reportProblem.visibility = View.GONE + certificateRecyclerView.visibility = View.GONE + certificateSwipeRefresh.visibility = View.GONE + needAuthView.visibility = View.VISIBLE + } + + override fun onRefresh() { + certificatePresenter.showCertificates(true) + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean = + when (item?.itemId) { + android.R.id.home -> { + activity.finish() + true + } + else -> super.onOptionsItemSelected(item) + } + + companion object { + fun newInstance(): Fragment = CertificatesFragment() + } + + + override fun onResume() { + super.onResume() + (activity as? BottomNavigationViewRoot)?.disableAnyBehaviour() + } + + override fun onPause() { + super.onPause() + (activity as? BottomNavigationViewRoot)?.resetDefaultBehaviour() + } +} diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CommentsFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/CommentsFragment.kt index 0a424fb4fc..0a8b009c77 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/CommentsFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/CommentsFragment.kt @@ -413,11 +413,11 @@ class CommentsFragment : FragmentBase(), private fun showEmptyProgressOnCenter(needShow: Boolean = true) { if (needShow) { - ProgressHelper.activate(loadProgressbar) + ProgressHelper.activate(loadProgressbarOnEmptyScreen) showEmptyState(false) showInternetConnectionProblem(false) } else { - ProgressHelper.dismiss(loadProgressbar) + ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) } } diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CourseListFragmentBase.java b/app/src/main/java/org/stepic/droid/ui/fragments/CourseListFragmentBase.java index 03470f3c8a..2044f1aa3d 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/CourseListFragmentBase.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/CourseListFragmentBase.java @@ -73,7 +73,7 @@ public abstract class CourseListFragmentBase extends FragmentBase implements Swi @BindView(R.id.root_fragment_view) protected TouchDispatchableFrameLayout rootView; - @BindView(R.id.loadProgressbar) + @BindView(R.id.loadProgressbarOnEmptyScreen) protected ProgressBar progressBarOnEmptyScreen; @BindView(R.id.empty_search) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/DownloadsFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/DownloadsFragment.java index bb0b19ea07..677dbbd64b 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/DownloadsFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/DownloadsFragment.java @@ -85,7 +85,7 @@ public static DownloadsFragment newInstance() { @BindView(R.id.progress_bar) ProgressBar progressBar; - @BindView(R.id.need_auth_view) + @BindView(R.id.needAuthView) View needAuthRootView; @BindView(R.id.authAction) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/LessonFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/LessonFragment.java index a5e7febf72..7a1117ba58 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/LessonFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/LessonFragment.java @@ -122,7 +122,7 @@ public static LessonFragment newInstance(long simpleUnitId, long simpleLessonId, @BindView(R.id.stepsTabs) TabLayout tabLayout; - @BindView(R.id.loadProgressbar) + @BindView(R.id.loadProgressbarOnEmptyScreen) ProgressBar progressBar; @BindView(R.id.reportProblem) @@ -134,7 +134,7 @@ public static LessonFragment newInstance(long simpleUnitId, long simpleLessonId, @BindView(R.id.authAction) View authActionView; - @BindView(R.id.need_auth_view) + @BindView(R.id.needAuthView) View authView; @BindString(R.string.connectionProblems) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationListFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationListFragment.java index 5aeabcb028..db3e69e5b1 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationListFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationListFragment.java @@ -54,7 +54,7 @@ public static NotificationListFragment newInstance(int categoryPosition) { @BindView(R.id.notification_recycler_view) RecyclerView notificationRecyclerView; - @BindView(R.id.loadProgressbar) + @BindView(R.id.loadProgressbarOnEmptyScreen) View progressBarOnEmptyScreen; @BindView(R.id.reportProblem) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java index 06e78736b6..075b28eed8 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/NotificationsFragment.java @@ -42,7 +42,7 @@ public static NotificationsFragment newInstance() { @BindView(R.id.notification_viewpager) ViewPager viewPager; - @BindView(R.id.need_auth_view) + @BindView(R.id.needAuthView) View needAuthRootView; @BindView(R.id.authAction) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt index 499ab63d26..32efb4f38e 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt @@ -428,14 +428,4 @@ class ProfileFragment : FragmentBase(), streakIndicator.visibility = visibility } - /** - * Apply margin if activity has bottom navigation bar - */ - private fun applyBottomMarginForRootView() { - activity as? BottomNavigationViewRoot ?: return - - val layoutParams = profileRootView.layoutParams as LinearLayout.LayoutParams - layoutParams.bottomMargin = resources.getDimensionPixelSize(R.dimen.bottom_navigation_height) - } - } diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/SectionsFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/SectionsFragment.java index 0edae3c381..8ae7eb1073 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/SectionsFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/SectionsFragment.java @@ -138,7 +138,7 @@ public static SectionsFragment newInstance() { @BindView(R.id.sections_recycler_view) RecyclerView sectionsRecyclerView; - @BindView(R.id.loadProgressbar) + @BindView(R.id.loadProgressbarOnEmptyScreen) ProgressBar loadOnCenterProgressBar; @BindView(R.id.reportProblem) diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/UnitsFragment.java b/app/src/main/java/org/stepic/droid/ui/fragments/UnitsFragment.java index 9bc5cf671d..37b29532c2 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/UnitsFragment.java +++ b/app/src/main/java/org/stepic/droid/ui/fragments/UnitsFragment.java @@ -82,7 +82,7 @@ public static UnitsFragment newInstance(Section section) { @BindView(R.id.units_recycler_view) RecyclerView unitsRecyclerView; - @BindView(R.id.loadProgressbar) + @BindView(R.id.loadProgressbarOnEmptyScreen) ProgressBar progressBar; @BindView(R.id.reportProblem) diff --git a/app/src/main/res/layout/empty_certificates.xml b/app/src/main/res/layout/empty_certificates.xml index 5a90123edd..92972bc476 100644 --- a/app/src/main/res/layout/empty_certificates.xml +++ b/app/src/main/res/layout/empty_certificates.xml @@ -1,8 +1,8 @@ Date: Mon, 28 Aug 2017 20:29:28 +0300 Subject: [PATCH 11/37] fix color bug for e-mail textColor on sign up screen (Android O) fix wrong focus on empty courses fix position of Certificate empty views with bottom navigation --- .../org/stepic/droid/base/FragmentBase.kt | 9 ++++++--- .../ui/fragments/CertificatesFragment.kt | 19 +++++++++++++++++++ .../droid/ui/fragments/ProfileFragment.kt | 4 ++-- app/src/main/res/layout/activity_register.xml | 2 +- app/src/main/res/layout/empty_courses.xml | 2 ++ .../main/res/layout/fragment_certificates.xml | 7 +++++-- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/base/FragmentBase.kt b/app/src/main/java/org/stepic/droid/base/FragmentBase.kt index f25f34ab0f..3d947e94c4 100644 --- a/app/src/main/java/org/stepic/droid/base/FragmentBase.kt +++ b/app/src/main/java/org/stepic/droid/base/FragmentBase.kt @@ -6,12 +6,11 @@ import android.os.Bundle import android.support.annotation.DrawableRes import android.support.v4.app.Fragment import android.view.View +import android.view.ViewGroup import android.view.animation.Animation import android.view.inputmethod.InputMethodManager -import android.widget.LinearLayout import butterknife.ButterKnife import butterknife.Unbinder -import kotlinx.android.synthetic.main.fragment_profile_new.* import org.stepic.droid.R import org.stepic.droid.analytic.Analytic import org.stepic.droid.concurrency.MainHandler @@ -178,8 +177,12 @@ open class FragmentBase : Fragment() { */ protected fun applyBottomMarginForRootView() { activity as? BottomNavigationViewRoot ?: return + val rootView: ViewGroup = getRootView() ?: throw IllegalStateException("For using applyBottomMarginForRootView, you should override getRootView() in your fragment.") + + val layoutParams = rootView.layoutParams as ViewGroup.MarginLayoutParams - val layoutParams = profileRootView.layoutParams as LinearLayout.LayoutParams layoutParams.bottomMargin = resources.getDimensionPixelSize(R.dimen.bottom_navigation_height) } + + protected open fun getRootView(): ViewGroup? = null } \ No newline at end of file diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt index 4d58d47061..e0ea5ca5fe 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/CertificatesFragment.kt @@ -24,6 +24,7 @@ import org.stepic.droid.ui.activities.contracts.BottomNavigationViewRoot import org.stepic.droid.ui.adapters.CertificatesAdapter import org.stepic.droid.ui.dialogs.CertificateShareDialogFragment import org.stepic.droid.ui.util.initCenteredToolbar +import org.stepic.droid.util.ColorUtil import org.stepic.droid.util.ProgressHelper import javax.inject.Inject @@ -33,6 +34,14 @@ class CertificatesFragment : FragmentBase(), private var adapter: CertificatesAdapter? = null + private val oldCoverColor: Int by lazy { + ColorUtil.getColorArgb(R.color.old_cover, context) + } + + private val newCoverColor: Int by lazy { + ColorUtil.getColorArgb(R.color.new_cover, context) + } + @Inject lateinit var certificatePresenter: CertificatePresenter @@ -89,8 +98,10 @@ class CertificatesFragment : FragmentBase(), override fun onLoading() { if (certificatePresenter.size() <= 0) { + certificateSwipeRefresh.visibility = View.GONE reportProblem.visibility = View.GONE reportEmptyCertificates.visibility = View.GONE + certificateRootView.setBackgroundColor(newCoverColor) ProgressHelper.activate(loadProgressbarOnEmptyScreen) } } @@ -101,6 +112,8 @@ class CertificatesFragment : FragmentBase(), ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) reportProblem.visibility = View.GONE if (certificatePresenter.size() <= 0) { + certificateRootView.setBackgroundColor(oldCoverColor) + certificateSwipeRefresh.visibility = View.GONE reportEmptyCertificates.visibility = View.VISIBLE } } @@ -110,7 +123,9 @@ class CertificatesFragment : FragmentBase(), ProgressHelper.dismiss(loadProgressbarOnEmptyScreen) reportEmptyCertificates.visibility = View.GONE needAuthView.visibility = View.GONE + certificateSwipeRefresh.visibility = View.GONE if (certificatePresenter.size() <= 0) { + certificateRootView.setBackgroundColor(oldCoverColor) reportProblem.visibility = View.VISIBLE } else { Toast.makeText(context, R.string.connectionProblems, Toast.LENGTH_SHORT).show() @@ -125,6 +140,7 @@ class CertificatesFragment : FragmentBase(), needAuthView.visibility = View.GONE certificateSwipeRefresh.visibility = View.VISIBLE certificateRecyclerView.visibility = View.VISIBLE + certificateRootView.setBackgroundColor(oldCoverColor) adapter?.updateCertificates(certificateViewItems) } @@ -146,6 +162,7 @@ class CertificatesFragment : FragmentBase(), certificateRecyclerView.visibility = View.GONE certificateSwipeRefresh.visibility = View.GONE needAuthView.visibility = View.VISIBLE + certificateRootView.setBackgroundColor(newCoverColor) } override fun onRefresh() { @@ -175,4 +192,6 @@ class CertificatesFragment : FragmentBase(), super.onPause() (activity as? BottomNavigationViewRoot)?.resetDefaultBehaviour() } + + override fun getRootView(): ViewGroup = certificateRootView } diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt index 32efb4f38e..3eba886f59 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.support.v4.content.ContextCompat import android.support.v7.widget.LinearLayoutManager import android.view.* -import android.widget.LinearLayout import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import kotlinx.android.synthetic.main.fragment_profile_new.* @@ -63,7 +62,6 @@ class ProfileFragment : FragmentBase(), setHasOptionsMenu(true) profileSettingsList.clear() profileSettingsList.addAll(ProfileSettingsHelper.getProfileSettings()) - Timber.d("onCreate %s", this) } override fun injectComponent() { @@ -428,4 +426,6 @@ class ProfileFragment : FragmentBase(), streakIndicator.visibility = visibility } + override fun getRootView(): ViewGroup = profileRootView + } diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml index 14a068a74a..4163058364 100644 --- a/app/src/main/res/layout/activity_register.xml +++ b/app/src/main/res/layout/activity_register.xml @@ -99,7 +99,7 @@ android:paddingBottom="@dimen/half_padding" android:paddingTop="@dimen/half_padding"> - diff --git a/app/src/main/res/layout/fragment_certificates.xml b/app/src/main/res/layout/fragment_certificates.xml index f1c9af55cd..a8d80b4b46 100644 --- a/app/src/main/res/layout/fragment_certificates.xml +++ b/app/src/main/res/layout/fragment_certificates.xml @@ -9,9 +9,10 @@ + android:background="@color/new_cover"> @@ -22,10 +23,12 @@ + + android:layout_height="match_parent" + android:background="@color/old_cover"> Date: Tue, 29 Aug 2017 11:40:07 +0300 Subject: [PATCH 12/37] kotlinx & loader for webView --- .../droid/ui/activities/SocialAuthActivity.kt | 31 +++++++++++-------- .../main/res/layout/activity_social_auth.xml | 21 +++++++++++-- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt index bcd8c8aef8..6af8600f49 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt @@ -3,26 +3,25 @@ package org.stepic.droid.ui.activities import android.content.Intent import android.net.Uri import android.os.Bundle -import android.support.v7.app.AppCompatActivity import android.view.View import android.webkit.WebView import android.webkit.WebViewClient import org.stepic.droid.R +import org.stepic.droid.base.FragmentActivityBase import org.stepic.droid.util.AppConstants +import kotlinx.android.synthetic.main.activity_social_auth.* +import kotlinx.android.synthetic.main.panel_custom_action_bar.* -class SocialAuthActivity : AppCompatActivity() { - private lateinit var authWebView : WebView +class SocialAuthActivity : FragmentActivityBase() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_social_auth) overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.no_transition) - val d = intent.data.toString() - authWebView = findViewById(R.id.social_auth_web_view) - authWebView.webViewClient = object : WebViewClient() { + socialAuthWebView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (url != null) { val uri = Uri.parse(url) @@ -39,16 +38,22 @@ class SocialAuthActivity : AppCompatActivity() { } return false } + + override fun onPageFinished(view: WebView?, url: String?) { + socialAuthWebView.visibility = View.VISIBLE + progress.visibility = View.GONE + } } - authWebView.settings.javaScriptEnabled = true + socialAuthWebView.settings.javaScriptEnabled = true if (savedInstanceState == null) { - authWebView.loadUrl(d) + val authUrl = intent.data.toString() + socialAuthWebView.loadUrl(authUrl) } else { - authWebView.restoreState(savedInstanceState) + socialAuthWebView.restoreState(savedInstanceState) } - findViewById(R.id.actionbarCloseButtonLayout).setOnClickListener { finish() } + actionbarCloseButtonLayout.setOnClickListener { finish() } } override fun finish() { @@ -57,12 +62,12 @@ class SocialAuthActivity : AppCompatActivity() { } override fun onSaveInstanceState(outState: Bundle?) { - authWebView.saveState(outState) + socialAuthWebView.saveState(outState) } override fun onBackPressed() { - if (authWebView.canGoBack()) { - authWebView.goBack() + if (socialAuthWebView.canGoBack()) { + socialAuthWebView.goBack() } else { super.onBackPressed() } diff --git a/app/src/main/res/layout/activity_social_auth.xml b/app/src/main/res/layout/activity_social_auth.xml index c49fe76e48..13e700213e 100644 --- a/app/src/main/res/layout/activity_social_auth.xml +++ b/app/src/main/res/layout/activity_social_auth.xml @@ -10,9 +10,24 @@ android:id="@+id/toolbar" layout="@layout/panel_custom_action_bar"/> - + android:layout_height="match_parent"> + + + + + + \ No newline at end of file From 07cafe1abadedc11452fedf5a15d192a145836d7 Mon Sep 17 00:00:00 2001 From: Ruslan Davletshin Date: Tue, 29 Aug 2017 12:07:18 +0300 Subject: [PATCH 13/37] separation of concerns for SocialAuthActivity --- .../org.stepic.droid/ui/activities/LaunchActivity.kt | 4 +--- .../main/java/org/stepic/droid/core/ScreenManager.java | 2 ++ .../java/org/stepic/droid/core/ScreenManagerImpl.java | 8 ++++++++ .../org/stepic/droid/ui/adapters/SocialAuthAdapter.java | 2 +- .../main/java/org/stepic/droid/util/AppConstants.java | 1 + app/src/main/java/org/stepic/droid/web/Api.java | 2 +- app/src/main/java/org/stepic/droid/web/ApiImpl.java | 9 ++------- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt index dae2123035..0cb5f7e9d6 100644 --- a/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt +++ b/app/src/classic/java/org.stepic.droid/ui/activities/LaunchActivity.kt @@ -52,8 +52,6 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { private val TAG = "LaunchActivity" val wasLogoutKey = "wasLogoutKey" private val resolvingAccountKey = "resolvingAccountKey" - - const val REQUEST_CODE_SOCIAL_AUTH = 377 } private val requestFromSmartLockCode = 314 @@ -318,7 +316,7 @@ class LaunchActivity : BackToExitActivityBase(), LoginView { } } - if (requestCode == REQUEST_CODE_SOCIAL_AUTH && data != null) { + if (requestCode == AppConstants.REQUEST_CODE_SOCIAL_AUTH && data != null) { if (resultCode == Activity.RESULT_OK) { redirectFromSocial(data) } else if (resultCode == Activity.RESULT_CANCELED) { diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManager.java b/app/src/main/java/org/stepic/droid/core/ScreenManager.java index ea46544262..622a93d9b0 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManager.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManager.java @@ -34,6 +34,8 @@ public interface ScreenManager { void showLogin(Activity sourceActivity, @Nullable Course course, @Nullable String email); + void showSocialAuth(Activity sourceActivity, String authUrl, int requestCode); + void showMainFeed(Context sourceActivity, @Nullable Course course); void showMainFeedFromSplash(Activity sourceActivity); diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java index 7094b91746..937922814f 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java @@ -55,6 +55,7 @@ import org.stepic.droid.ui.activities.RegisterActivity; import org.stepic.droid.ui.activities.SectionActivity; import org.stepic.droid.ui.activities.SettingsActivity; +import org.stepic.droid.ui.activities.SocialAuthActivity; import org.stepic.droid.ui.activities.SplashActivity; import org.stepic.droid.ui.activities.StepsActivity; import org.stepic.droid.ui.activities.StoreManagementActivity; @@ -169,6 +170,13 @@ public void showLogin(Activity sourceActivity, @Nullable Course course, @Nullabl sourceActivity.startActivity(loginIntent); } + @Override + public void showSocialAuth(Activity sourceActivity, String authUrl, int requestCode) { + Uri uri = Uri.parse(authUrl); + final Intent intent = new Intent(sourceActivity, SocialAuthActivity.class).setData(uri); + sourceActivity.startActivityForResult(intent, requestCode); + } + @Override public void showMainFeed(Context sourceActivity, @Nullable Course course) { analytic.reportEvent(Analytic.Screens.SHOW_MAIN_FEED); diff --git a/app/src/main/java/org/stepic/droid/ui/adapters/SocialAuthAdapter.java b/app/src/main/java/org/stepic/droid/ui/adapters/SocialAuthAdapter.java index 08d5876df0..a11c525cb7 100644 --- a/app/src/main/java/org/stepic/droid/ui/adapters/SocialAuthAdapter.java +++ b/app/src/main/java/org/stepic/droid/ui/adapters/SocialAuthAdapter.java @@ -95,7 +95,7 @@ public void onClick(int position) { String[] scopes = {VKScope.EMAIL}; VKSdk.login(activity, scopes); } else { - api.loginWithSocial(activity, type); + api.loginWithSocial(activity, type, AppConstants.REQUEST_CODE_SOCIAL_AUTH); } } diff --git a/app/src/main/java/org/stepic/droid/util/AppConstants.java b/app/src/main/java/org/stepic/droid/util/AppConstants.java index fcbaa0e375..021bf0970b 100644 --- a/app/src/main/java/org/stepic/droid/util/AppConstants.java +++ b/app/src/main/java/org/stepic/droid/util/AppConstants.java @@ -12,6 +12,7 @@ public class AppConstants { public static final String APP_SCHEME = "stepic://"; public static final String QUERY_ERROR = "error"; public static final String ERROR_SOCIAL_AUTH_WITH_EXISTING_EMAIL = "social_signup_with_existing_email"; + public static final int REQUEST_CODE_SOCIAL_AUTH = 377; public static final String USER_LOG_IN = "user_login_clicked"; public static final String KEY_EMAIL_BUNDLE = "email"; diff --git a/app/src/main/java/org/stepic/droid/web/Api.java b/app/src/main/java/org/stepic/droid/web/Api.java index 789345eb8e..88a67b0670 100644 --- a/app/src/main/java/org/stepic/droid/web/Api.java +++ b/app/src/main/java/org/stepic/droid/web/Api.java @@ -60,7 +60,7 @@ enum TokenType { Call postViewed(ViewAssignment stepAssignment); - void loginWithSocial(FragmentActivity activity, ISocialType type); + void loginWithSocial(FragmentActivity activity, ISocialType type, int requestCode); Call getSearchResultsCourses(int page, String rawQuery); diff --git a/app/src/main/java/org/stepic/droid/web/ApiImpl.java b/app/src/main/java/org/stepic/droid/web/ApiImpl.java index c1f0dd918e..b121300323 100644 --- a/app/src/main/java/org/stepic/droid/web/ApiImpl.java +++ b/app/src/main/java/org/stepic/droid/web/ApiImpl.java @@ -1,7 +1,6 @@ package org.stepic.droid.web; import android.content.Context; -import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -47,8 +46,6 @@ import org.stepic.droid.serializers.ReplySerializer; import org.stepic.droid.social.ISocialType; import org.stepic.droid.social.SocialManager; -import org.stepic.droid.ui.activities.LaunchActivity; -import org.stepic.droid.ui.activities.SocialAuthActivity; import org.stepic.droid.util.AppConstants; import org.stepic.droid.util.DeviceInfoUtil; import org.stepic.droid.util.RWLocks; @@ -473,12 +470,10 @@ public Call postViewed(ViewAssignment stepAssignment) { } @Override - public void loginWithSocial(final FragmentActivity activity, ISocialType type) { + public void loginWithSocial(final FragmentActivity activity, ISocialType type, int requestCode) { String socialIdentifier = type.getIdentifier(); String url = config.getBaseUrl() + "/accounts/" + socialIdentifier + "/login?next=/oauth2/authorize/?" + Uri.encode("client_id=" + config.getOAuthClientId(TokenType.social) + "&response_type=code"); - Uri uri = Uri.parse(url); - final Intent intent = new Intent(activity, SocialAuthActivity.class).setData(uri); - activity.startActivityForResult(intent, LaunchActivity.REQUEST_CODE_SOCIAL_AUTH); + screenManager.showSocialAuth(activity, url, requestCode); } @Override From 91692387ffa2ca748bc1cc5ae2704ced600e41e2 Mon Sep 17 00:00:00 2001 From: Ruslan Davletshin Date: Tue, 29 Aug 2017 13:37:40 +0300 Subject: [PATCH 14/37] progress_bar_on_empty_screen --- .../org/stepic/droid/ui/activities/SocialAuthActivity.kt | 4 +++- app/src/main/res/layout/activity_social_auth.xml | 8 +------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt index 6af8600f49..d958c8e5ed 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/SocialAuthActivity.kt @@ -11,6 +11,7 @@ import org.stepic.droid.base.FragmentActivityBase import org.stepic.droid.util.AppConstants import kotlinx.android.synthetic.main.activity_social_auth.* import kotlinx.android.synthetic.main.panel_custom_action_bar.* +import kotlinx.android.synthetic.main.progress_bar_on_empty_screen.* class SocialAuthActivity : FragmentActivityBase() { @@ -21,6 +22,7 @@ class SocialAuthActivity : FragmentActivityBase() { overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.no_transition) + loadProgressbar.visibility = View.VISIBLE socialAuthWebView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (url != null) { @@ -41,7 +43,7 @@ class SocialAuthActivity : FragmentActivityBase() { override fun onPageFinished(view: WebView?, url: String?) { socialAuthWebView.visibility = View.VISIBLE - progress.visibility = View.GONE + loadProgressbar.visibility = View.GONE } } socialAuthWebView.settings.javaScriptEnabled = true diff --git a/app/src/main/res/layout/activity_social_auth.xml b/app/src/main/res/layout/activity_social_auth.xml index 13e700213e..240f99a1a0 100644 --- a/app/src/main/res/layout/activity_social_auth.xml +++ b/app/src/main/res/layout/activity_social_auth.xml @@ -20,13 +20,7 @@ android:id="@+id/socialAuthWebView" android:visibility="invisible"/> - + From c6a3b1e872862342457a5b677c2c97eac20d39ef Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Tue, 29 Aug 2017 14:19:39 +0300 Subject: [PATCH 15/37] change indexes of tabs from getters to const values in MainFeedActivity --- .../stepic/droid/core/ScreenManagerImpl.java | 6 +++--- .../droid/ui/activities/MainFeedActivity.kt | 18 ++++++------------ .../droid/ui/fragments/ProfileFragment.kt | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java index 82ab8c8d84..bf3ada1eba 100644 --- a/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java +++ b/app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java @@ -254,7 +254,7 @@ public Intent getCertificateIntent() { @Override public void showCertificates(Context context) { - showMainFeed(context, MainFeedActivity.Companion.getCertificateIndex()); + showMainFeed(context, MainFeedActivity.CERTIFICATE_INDEX); } @Override @@ -273,7 +273,7 @@ public void showFindCourses(Context context) { @Override public Intent getShowFindCoursesIntent(Context context) { - int index = MainFeedActivity.Companion.getFindCoursesIndex(); + int index = MainFeedActivity.FIND_COURSES_INDEX; return getFromMainActivityIntent(context, index); } @@ -399,7 +399,7 @@ public void openFeedbackActivity(Activity activity) { @Override public Intent getMyCoursesIntent(@NotNull Context context) { - int index = MainFeedActivity.Companion.getMyCoursesIndex(); + int index = MainFeedActivity.MY_COURSES_INDEX; return getFromMainActivityIntent(context, index); } diff --git a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt index bb53b1eb90..3c28920dd0 100644 --- a/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt +++ b/app/src/main/java/org/stepic/droid/ui/activities/MainFeedActivity.kt @@ -65,17 +65,11 @@ class MainFeedActivity : BackToExitActivityBase(), const val defaultIndex: Int = 0 val defaultTag: String = MyCoursesFragment::class.java.simpleName private val progressLogoutTag = "progressLogoutTag" - val certificateIndex: Int - get() = 4 - val myCoursesIndex: Int - get() = 1 - - val findCoursesIndex: Int - get() = 2 - - val profileIndex: Int - get() = 3 + const val MY_COURSES_INDEX: Int = 1 + const val FIND_COURSES_INDEX: Int = 2 + const val PROFILE_INDEX: Int = 3 + const val CERTIFICATE_INDEX: Int = 4 } @Inject @@ -157,8 +151,8 @@ class MainFeedActivity : BackToExitActivityBase(), setFragment(R.id.my_courses) val wantedIndex = intent?.getIntExtra(currentIndexKey, -1) ?: -1 when (wantedIndex) { - findCoursesIndex -> navigationView.selectedItemId = R.id.find_courses - certificateIndex -> navigationView.selectedItemId = R.id.certificates + FIND_COURSES_INDEX -> navigationView.selectedItemId = R.id.find_courses + CERTIFICATE_INDEX -> navigationView.selectedItemId = R.id.certificates else -> { //do nothing } diff --git a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt index 3eba886f59..4a4e1da334 100644 --- a/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt +++ b/app/src/main/java/org/stepic/droid/ui/fragments/ProfileFragment.kt @@ -109,7 +109,7 @@ class ProfileFragment : FragmentBase(), } authAction.setOnClickListener { - screenManager.showLaunchScreen(context, true, MainFeedActivity.profileIndex) + screenManager.showLaunchScreen(context, true, MainFeedActivity.PROFILE_INDEX) } } From 57883e1bccb1818e648fc2f6b4d5619cdf15f68e Mon Sep 17 00:00:00 2001 From: Kirill Makarov Date: Tue, 29 Aug 2017 16:53:26 +0300 Subject: [PATCH 16/37] the 1st version of new course widget --- .../droid/ui/adapters/CoursesAdapter.java | 17 +++---- app/src/main/res/layout/new_course_item.xml | 47 +++++++++++++++++++ app/src/main/res/values/dimens.xml | 2 + 3 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 app/src/main/res/layout/new_course_item.xml diff --git a/app/src/main/java/org/stepic/droid/ui/adapters/CoursesAdapter.java b/app/src/main/java/org/stepic/droid/ui/adapters/CoursesAdapter.java index 2d8189fa19..a700f96b9a 100644 --- a/app/src/main/java/org/stepic/droid/ui/adapters/CoursesAdapter.java +++ b/app/src/main/java/org/stepic/droid/ui/adapters/CoursesAdapter.java @@ -23,8 +23,8 @@ import org.stepic.droid.R; import org.stepic.droid.analytic.Analytic; import org.stepic.droid.base.App; -import org.stepic.droid.configuration.RemoteConfig; import org.stepic.droid.configuration.Config; +import org.stepic.droid.configuration.RemoteConfig; import org.stepic.droid.core.ScreenManager; import org.stepic.droid.core.presenters.ContinueCoursePresenter; import org.stepic.droid.model.Course; @@ -41,7 +41,6 @@ public class CoursesAdapter extends RecyclerView.Adapter { - @Inject Config config; @@ -92,7 +91,7 @@ public CourseViewHolderBase onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.loading_view, parent, false); return new FooterViewHolderItem(view); } else if (itemViewType == viewType) { - View view = inflater.inflate(R.layout.course_item, parent, false); + View view = inflater.inflate(R.layout.new_course_item, parent, false); return new CourseViewHolderItem(view); } else { throw new IllegalStateException("Not valid item type"); @@ -104,7 +103,6 @@ public void onBindViewHolder(CourseViewHolderBase holder, int position) { holder.setDataOnView(position); } - @Override public int getItemViewType(int position) { if (position == getItemCount() - 1) { @@ -153,16 +151,13 @@ public CourseViewHolderBase(View itemView) { class CourseViewHolderItem extends CourseViewHolderBase { - @BindView(R.id.course_name) + @BindView(R.id.courseItemName) TextView courseName; - @BindView(R.id.course_info) - TextView courseSummary; - - @BindView(R.id.course_icon) + @BindView(R.id.courseItemImage) ImageView courseIcon; - @BindView(R.id.continue_button) + @BindView(R.id.continueButton) Button continueButton; GlideDrawableImageViewTarget imageViewTarget; @@ -198,7 +193,6 @@ void setDataOnView(int position) { final Course course = courses.get(position); courseName.setText(course.getTitle()); - courseSummary.setText(textResolver.fromHtml(course.getSummary()).toString()); Glide .with(contextActivity) .load(StepikLogicHelper.getPathForCourseOrEmpty(course, config)) @@ -207,6 +201,7 @@ void setDataOnView(int position) { .into(imageViewTarget); + //// FIXME: 29.08.17 change logic to GONE-> "Join course" if (course.getEnrollment() != 0 && course.isActive() && course.getLastStepId() != null) { continueButton.setVisibility(View.VISIBLE); } else { diff --git a/app/src/main/res/layout/new_course_item.xml b/app/src/main/res/layout/new_course_item.xml new file mode 100644 index 0000000000..76e3a0915b --- /dev/null +++ b/app/src/main/res/layout/new_course_item.xml @@ -0,0 +1,47 @@ + + + + + +