Pārlūkot izejas kodu

Removed external library for permissions

Vadik Sirekanyan 6 gadi atpakaļ
vecāks
revīzija
b64b21f384

+ 0 - 1
app/build.gradle.kts

@@ -45,7 +45,6 @@ dependencies {
     implementation("io.reactivex.rxjava2:rxjava:2.2.5")
     implementation("io.reactivex.rxjava2:rxkotlin:2.3.0")
     implementation("io.reactivex.rxjava2:rxandroid:2.1.0")
-    implementation("com.github.tbruyelle:rxpermissions:0.10.2")
 
     // retrofit & okhttp
     implementation("com.squareup.retrofit2:retrofit:2.6.1")

+ 0 - 20
app/src/main/java/com/sirekanyan/knigopis/common/android/Permissions.kt

@@ -1,20 +0,0 @@
-package com.sirekanyan.knigopis.common.android
-
-import android.Manifest.permission.READ_PHONE_STATE
-import android.support.v7.app.AppCompatActivity
-import com.tbruyelle.rxpermissions2.Permission
-import com.tbruyelle.rxpermissions2.RxPermissions
-import io.reactivex.Single
-
-interface Permissions {
-
-    fun requestReadPhoneState(): Single<Permission>
-
-}
-
-class PermissionsImpl(private val activity: AppCompatActivity) : Permissions {
-
-    override fun requestReadPhoneState(): Single<Permission> =
-        RxPermissions(activity).requestEach(READ_PHONE_STATE).firstOrError()
-
-}

+ 18 - 0
app/src/main/java/com/sirekanyan/knigopis/common/android/permissions/Permission.kt

@@ -0,0 +1,18 @@
+package com.sirekanyan.knigopis.common.android.permissions
+
+import android.Manifest
+
+enum class Permission(val key: String, val requestCode: Int, val rationaleRequestCode: Int) {
+
+    PHONE(Manifest.permission.READ_PHONE_STATE, 300, 400);
+
+    val requestCodes = setOf(requestCode, rationaleRequestCode)
+
+    companion object {
+
+        fun findByKey(key: String): Permission? =
+            values().find { it.key == key }
+
+    }
+
+}

+ 27 - 0
app/src/main/java/com/sirekanyan/knigopis/common/android/permissions/PermissionResult.kt

@@ -0,0 +1,27 @@
+package com.sirekanyan.knigopis.common.android.permissions
+
+import android.content.pm.PackageManager
+
+class PermissionResult(
+    private val requestCode: Int,
+    val permission: Permission,
+    private val result: Int
+) {
+
+    fun isGranted(): Boolean =
+        result == PackageManager.PERMISSION_GRANTED
+
+    fun isRegularRequest(): Boolean =
+        requestCode == permission.requestCode
+
+    companion object {
+
+        fun create(requestCode: Int, permissionKey: String, result: Int): PermissionResult? {
+            val permission = Permission.findByKey(permissionKey) ?: return null
+            if (requestCode !in permission.requestCodes) return null
+            return PermissionResult(requestCode, permission, result)
+        }
+
+    }
+
+}

+ 92 - 0
app/src/main/java/com/sirekanyan/knigopis/common/android/permissions/Permissions.kt

@@ -0,0 +1,92 @@
+package com.sirekanyan.knigopis.common.android.permissions
+
+import android.content.pm.PackageManager.PERMISSION_DENIED
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import android.support.design.widget.Snackbar
+import android.support.v4.app.ActivityCompat
+import android.support.v4.content.ContextCompat
+import android.support.v7.app.AlertDialog
+import android.support.v7.app.AppCompatActivity
+import android.view.View
+import com.sirekanyan.knigopis.R
+import com.sirekanyan.knigopis.common.android.permissions.Permissions.Callback
+import com.sirekanyan.knigopis.common.functions.createAppSettingsIntent
+import com.sirekanyan.knigopis.repository.Configuration
+
+interface Permissions {
+
+    fun requestPermission(permission: Permission)
+    fun submitResult(result: PermissionResult)
+
+    interface Callback {
+
+        fun onGranted(permission: Permission)
+
+    }
+
+}
+
+class PermissionsImpl(
+    private val activity: AppCompatActivity,
+    private val config: Configuration
+) : Permissions {
+
+    lateinit var callback: Callback
+
+    override fun requestPermission(permission: Permission) {
+        when (ContextCompat.checkSelfPermission(activity, permission.key)) {
+            PERMISSION_GRANTED -> callback.onGranted(permission)
+            PERMISSION_DENIED -> onPermissionDenied(permission)
+        }
+    }
+
+    private fun onPermissionDenied(permission: Permission) {
+        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission.key)) {
+            showRationaleDialog {
+                requestPermission(permission, permission.rationaleRequestCode)
+            }
+        } else {
+            requestPermission(permission, permission.requestCode)
+        }
+    }
+
+    private fun requestPermission(permission: Permission, requestCode: Int) {
+        ActivityCompat.requestPermissions(activity, arrayOf(permission.key), requestCode)
+    }
+
+    override fun submitResult(result: PermissionResult) {
+        when {
+            result.isGranted() -> {
+                callback.onGranted(result.permission)
+            }
+            result.isRegularRequest() -> {
+                if (config.shouldShowSettings) {
+                    showSettingsDialog()
+                }
+                config.shouldShowSettings = true
+            }
+        }
+    }
+
+    private inline fun showRationaleDialog(crossinline onAllowed: () -> Unit) {
+        AlertDialog.Builder(activity)
+            .setTitle(R.string.permissions_title)
+            .setMessage(R.string.permissions_message_rationale)
+            .setPositiveButton(R.string.permissions_button_rationale) { _, _ -> onAllowed() }
+            .setNegativeButton(R.string.common_button_cancel, null)
+            .setCancelable(false)
+            .show()
+    }
+
+    private fun showSettingsDialog() {
+        val contentView = activity.findViewById<View>(android.R.id.content)
+        Snackbar.make(contentView, R.string.permissions_message_settings, Snackbar.LENGTH_LONG)
+            .setAction(R.string.permissions_button_settings) { openSettings() }
+            .show()
+    }
+
+    private fun openSettings() {
+        activity.startActivity(activity.createAppSettingsIntent())
+    }
+
+}

