diff --git a/app/src/main/java/com/h/pixeldroid/LoginActivity.kt b/app/src/main/java/com/h/pixeldroid/LoginActivity.kt index 389e93aa..c2ba4a04 100644 --- a/app/src/main/java/com/h/pixeldroid/LoginActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/LoginActivity.kt @@ -6,7 +6,6 @@ import android.content.Intent import android.content.SharedPreferences import android.net.Uri import android.os.Bundle -import android.util.Log import android.view.View import android.view.inputmethod.InputMethodManager import androidx.lifecycle.lifecycleScope @@ -19,13 +18,12 @@ import com.h.pixeldroid.utils.hasInternet import com.h.pixeldroid.utils.normalizeDomain import com.h.pixeldroid.utils.openUrl import kotlinx.android.synthetic.main.activity_login.* +import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope import okhttp3.HttpUrl -import retrofit2.Call -import retrofit2.Callback import retrofit2.HttpException -import retrofit2.Response import java.io.IOException /** @@ -132,17 +130,24 @@ class LoginActivity : BaseActivity() { lifecycleScope.launch { try { - val credentialsDeferred = async { - pixelfedAPI.registerApplication( - appName, "$oauthScheme://$PACKAGE_ID", SCOPE - ) + supervisorScope { } + val credentialsDeferred: Deferred = async { + try { + pixelfedAPI.registerApplication( + appName, "$oauthScheme://$PACKAGE_ID", SCOPE + ) + } catch (exception: IOException) { + return@async null + } catch (exception: HttpException) { + return@async null + } } val nodeInfoJRD = pixelfedAPI.wellKnownNodeInfo() val credentials = credentialsDeferred.await() - val clientId = credentials.client_id ?: return@launch failedRegistration() + val clientId = credentials?.client_id ?: return@launch failedRegistration() preferences.edit() .putString("domain", normalizedDomain) .putString("clientID", clientId) diff --git a/app/src/main/java/com/h/pixeldroid/MainActivity.kt b/app/src/main/java/com/h/pixeldroid/MainActivity.kt index 48536be8..295ece55 100644 --- a/app/src/main/java/com/h/pixeldroid/MainActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/MainActivity.kt @@ -14,6 +14,7 @@ import androidx.core.view.GravityCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.paging.ExperimentalPagingApi +import androidx.room.withTransaction import androidx.viewpager2.adapter.FragmentStateAdapter import com.bumptech.glide.Glide import com.google.android.material.tabs.TabLayoutMediator @@ -167,21 +168,21 @@ class MainActivity : BaseActivity() { } private fun logOut(){ - db.userDao().deleteActiveUsers() + db.runInTransaction { + db.userDao().deleteActiveUsers() - val remainingUsers = db.userDao().getAll() - if (remainingUsers.isEmpty()){ - //no more users, start first-time login flow - launchActivity(LoginActivity(), firstTime = true) - } else { - val newActive = remainingUsers.first() - db.userDao().activateUser(newActive.user_id) - //relaunch the app - launchActivity(MainActivity(), firstTime = true) + val remainingUsers = db.userDao().getAll() + if (remainingUsers.isEmpty()){ + //no more users, start first-time login flow + launchActivity(LoginActivity(), firstTime = true) + } else { + val newActive = remainingUsers.first() + db.userDao().activateUser(newActive.user_id) + apiHolder.setDomainToCurrentUser(db) + //relaunch the app + launchActivity(MainActivity(), firstTime = true) + } } - - - } private fun getUpdatedAccount() { if (hasInternet(applicationContext)) { diff --git a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/CachedFeedFragment.kt b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/CachedFeedFragment.kt index ab2ec9e8..c02eb2f8 100644 --- a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/CachedFeedFragment.kt +++ b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/CachedFeedFragment.kt @@ -42,7 +42,7 @@ open class CachedFeedFragment : BaseFragment() { internal fun launch() { // Make sure we cancel the previous job before creating a new one job?.cancel() - job = lifecycleScope.launch { + job = lifecycleScope.launchWhenStarted { viewModel.flow().collectLatest { adapter.submitData(it) } @@ -88,8 +88,8 @@ open class CachedFeedFragment : BaseFragment() { /** * Factory that creates ViewModel from a [FeedContentRepository], to be used in cached feeds to - * fetch the ViewModel that is responsible for preparing and managing the data for - * an Activity or a Fragment + * fetch the ViewModel that is responsible for preparing and managing the data + * for a CachedFeedFragment */ class ViewModelFactory @ExperimentalPagingApi constructor(private val db: AppDatabase?, private val dao: FeedContentDao?, diff --git a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/FeedContentRepository.kt b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/FeedContentRepository.kt index 9c887d48..8477b2e7 100644 --- a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/FeedContentRepository.kt +++ b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/FeedContentRepository.kt @@ -39,9 +39,9 @@ class FeedContentRepository @ExperimentalPagingApi */ @ExperimentalPagingApi fun stream(): Flow> { + val user = db.userDao().getActiveUser()!! val pagingSourceFactory = { - val user = db.userDao().getActiveUser()!! dao.feedContent(user.user_id, user.instance_uri) } diff --git a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/notifications/NotificationsRemoteMediator.kt b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/notifications/NotificationsRemoteMediator.kt index a518742d..edb5297c 100644 --- a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/notifications/NotificationsRemoteMediator.kt +++ b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/notifications/NotificationsRemoteMediator.kt @@ -23,6 +23,7 @@ import com.h.pixeldroid.utils.di.PixelfedAPIHolder import com.h.pixeldroid.utils.api.objects.Notification import retrofit2.HttpException import java.io.IOException +import java.lang.NullPointerException import javax.inject.Inject /** @@ -55,7 +56,8 @@ class NotificationsRemoteMediator @Inject constructor( } try { - val user = db.userDao().getActiveUser()!! + val user = db.userDao().getActiveUser() + ?: return MediatorResult.Error(NullPointerException("No active user exists")) val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db) val accessToken = user.accessToken diff --git a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/HomeFeedRemoteMediator.kt b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/HomeFeedRemoteMediator.kt index cde22c9d..5f626993 100644 --- a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/HomeFeedRemoteMediator.kt +++ b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/HomeFeedRemoteMediator.kt @@ -7,6 +7,7 @@ import com.h.pixeldroid.utils.di.PixelfedAPIHolder import com.h.pixeldroid.utils.db.entities.HomeStatusDatabaseEntity import retrofit2.HttpException import java.io.IOException +import java.lang.NullPointerException import javax.inject.Inject @@ -40,7 +41,8 @@ class HomeFeedRemoteMediator @Inject constructor( } try { - val user = db.userDao().getActiveUser()!! + val user = db.userDao().getActiveUser() + ?: return MediatorResult.Error(NullPointerException("No active user exists")) val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db) val accessToken = user.accessToken diff --git a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/PublicFeedRemoteMediator.kt b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/PublicFeedRemoteMediator.kt index f668105e..0d061bbd 100644 --- a/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/PublicFeedRemoteMediator.kt +++ b/app/src/main/java/com/h/pixeldroid/posts/feeds/cachedFeeds/postFeeds/PublicFeedRemoteMediator.kt @@ -23,6 +23,7 @@ import com.h.pixeldroid.utils.db.entities.PublicFeedStatusDatabaseEntity import com.h.pixeldroid.utils.di.PixelfedAPIHolder import retrofit2.HttpException import java.io.IOException +import java.lang.NullPointerException import javax.inject.Inject /** @@ -55,7 +56,8 @@ class PublicFeedRemoteMediator @Inject constructor( } try { - val user = db.userDao().getActiveUser()!! + val user = db.userDao().getActiveUser() + ?: return MediatorResult.Error(NullPointerException("No active user exists")) val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db) val apiResponse = api.timelinePublic(