From 22159bc46dfec2c9544bdabde2cd70e102a6e7cb Mon Sep 17 00:00:00 2001 From: Mopsalarm Date: Thu, 30 Sep 2021 18:58:09 +0200 Subject: [PATCH] Add some checks for age verification. --- app/build.gradle | 8 +++---- .../app/api/pr0gramm/LoginCookieJar.kt | 4 +++- .../com/pr0gramm/app/services/UserService.kt | 21 ++++++++++++---- .../java/com/pr0gramm/app/ui/AdService.kt | 2 +- .../app/ui/fragments/feed/FeedFragment.kt | 24 ++++++++++++++++++- .../pr0gramm/app/ui/upload/UploadFragment.kt | 17 ++++++++++++- app/src/main/res/menu/menu_feed.xml | 13 ++++++---- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + build.gradle | 4 ++-- model/build.gradle | 2 +- .../app/model/user/LoginStateModel.kt | 5 +++- 12 files changed, 82 insertions(+), 20 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 521bb693f..74f753ed2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -152,7 +152,7 @@ dependencies { implementation project(":model") - implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.30" + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.31" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" @@ -170,7 +170,7 @@ dependencies { implementation 'androidx.concurrent:concurrent-futures:1.1.0' // implementation 'com.google.guava:listenablefuture:1.0' implementation 'androidx.paging:paging-runtime:3.0.1' - implementation "androidx.constraintlayout:constraintlayout:2.1.0" + implementation "androidx.constraintlayout:constraintlayout:2.1.1" implementation 'androidx.activity:activity-ktx:1.3.1' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' @@ -180,7 +180,7 @@ dependencies { implementation 'androidx.fragment:fragment-ktx:1.3.6' - implementation "com.google.android.gms:play-services-ads-lite:20.3.0" + implementation "com.google.android.gms:play-services-ads-lite:20.4.0" implementation 'com.google.firebase:firebase-analytics:19.0.1' implementation 'com.google.firebase:firebase-crashlytics:18.2.1' @@ -212,7 +212,7 @@ dependencies { implementation 'com.github.paolorotolo:appintro:5.1.0' - implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0' + implementation 'com.google.android.exoplayer:exoplayer-core:2.15.1' debugImplementation 'androidx.multidex:multidex:2.0.1' diff --git a/app/src/main/java/com/pr0gramm/app/api/pr0gramm/LoginCookieJar.kt b/app/src/main/java/com/pr0gramm/app/api/pr0gramm/LoginCookieJar.kt index 3ff862e04..016630cda 100644 --- a/app/src/main/java/com/pr0gramm/app/api/pr0gramm/LoginCookieJar.kt +++ b/app/src/main/java/com/pr0gramm/app/api/pr0gramm/LoginCookieJar.kt @@ -105,8 +105,10 @@ class LoginCookieJar(context: Context, private val preferences: SharedPreference // do nothing if the cookie value has not changed. val notChanged = previousCookie?.value == cookie.value - if (notChanged) + if (notChanged) { + logger.debug { "Cookie has not changed" } return true + } val parsedCookie = parseCookie(cookie) diff --git a/app/src/main/java/com/pr0gramm/app/services/UserService.kt b/app/src/main/java/com/pr0gramm/app/services/UserService.kt index 9eb0de0bf..21b2a3e36 100644 --- a/app/src/main/java/com/pr0gramm/app/services/UserService.kt +++ b/app/src/main/java/com/pr0gramm/app/services/UserService.kt @@ -11,6 +11,7 @@ import com.pr0gramm.app.model.user.LoginCookie import com.pr0gramm.app.model.user.LoginState import com.pr0gramm.app.orm.BenisRecord import com.pr0gramm.app.ui.base.AsyncScope +import com.pr0gramm.app.ui.base.launchIgnoreErrors import com.pr0gramm.app.util.catchAll import com.pr0gramm.app.util.debugOnly import com.pr0gramm.app.util.doInBackground @@ -44,7 +45,9 @@ class UserService(private val api: Api, @Suppress("PrivatePropertyName") private val NotAuthorized = LoginState( id = -1, score = 0, mark = 0, admin = false, - premium = false, authorized = false, name = null, uniqueToken = null) + premium = false, authorized = false, name = null, + uniqueToken = null, verified = false, + ) private val fullSyncInProgress = AtomicBoolean() @@ -145,6 +148,12 @@ class UserService(private val api: Api, if (cookie == null) { logger.info { "LoginCookie was removed, performing logout now." } AsyncScope.launch { logout() } + + } else { + // cookie has changed, re-build cached user info + AsyncScope.launchIgnoreErrors { + updateCachedUserInfo() + } } } @@ -375,7 +384,7 @@ class UserService(private val api: Api, private fun persistLatestLoginState(state: LoginState) { try { if (state.authorized) { - logger.debug { "Persisting login state now." } + logger.debug { "Persisting login state now: $loginState" } preferences.edit { val encoded = MoshiInstance.adapter().toJson(state) @@ -397,10 +406,13 @@ class UserService(private val api: Api, get() = loginState.authorized && cookieJar.parsedCookie?.id?.isNotBlank() == true val userIsPremium: Boolean - get() = loginState.authorized && cookieJar.parsedCookie?.paid == true + get() = isAuthorized && loginState.premium val userIsAdmin: Boolean - get() = loginState.authorized && cookieJar.parsedCookie?.admin == true + get() = isAuthorized && loginState.admin + + val userIsVerified: Boolean + get() = isAuthorized && loginState.verified val loginStateWithBenisGraph = run { val graphs = loginStates.mapLatest { loginState -> @@ -486,5 +498,6 @@ private fun createLoginStateFromInfo(user: Api.Info.User, cookie: LoginCookie?, score = user.score, premium = cookie?.paid == true, admin = cookie?.admin == true, + verified = cookie?.verified == true, uniqueToken = token) } \ No newline at end of file diff --git a/app/src/main/java/com/pr0gramm/app/ui/AdService.kt b/app/src/main/java/com/pr0gramm/app/ui/AdService.kt index a71dcd29a..5323cc0ea 100644 --- a/app/src/main/java/com/pr0gramm/app/ui/AdService.kt +++ b/app/src/main/java/com/pr0gramm/app/ui/AdService.kt @@ -106,7 +106,7 @@ class AdService(private val configService: ConfigService, private val userServic } fun newAdView(context: Context): AdView { - val view = AdView(context.applicationContext) + val view = AdView(context) view.adUnitId = bannerUnitId val backgroundColor = AndroidUtility.resolveColorAttribute(context, android.R.attr.windowBackground) diff --git a/app/src/main/java/com/pr0gramm/app/ui/fragments/feed/FeedFragment.kt b/app/src/main/java/com/pr0gramm/app/ui/fragments/feed/FeedFragment.kt index ce0c3e332..0130a2da5 100644 --- a/app/src/main/java/com/pr0gramm/app/ui/fragments/feed/FeedFragment.kt +++ b/app/src/main/java/com/pr0gramm/app/ui/fragments/feed/FeedFragment.kt @@ -247,6 +247,12 @@ class FeedFragment : BaseFragment("FeedFragment", R.layout.fragment_feed), Filte activity.invalidateOptionsMenu() } } + + launchInViewScope { + userService.loginStates.drop(1).collect { + activity.invalidateOptionsMenu() + } + } } private fun updateAdapterState(feedState: FeedViewModel.FeedState, userState: UserStateModel.UserState) { @@ -691,8 +697,16 @@ class FeedFragment : BaseFragment("FeedFragment", R.layout.fragment_feed), Filte R.string.action_switch_to_top else R.string.action_switch_to_new) } + menu.findItem(R.id.action_change_content_type__not_verified)?.let { item -> + item.isVisible = !userService.userIsVerified + item.icon = ContentTypeDrawable(activity, listOf(ContentType.SFW)).also { icon -> + icon.textSize = resources.getDimensionPixelSize( + R.dimen.feed_content_type_action_icon_text_size).toFloat() + } + } + menu.findItem(R.id.action_change_content_type)?.let { item -> - if (userService.isAuthorized) { + if (userService.userIsVerified) { val icon = ContentTypeDrawable(activity, selectedContentType) icon.textSize = resources.getDimensionPixelSize( R.dimen.feed_content_type_action_icon_text_size).toFloat() @@ -762,6 +776,7 @@ class FeedFragment : BaseFragment("FeedFragment", R.layout.fragment_feed), Filte R.id.action_open_in_admin -> openUserInAdmin() R.id.action_scroll_seen -> scrollToNextSeenAsync() R.id.action_scroll_unseen -> scrollToNextUnseenAsync() + R.id.action_change_content_type__not_verified -> hintUserIsNotVerified() else -> super.onOptionsItemSelected(item) } @@ -816,6 +831,13 @@ class FeedFragment : BaseFragment("FeedFragment", R.layout.fragment_feed), Filte (activity as MainActionHandler).bookmarkFilter(filter, title) } + private fun hintUserIsNotVerified() { + showDialog(this) { + content(R.string.user_is_not_verified) + positive() + } + } + private fun preloadCurrentFeed() { if (AndroidUtility.isOnMobile(activity)) { showDialog(this) { diff --git a/app/src/main/java/com/pr0gramm/app/ui/upload/UploadFragment.kt b/app/src/main/java/com/pr0gramm/app/ui/upload/UploadFragment.kt index 8898c9e85..6b14d371f 100644 --- a/app/src/main/java/com/pr0gramm/app/ui/upload/UploadFragment.kt +++ b/app/src/main/java/com/pr0gramm/app/ui/upload/UploadFragment.kt @@ -27,6 +27,7 @@ import com.pr0gramm.app.feed.FeedType import com.pr0gramm.app.services.RulesService import com.pr0gramm.app.services.UploadService import com.pr0gramm.app.services.UriHelper +import com.pr0gramm.app.services.UserService import com.pr0gramm.app.ui.* import com.pr0gramm.app.ui.base.BaseFragment import com.pr0gramm.app.ui.base.bindViews @@ -47,6 +48,7 @@ class UploadFragment : BaseFragment("UploadFragment", R.layout.fragment_upload) private val rulesService: RulesService by instance() private val tagSuggestions: TagSuggestionService by instance() + private val userService: UserService by instance() private val views by bindViews(FragmentUploadBinding::bind) @@ -117,6 +119,12 @@ class UploadFragment : BaseFragment("UploadFragment", R.layout.fragment_upload) } } + launchInViewScope { + userService.loginStates.drop(1).collect { + updateFormState(vm.state.value) + } + } + launchInViewScope { vm.state.collect { state -> logger.debug { "Current state is: $state" } @@ -234,8 +242,14 @@ class UploadFragment : BaseFragment("UploadFragment", R.layout.fragment_upload) views.tags.isEnabled = enabled + val loginState = userService.loginState + for (childView in views.contentTypeGroup.children) { childView.isEnabled = enabled + + if (!loginState.verified && childView.id != R.id.upload_type_sfw) { + childView.isEnabled = false + } } val hasTagSelected = views.contentTypeGroup.children.any { childView -> @@ -243,8 +257,9 @@ class UploadFragment : BaseFragment("UploadFragment", R.layout.fragment_upload) } val imageSizeOkay = state.fileSizeOkay + val isVerifiedOrUploadTypeIsSFW = selectedContentType() == ContentType.SFW || loginState.verified - views.actionUpload.isEnabled = enabled && hasTagSelected && imageSizeOkay + views.actionUpload.isEnabled = enabled && hasTagSelected && imageSizeOkay && isVerifiedOrUploadTypeIsSFW } private fun onUploadComplete(postId: Long) { diff --git a/app/src/main/res/menu/menu_feed.xml b/app/src/main/res/menu/menu_feed.xml index b65bcfbab..967231551 100644 --- a/app/src/main/res/menu/menu_feed.xml +++ b/app/src/main/res/menu/menu_feed.xml @@ -12,7 +12,6 @@ @@ -25,21 +24,27 @@ + android:title="@string/type_nsfw" /> + android:title="@string/type_nsfl" /> + + + app:showAsAction="ifRoom" /> Nächster gesehener Hochlad Maximale Scrollweite erreicht. Probiere es einfach nochmal. Changelog + Deine Altersverifikation ist noch nicht abgeschlossen. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 938f572ef..072de459c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -581,5 +581,6 @@ Scroll next seen Max scroll distance reached. Please try again. Changelog + You are not age verified. diff --git a/build.gradle b/build.gradle index 6d5a93dff..388f6c384 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,8 @@ buildscript { } plugins { - id "org.jetbrains.kotlin.android" version "1.5.30" apply false - id "org.jetbrains.kotlin.kapt" version "1.5.30" apply false + id "org.jetbrains.kotlin.android" version "1.5.31" apply false + id "org.jetbrains.kotlin.kapt" version "1.5.31" apply false id "com.github.ben-manes.versions" version "0.39.0" } diff --git a/model/build.gradle b/model/build.gradle index 5fe2d0957..5b48316c1 100644 --- a/model/build.gradle +++ b/model/build.gradle @@ -53,7 +53,7 @@ repositories { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.30" + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.31" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" diff --git a/model/src/main/java/com/pr0gramm/app/model/user/LoginStateModel.kt b/model/src/main/java/com/pr0gramm/app/model/user/LoginStateModel.kt index 551e0e668..ac6de13ae 100644 --- a/model/src/main/java/com/pr0gramm/app/model/user/LoginStateModel.kt +++ b/model/src/main/java/com/pr0gramm/app/model/user/LoginStateModel.kt @@ -12,6 +12,7 @@ data class LoginState( val uniqueToken: String?, val admin: Boolean, val premium: Boolean, + val verified: Boolean = false, val authorized: Boolean) @@ -20,4 +21,6 @@ data class LoginCookie( val id: String, @Json(name = "n") val name: String, @Json(name = "paid") val paid: Boolean = false, - @Json(name = "a") val admin: Boolean = false) + @Json(name = "a") val admin: Boolean = false, + @Json(name = "verified") val verified: Boolean = false, +)