+ 1 - 7
app/src/main/java/com/sirekanyan/knigopis/dependency/activity.kt

@@ -1,14 +1,8 @@
 package com.sirekanyan.knigopis.dependency
 
 import android.app.Activity
-import android.support.v7.app.AppCompatActivity
-import com.sirekanyan.knigopis.common.android.Permissions
-import com.sirekanyan.knigopis.common.android.PermissionsImpl
 import com.sirekanyan.knigopis.common.android.dialog.BottomSheetDialogFactory
 import com.sirekanyan.knigopis.common.android.dialog.DialogFactory
 
 fun Activity.provideDialogs(): DialogFactory =
-    BottomSheetDialogFactory(this)
-
-fun AppCompatActivity.providePermissions(): Permissions =
-    PermissionsImpl(this)
+    BottomSheetDialogFactory(this)

+ 5 - 6
app/src/main/java/com/sirekanyan/knigopis/dependency/main.kt

@@ -1,13 +1,12 @@
 package com.sirekanyan.knigopis.dependency
 
 import com.sirekanyan.knigopis.common.android.dialog.DialogFactory
+import com.sirekanyan.knigopis.common.android.permissions.PermissionsImpl
 import com.sirekanyan.knigopis.common.extensions.app
 import com.sirekanyan.knigopis.common.extensions.getRootView
 import com.sirekanyan.knigopis.feature.*
 import com.sirekanyan.knigopis.feature.books.BooksPresenterImpl
 import com.sirekanyan.knigopis.feature.books.BooksViewImpl
-import com.sirekanyan.knigopis.feature.login.LoginPresenterImpl
-import com.sirekanyan.knigopis.feature.login.LoginViewImpl
 import com.sirekanyan.knigopis.feature.notes.NotesPresenterImpl
 import com.sirekanyan.knigopis.feature.notes.NotesViewImpl
 import com.sirekanyan.knigopis.feature.users.UsersPresenterImpl
@@ -19,12 +18,11 @@ import kotlinx.android.synthetic.main.notes_page.view.*
 import kotlinx.android.synthetic.main.users_page.view.*
 
 fun MainActivity.providePresenter(): MainPresenter {
-    val loginPresenter = LoginPresenterImpl(this, providePermissions())
     val booksPresenter = BooksPresenterImpl(this, app.bookRepository)
     val usersPresenter = UsersPresenterImpl(this, app.userRepository, app.resourceProvider)
     val notesPresenter = NotesPresenterImpl(this, app.noteRepository)
+    val permissions = PermissionsImpl(this, app.config)
     return MainPresenterImpl(
-        loginPresenter,
         mapOf(
             BOOKS_TAB to booksPresenter,
             USERS_TAB to usersPresenter,
@@ -32,12 +30,12 @@ fun MainActivity.providePresenter(): MainPresenter {
         ),
         this,
         app.config,
-        app.authRepository
+        app.authRepository,
+        permissions
     ).also { mainPresenter ->
         val rootView = getRootView()
         val progressView = ProgressViewImpl(rootView.swipeRefresh, mainPresenter)
         val dialogs: DialogFactory = provideDialogs()
-        loginPresenter.view = LoginViewImpl(rootView, loginPresenter)
         booksPresenter.also { p ->
             p.view = BooksViewImpl(rootView.booksPage, booksPresenter, progressView, dialogs)
             p.parent = mainPresenter
@@ -51,5 +49,6 @@ fun MainActivity.providePresenter(): MainPresenter {
             p.parent = mainPresenter
         }
         mainPresenter.view = MainViewImpl(rootView, mainPresenter)
+        permissions.callback = mainPresenter
     }
 }

+ 13 - 7
app/src/main/java/com/sirekanyan/knigopis/feature/MainActivity.kt

@@ -6,15 +6,14 @@ import android.net.Uri
 import android.os.Bundle
 import com.sirekanyan.knigopis.R
 import com.sirekanyan.knigopis.common.BaseActivity
+import com.sirekanyan.knigopis.common.android.permissions.PermissionResult
 import com.sirekanyan.knigopis.common.extensions.*
-import com.sirekanyan.knigopis.common.functions.createAppSettingsIntent
 import com.sirekanyan.knigopis.common.functions.createLoginIntent
 import com.sirekanyan.knigopis.common.functions.extra
 import com.sirekanyan.knigopis.common.functions.logError
 import com.sirekanyan.knigopis.dependency.providePresenter
 import com.sirekanyan.knigopis.feature.book.createBookIntent
 import com.sirekanyan.knigopis.feature.books.BooksPresenter
-import com.sirekanyan.knigopis.feature.login.LoginPresenter
 import com.sirekanyan.knigopis.feature.notes.NotesPresenter
 import com.sirekanyan.knigopis.feature.profile.createProfileIntent
 import com.sirekanyan.knigopis.feature.user.createUserIntent
@@ -30,7 +29,6 @@ private val CURRENT_TAB_EXTRA = extra("current_tab")
 
 class MainActivity : BaseActivity(),
     MainPresenter.Router,
-    LoginPresenter.Router,
     BooksPresenter.Router,
     UsersPresenter.Router,
     NotesPresenter.Router {
@@ -99,6 +97,18 @@ class MainActivity : BaseActivity(),
         }
     }
 
+    override fun onRequestPermissionsResult(
+        requestCode: Int,
+        permissions: Array<String>,
+        results: IntArray
+    ) {
+        if (permissions.size == 1 && results.size == 1) {
+            PermissionResult.create(requestCode, permissions.single(), results.single())?.let {
+                presenter.onPermissionResult(it)
+            }
+        }
+    }
+
     override fun onBackPressed() {
         if (!presenter.back()) {
             super.onBackPressed()
@@ -109,10 +119,6 @@ class MainActivity : BaseActivity(),
         startActivityForResult(createLoginIntent(), LOGIN_REQUEST_CODE)
     }
 
-    override fun openSettingsScreen() {
-        startActivity(createAppSettingsIntent())
-    }
-
     override fun openProfileScreen() {
         startActivity(createProfileIntent())
     }

+ 21 - 6
app/src/main/java/com/sirekanyan/knigopis/feature/MainPresenter.kt

@@ -2,8 +2,10 @@ package com.sirekanyan.knigopis.feature
 
 import com.sirekanyan.knigopis.common.BasePresenter
 import com.sirekanyan.knigopis.common.Presenter
+import com.sirekanyan.knigopis.common.android.permissions.Permission
+import com.sirekanyan.knigopis.common.android.permissions.PermissionResult
+import com.sirekanyan.knigopis.common.android.permissions.Permissions
 import com.sirekanyan.knigopis.common.functions.logError
-import com.sirekanyan.knigopis.feature.login.LoginPresenter
 import com.sirekanyan.knigopis.feature.users.MainPresenterState
 import com.sirekanyan.knigopis.model.CurrentTab
 import com.sirekanyan.knigopis.model.CurrentTab.BOOKS_TAB
@@ -20,8 +22,10 @@ interface MainPresenter : Presenter {
     fun back(): Boolean
     fun onLoginScreenResult(token: String)
     fun onBookScreenResult()
+    fun onPermissionResult(permissionResult: PermissionResult)
 
     interface Router {
+        fun openLoginScreen()
         fun openProfileScreen()
         fun reopenScreen()
     }
@@ -29,16 +33,17 @@ interface MainPresenter : Presenter {
 }
 
 class MainPresenterImpl(
-    private val loginPresenter: LoginPresenter,
     private val pagePresenters: Map<CurrentTab, PagePresenter>,
     private val router: MainPresenter.Router,
     private val config: Configuration,
-    private val auth: AuthRepository
-) : BasePresenter<MainView>(loginPresenter, *pagePresenters.values.toTypedArray()),
+    private val auth: AuthRepository,
+    private val permissions: Permissions
+) : BasePresenter<MainView>(*pagePresenters.values.toTypedArray()),
     MainPresenter,
     MainView.Callbacks,
     PagesPresenter,
-    ProgressView.Callbacks {
+    ProgressView.Callbacks,
+    Permissions.Callback {
 
     private val loadedTabs = mutableSetOf<CurrentTab>()
     private var currentTab: CurrentTab? = null
@@ -135,7 +140,17 @@ class MainPresenterImpl(
     }
 
     override fun onLoginOptionClicked() {
-        loginPresenter.login()
+        permissions.requestPermission(Permission.PHONE)
+    }
+
+    override fun onPermissionResult(permissionResult: PermissionResult) {
+        permissions.submitResult(permissionResult)
+    }
+
+    override fun onGranted(permission: Permission) {
+        if (permission == Permission.PHONE) {
+            router.openLoginScreen()
+        }
     }
 
     override fun onProfileOptionClicked() {

+ 0 - 52
app/src/main/java/com/sirekanyan/knigopis/feature/login/LoginPresenter.kt

@@ -1,52 +0,0 @@
-package com.sirekanyan.knigopis.feature.login
-
-import com.sirekanyan.knigopis.common.BasePresenter
-import com.sirekanyan.knigopis.common.Presenter
-import com.sirekanyan.knigopis.common.android.Permissions
-import com.sirekanyan.knigopis.common.functions.logError
-
-interface LoginPresenter : Presenter {
-
-    fun login()
-
-    interface Router {
-        fun openLoginScreen()
-        fun openSettingsScreen()
-    }
-
-}
-
-class LoginPresenterImpl(
-    private val router: LoginPresenter.Router,
-    private val permissions: Permissions
-) : BasePresenter<LoginView>(),
-    LoginPresenter,
-    LoginView.Callbacks {
-
-    override fun login() {
-        permissions.requestReadPhoneState().bind({
-            when {
-                it.granted -> {
-                    router.openLoginScreen()
-                }
-                it.shouldShowRequestPermissionRationale -> {
-                    view.showPermissionsRetryDialog()
-                }
-                else -> {
-                    view.showPermissionsSettingsDialog()
-                }
-            }
-        }, {
-            logError("cannot request permission", it)
-        })
-    }
-
-    override fun onRetryLoginClicked() {
-        login()
-    }
-
-    override fun onGotoSettingsClicked() {
-        router.openSettingsScreen()
-    }
-
-}

+ 0 - 52
app/src/main/java/com/sirekanyan/knigopis/feature/login/LoginView.kt

@@ -1,52 +0,0 @@
-package com.sirekanyan.knigopis.feature.login
-
-import android.support.v7.app.AlertDialog
-import android.view.View
-import com.sirekanyan.knigopis.R
-import kotlinx.android.extensions.LayoutContainer
-
-interface LoginView {
-
-    fun showPermissionsRetryDialog()
-    fun showPermissionsSettingsDialog()
-
-    interface Callbacks {
-        fun onRetryLoginClicked()
-        fun onGotoSettingsClicked()
-    }
-
-}
-
-class LoginViewImpl(
-    override val containerView: View,
-    private val callbacks: LoginView.Callbacks
-) : LoginView,
-    LayoutContainer {
-
-    private val context = containerView.context
-
-    override fun showPermissionsRetryDialog() {
-        AlertDialog.Builder(context)
-            .setTitle(R.string.permissions_title)
-            .setMessage(R.string.permissions_message_retry)
-            .setPositiveButton(R.string.common_button_retry) { _, _ ->
-                callbacks.onRetryLoginClicked()
-            }
-            .setNegativeButton(R.string.common_button_cancel, null)
-            .setCancelable(false)
-            .show()
-    }
-
-    override fun showPermissionsSettingsDialog() {
-        AlertDialog.Builder(context)
-            .setTitle(R.string.permissions_title)
-            .setMessage(R.string.permissions_message_settings)
-            .setPositiveButton(R.string.permissions_button_settings) { _, _ ->
-                callbacks.onGotoSettingsClicked()
-            }
-            .setNegativeButton(R.string.common_button_cancel, null)
-            .setCancelable(false)
-            .show()
-    }
-
-}

+ 2 - 0
app/src/main/java/com/sirekanyan/knigopis/repository/Configuration.kt

@@ -10,10 +10,12 @@ private const val PREFS_NAME = "config"
 interface Configuration {
     var isDarkTheme: Boolean
     var sortingMode: Int
+    var shouldShowSettings: Boolean
 }
 
 class ConfigurationImpl(context: Application) : Configuration {
     internal val prefs = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
     override var isDarkTheme by BooleanPreference()
     override var sortingMode by IntPreference()
+    override var shouldShowSettings by BooleanPreference()
 }

+ 4 - 4
app/src/main/res/values-ru/strings.xml

@@ -2,7 +2,6 @@
     <!-- common -->
     <string name="common.title.app">Книгопись</string>
     <string name="common.error.network">Проверьте подключение к сети</string>
-    <string name="common.button.retry">Повторить</string>
     <string name="common.button.cancel">Отмена</string>
     <string name="common.info.dev">НЕ ПЫТАЙТЕСБ ЧТОТ0 N3МЕНИТЬ!</string>
     <plurals name="common.header.books">
@@ -96,9 +95,10 @@
 
     <!-- permissions -->
     <string name="permissions.title">Разрешения</string>
-    <string name="permissions.message.retry">Данное разрешение необходимо для авторизации через uLogin</string>
-    <string name="permissions.message.settings">Включите разрешение в настройках, чтобы авторизоваться с помощью uLogin</string>
-    <string name="permissions.button.settings">В настройки</string>
+    <string name="permissions.message.rationale">Для авторизации через uLogin необходимо дать разрешение на чтение идентификатора телефона.</string>
+    <string name="permissions.button.rationale">Продолжить</string>
+    <string name="permissions.message.settings">Разрешите доступ к телефону в\u00a0настройках</string>
+    <string name="permissions.button.settings">Настройки</string>
 
     <!-- social networks -->
     <string name="common.social.facebook">Фейсбук</string>

+ 4 - 4
app/src/main/res/values/strings.xml

@@ -2,7 +2,6 @@
     <!-- common -->
     <string name="common.title.app">Knigopis</string>
     <string name="common.error.network">Check your network connection</string>
-    <string name="common.button.retry">Retry</string>
     <string name="common.button.cancel">Cancel</string>
     <string name="common.info.dev">We Present A SPECIAL PRESENTATION</string>
     <plurals name="common.header.books">
@@ -95,9 +94,10 @@
 
     <!-- permissions -->
     <string name="permissions.title">Permissions</string>
-    <string name="permissions.message.retry">The permission is necessary to authorize you by using uLogin library, please allow in order to continue</string>
-    <string name="permissions.message.settings">Please allow permission in settings to authorize with uLogin</string>
-    <string name="permissions.button.settings">Goto settings</string>
+    <string name="permissions.message.rationale">Phone permission is necessary to authorize you by using uLogin library.</string>
+    <string name="permissions.button.rationale">Continue</string>
+    <string name="permissions.message.settings">Allow phone permission in settings</string>
+    <string name="permissions.button.settings">Settings</string>
 
     <!-- social networks -->
     <string name="common.social.facebook">Facebook</string>

+ 0 - 6
build.gradle.kts

@@ -13,12 +13,6 @@ allprojects {
     repositories {
         jcenter()
         google()
-        maven {
-            url = uri("https://jitpack.io")
-            content {
-                includeGroup("com.github.tbruyelle")
-            }
-        }
     }
 }