cleanup code, fix some todos

This commit is contained in:
Konrad Pozniak 2020-09-29 20:24:02 +02:00
parent e07211a14d
commit 9ff3f9372a
22 changed files with 49 additions and 153 deletions

View File

@ -22,7 +22,6 @@ package at.connyduck.pixelcat.components.about.licenses
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.annotation.RawRes import androidx.annotation.RawRes
@ -33,7 +32,6 @@ import at.connyduck.pixelcat.R
import at.connyduck.pixelcat.components.general.BaseActivity import at.connyduck.pixelcat.components.general.BaseActivity
import at.connyduck.pixelcat.databinding.ActivityLicenseBinding import at.connyduck.pixelcat.databinding.ActivityLicenseBinding
import java.io.BufferedReader import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader import java.io.InputStreamReader
class LicenseActivity : BaseActivity() { class LicenseActivity : BaseActivity() {
@ -62,24 +60,16 @@ class LicenseActivity : BaseActivity() {
private fun loadFileIntoTextView(@RawRes fileId: Int, textView: TextView) { private fun loadFileIntoTextView(@RawRes fileId: Int, textView: TextView) {
val sb = StringBuilder() textView.text = buildString {
BufferedReader(InputStreamReader(resources.openRawResource(fileId))).use { br ->
val br = BufferedReader(InputStreamReader(resources.openRawResource(fileId))) var line: String? = br.readLine()
while (line != null) {
try { append(line)
var line: String? = br.readLine() append('\n')
while (line != null) { line = br.readLine()
sb.append(line) }
sb.append('\n')
line = br.readLine()
} }
} catch (e: IOException) {
Log.w("LicenseActivity", e)
} }
br.close()
textView.text = sb.toString()
} }
companion object { companion object {

View File

@ -29,6 +29,7 @@ import at.connyduck.pixelcat.components.login.LoginActivity
import at.connyduck.pixelcat.components.main.MainActivity import at.connyduck.pixelcat.components.main.MainActivity
import at.connyduck.pixelcat.databinding.BottomsheetAccountsBinding import at.connyduck.pixelcat.databinding.BottomsheetAccountsBinding
import at.connyduck.pixelcat.db.AccountManager import at.connyduck.pixelcat.db.AccountManager
import at.connyduck.pixelcat.util.viewBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -36,22 +37,18 @@ class AccountSelectionBottomSheet(
private val accountManager: AccountManager private val accountManager: AccountManager
) : BottomSheetDialogFragment() { ) : BottomSheetDialogFragment() {
private var _binding: BottomsheetAccountsBinding? = null private val binding by viewBinding(BottomsheetAccountsBinding::bind)
private val binding
get() = _binding!!
override fun onCreateView( override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = binding.root
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = BottomsheetAccountsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
lifecycleScope.launch { lifecycleScope.launch {
binding.accountsRecyclerView.adapter = AccountSelectionAdapter(accountManager.getAllAccounts(), ::onAccountSelected, ::onNewAccount) binding.accountsRecyclerView.adapter =
AccountSelectionAdapter(
accountManager.getAllAccounts(),
::onAccountSelected,
::onNewAccount
)
} }
} }
@ -67,12 +64,6 @@ class AccountSelectionBottomSheet(
} }
private fun onNewAccount() { private fun onNewAccount() {
// TODO don't create intent here startActivity(LoginActivity.newIntent(requireContext()))
startActivity(Intent(requireContext(), LoginActivity::class.java))
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
} }
} }

View File

@ -26,22 +26,18 @@ import android.view.ViewGroup
import at.connyduck.pixelcat.components.about.AboutActivity import at.connyduck.pixelcat.components.about.AboutActivity
import at.connyduck.pixelcat.components.settings.SettingsActivity import at.connyduck.pixelcat.components.settings.SettingsActivity
import at.connyduck.pixelcat.databinding.BottomsheetMenuBinding import at.connyduck.pixelcat.databinding.BottomsheetMenuBinding
import at.connyduck.pixelcat.util.viewBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class MenuBottomSheet : BottomSheetDialogFragment() { class MenuBottomSheet : BottomSheetDialogFragment() {
private var _binding: BottomsheetMenuBinding? = null private val binding by viewBinding(BottomsheetMenuBinding::bind)
private val binding
get() = _binding!!
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ) = binding.root
_binding = BottomsheetMenuBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -54,9 +50,4 @@ class MenuBottomSheet : BottomSheetDialogFragment() {
dismiss() dismiss()
} }
} }
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
} }

View File

@ -37,7 +37,7 @@ import javax.inject.Inject
@FlowPreview @FlowPreview
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
class LoginViewModel @Inject constructor( class LoginViewModel @Inject constructor(
private val fediverseApi: FediverseApi, private val api: FediverseApi,
private val accountManager: AccountManager private val accountManager: AccountManager
) : ViewModel() { ) : ViewModel() {
@ -67,7 +67,7 @@ class LoginViewModel @Inject constructor(
loginState.send(LoginModel(input, LoginState.LOADING)) loginState.send(LoginModel(input, LoginState.LOADING))
fediverseApi.authenticateAppAsync( api.authenticateAppAsync(
domain = domainInput, domain = domainInput,
clientName = "Pixelcat", clientName = "Pixelcat",
clientWebsite = Config.website, clientWebsite = Config.website,
@ -88,7 +88,7 @@ class LoginViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
val loginModel = loginState.value val loginModel = loginState.value
fediverseApi.fetchOAuthToken( api.fetchOAuthToken(
domain = loginModel.domain!!, domain = loginModel.domain!!,
clientId = loginModel.clientId!!, clientId = loginModel.clientId!!,
clientSecret = loginModel.clientSecret!!, clientSecret = loginModel.clientSecret!!,

View File

@ -35,9 +35,7 @@ class MainFragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAda
1 -> SearchFragment.newInstance() 1 -> SearchFragment.newInstance()
2 -> NotificationsFragment.newInstance() 2 -> NotificationsFragment.newInstance()
3 -> ProfileFragment.newInstance() 3 -> ProfileFragment.newInstance()
else -> { else -> throw IllegalStateException()
throw IllegalStateException()
}
} }
} }

View File

@ -27,7 +27,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class MainViewModel @Inject constructor( class MainViewModel @Inject constructor(
private val fediverseApi: FediverseApi, private val api: FediverseApi,
private val accountManager: AccountManager private val accountManager: AccountManager
) : ViewModel() { ) : ViewModel() {
@ -37,7 +37,7 @@ class MainViewModel @Inject constructor(
init { init {
viewModelScope.launch { viewModelScope.launch {
fediverseApi.accountVerifyCredentials().fold( api.accountVerifyCredentials().fold(
{ account -> { account ->
accountManager.updateActiveAccount(account) accountManager.updateActiveAccount(account)
}, },

View File

@ -36,7 +36,7 @@ import javax.inject.Inject
class NotificationsViewModel @Inject constructor( class NotificationsViewModel @Inject constructor(
accountManager: AccountManager, accountManager: AccountManager,
private val db: AppDatabase, private val db: AppDatabase,
private val fediverseApi: FediverseApi private val api: FediverseApi
) : ViewModel() { ) : ViewModel() {
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class)
@ -45,7 +45,7 @@ class NotificationsViewModel @Inject constructor(
.flatMapConcat { activeAccount -> .flatMapConcat { activeAccount ->
Pager( Pager(
config = PagingConfig(pageSize = 10, enablePlaceholders = false), config = PagingConfig(pageSize = 10, enablePlaceholders = false),
remoteMediator = NotificationsRemoteMediator(activeAccount?.id!!, fediverseApi, db), remoteMediator = NotificationsRemoteMediator(activeAccount?.id!!, api, db),
pagingSourceFactory = { db.notificationsDao().notifications(activeAccount.id) } pagingSourceFactory = { db.notificationsDao().notifications(activeAccount.id) }
).flow ).flow
} }

View File

@ -43,7 +43,7 @@ class GridSpacingItemDecoration(
outRect.left = column * spacing / spanCount // column * ((1f / spanCount) * spacing) outRect.left = column * spacing / spanCount // column * ((1f / spanCount) * spacing)
outRect.right = outRect.right =
spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing) spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position - topOffset >= spanCount) { if (position - topOffset >= spanCount) {
outRect.top = spacing // item top outRect.top = spacing // item top
} }

View File

@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class ProfileViewModel @Inject constructor( class ProfileViewModel @Inject constructor(
private val fediverseApi: FediverseApi, private val api: FediverseApi,
private val accountManager: AccountManager private val accountManager: AccountManager
) : ViewModel() { ) : ViewModel() {
@ -49,7 +49,7 @@ class ProfileViewModel @Inject constructor(
@ExperimentalPagingApi @ExperimentalPagingApi
val imageFlow = Pager( val imageFlow = Pager(
config = PagingConfig(pageSize = 10, enablePlaceholders = false), config = PagingConfig(pageSize = 10, enablePlaceholders = false),
pagingSourceFactory = { ProfileImagePagingSource(fediverseApi, accountId, accountManager) } pagingSourceFactory = { ProfileImagePagingSource(api, accountId, accountManager) }
).flow ).flow
.cachedIn(viewModelScope) .cachedIn(viewModelScope)
@ -73,7 +73,7 @@ class ProfileViewModel @Inject constructor(
private fun loadAccount(reload: Boolean = false) { private fun loadAccount(reload: Boolean = false) {
if (profile.value == null || reload) { if (profile.value == null || reload) {
viewModelScope.launch { viewModelScope.launch {
fediverseApi.account(getAccountId()).fold( api.account(getAccountId()).fold(
{ {
profile.value = Success(it) profile.value = Success(it)
}, },
@ -88,7 +88,7 @@ class ProfileViewModel @Inject constructor(
private fun loadRelationship(reload: Boolean = false) { private fun loadRelationship(reload: Boolean = false) {
if (relationship.value == null || reload) { if (relationship.value == null || reload) {
viewModelScope.launch { viewModelScope.launch {
fediverseApi.relationships(listOf(getAccountId())).fold( api.relationships(listOf(getAccountId())).fold(
{ {
relationship.value = Success(it.first()) relationship.value = Success(it.first())
}, },

View File

@ -29,6 +29,7 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsCompat.Type.systemBars import androidx.core.view.WindowInsetsCompat.Type.systemBars
import androidx.fragment.app.commit
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import at.connyduck.pixelcat.R import at.connyduck.pixelcat.R
import at.connyduck.pixelcat.components.general.BaseActivity import at.connyduck.pixelcat.components.general.BaseActivity
@ -56,10 +57,9 @@ class SettingsActivity : BaseActivity(), SharedPreferences.OnSharedPreferenceCha
WindowInsetsCompat.CONSUMED WindowInsetsCompat.CONSUMED
} }
supportFragmentManager supportFragmentManager.commit {
.beginTransaction() replace(R.id.settings, SettingsFragment())
.replace(R.id.settings, SettingsFragment()) }
.commit()
binding.settingsToolbar.setNavigationOnClickListener { binding.settingsToolbar.setNavigationOnClickListener {
onBackPressed() onBackPressed()

View File

@ -42,7 +42,6 @@ class TimelineImageAdapter : RecyclerView.Adapter<BindingHolder<ItemTimelineImag
override fun getItemCount() = images.size override fun getItemCount() = images.size
override fun onBindViewHolder(holder: BindingHolder<ItemTimelineImageBinding>, position: Int) { override fun onBindViewHolder(holder: BindingHolder<ItemTimelineImageBinding>, position: Int) {
holder.binding.timelineImageView.load(images[position].previewUrl) holder.binding.timelineImageView.load(images[position].previewUrl)
} }
} }

View File

@ -38,7 +38,7 @@ import javax.inject.Inject
class TimelineViewModel @Inject constructor( class TimelineViewModel @Inject constructor(
accountManager: AccountManager, accountManager: AccountManager,
private val db: AppDatabase, private val db: AppDatabase,
private val fediverseApi: FediverseApi, private val api: FediverseApi,
private val useCases: TimelineUseCases private val useCases: TimelineUseCases
) : ViewModel() { ) : ViewModel() {
@ -48,7 +48,7 @@ class TimelineViewModel @Inject constructor(
.flatMapConcat { activeAccount -> .flatMapConcat { activeAccount ->
Pager( Pager(
config = PagingConfig(pageSize = 10, enablePlaceholders = false), config = PagingConfig(pageSize = 10, enablePlaceholders = false),
remoteMediator = TimelineRemoteMediator(activeAccount?.id!!, fediverseApi, db), remoteMediator = TimelineRemoteMediator(activeAccount?.id!!, api, db),
pagingSourceFactory = { db.statusDao().statuses(activeAccount.id) } pagingSourceFactory = { db.statusDao().statuses(activeAccount.id) }
).flow ).flow
} }

View File

@ -41,8 +41,7 @@ class DetailViewModel @Inject constructor(
private val api: FediverseApi, private val api: FediverseApi,
private val db: AppDatabase, private val db: AppDatabase,
private val accountManager: AccountManager, private val accountManager: AccountManager,
private val useCases: TimelineUseCases, private val useCases: TimelineUseCases
private val fediverseApi: FediverseApi
) : ViewModel() { ) : ViewModel() {
val currentStatus = MutableLiveData<UiState<StatusEntity>>() val currentStatus = MutableLiveData<UiState<StatusEntity>>()
@ -129,7 +128,7 @@ class DetailViewModel @Inject constructor(
fun onReply(statusToReply: StatusEntity, replyText: String) { fun onReply(statusToReply: StatusEntity, replyText: String) {
viewModelScope.launch { viewModelScope.launch {
fediverseApi.reply( api.reply(
NewStatus( NewStatus(
status = replyText, status = replyText,
inReplyToId = statusToReply.actionableId, inReplyToId = statusToReply.actionableId,

View File

@ -34,6 +34,7 @@ fun Context.getDisplayWidthInPx(): Int {
windowManager.currentWindowMetrics.bounds.width() windowManager.currentWindowMetrics.bounds.width()
} else { } else {
val metrics = DisplayMetrics() val metrics = DisplayMetrics()
@Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(metrics) windowManager.defaultDisplay.getMetrics(metrics)
metrics.widthPixels metrics.widthPixels
} }

View File

@ -35,10 +35,9 @@ class StatusView @JvmOverloads constructor(
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) { ) : LinearLayout(context, attrs, defStyleAttr) {
val binding: ViewStatusBinding val binding: ViewStatusBinding = ViewStatusBinding.inflate(LayoutInflater.from(context), this)
init { init {
binding = ViewStatusBinding.inflate(LayoutInflater.from(context), this)
gravity = Gravity.CENTER gravity = Gravity.CENTER
setBackgroundColor(context.getColorForAttr(R.attr.colorSurface)) setBackgroundColor(context.getColorForAttr(R.attr.colorSurface))
orientation = VERTICAL orientation = VERTICAL

View File

@ -26,11 +26,8 @@ import at.connyduck.pixelcat.model.Account
/** /**
* This class caches the account database and handles all account related operations * This class caches the account database and handles all account related operations
* @author ConnyDuck
*/ */
// TODO check if the comments are up to date
private const val TAG = "AccountManager" private const val TAG = "AccountManager"
class AccountManager(db: AppDatabase) { class AccountManager(db: AppDatabase) {
@ -55,8 +52,8 @@ class AccountManager(db: AppDatabase) {
* Adds a new empty account and makes it the active account. * Adds a new empty account and makes it the active account.
* More account information has to be added later with [updateActiveAccount] * More account information has to be added later with [updateActiveAccount]
* or the account wont be saved to the database. * or the account wont be saved to the database.
* @param accessToken the access token for the new account * @param domain the domain of the accounts instance
* @param domain the domain of the accounts Mastodon instance * @param authData the auth data of the new account
*/ */
suspend fun addAccount(domain: String, authData: AccountAuthData) { suspend fun addAccount(domain: String, authData: AccountAuthData) {
@ -114,8 +111,7 @@ class AccountManager(db: AppDatabase) {
} }
/** /**
* updates the current account with new information from the mastodon api * updates the current account with new information from the api and saves it in the database
* and saves it in the database
* @param account the [Account] object returned from the api * @param account the [Account] object returned from the api
*/ */
suspend fun updateActiveAccount(account: Account) { suspend fun updateActiveAccount(account: Account) {
@ -124,9 +120,6 @@ class AccountManager(db: AppDatabase) {
it.username = account.username it.username = account.username
it.displayName = account.name it.displayName = account.name
it.profilePictureUrl = account.avatar it.profilePictureUrl = account.avatar
// it.defaultPostPrivacy = account.source?.privacy ?: Status.Visibility.PUBLIC
it.defaultMediaSensitivity = account.source?.sensitive ?: false
// it.emojis = account.emojis ?: emptyList()
Log.d(TAG, "updateActiveAccount: saving account with id " + it.id) Log.d(TAG, "updateActiveAccount: saving account with id " + it.id)
it.id = accountDao.insertOrReplace(it) it.id = accountDao.insertOrReplace(it)
@ -166,7 +159,7 @@ class AccountManager(db: AppDatabase) {
} }
/** /**
* @return an immutable list of all accounts in the database with the active account first * @return an immutable list of all accounts in the database
*/ */
suspend fun getAllAccounts(): List<AccountEntity> { suspend fun getAllAccounts(): List<AccountEntity> {
@ -180,13 +173,6 @@ class AccountManager(db: AppDatabase) {
return accounts.toList() return accounts.toList()
} }
/**
* @return true if at least one account has notifications enabled
*/
fun areNotificationsEnabled(): Boolean {
return accounts.any { it.notificationsEnabled }
}
/** /**
* Finds an account by its database id * Finds an account by its database id
* @param accountId the id of the account * @param accountId the id of the account

View File

@ -32,7 +32,6 @@ import androidx.room.PrimaryKey
) )
] ]
) )
// @TypeConverters(Converters::class)
data class AccountEntity( data class AccountEntity(
@field:PrimaryKey(autoGenerate = true) var id: Long, @field:PrimaryKey(autoGenerate = true) var id: Long,
val domain: String, val domain: String,
@ -41,21 +40,7 @@ data class AccountEntity(
var accountId: String = "", var accountId: String = "",
var username: String = "", var username: String = "",
var displayName: String = "", var displayName: String = "",
var profilePictureUrl: String = "", var profilePictureUrl: String = ""
var notificationsEnabled: Boolean = true,
var notificationsMentioned: Boolean = true,
var notificationsFollowed: Boolean = true,
var notificationsReblogged: Boolean = true,
var notificationsFavorited: Boolean = true,
var notificationSound: Boolean = true,
var notificationVibration: Boolean = true,
var notificationLight: Boolean = true,
var defaultMediaSensitivity: Boolean = false,
var alwaysShowSensitiveMedia: Boolean = false,
var mediaPreviewEnabled: Boolean = true,
var lastNotificationId: String = "0",
var activeNotifications: String = "[]",
var notificationsFilter: String = "[]"
) { ) {
val identifier: String val identifier: String

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
</vector>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
</menu>

View File

@ -1,12 +0,0 @@
<resources>
<!-- Reply Preference -->
<string-array name="reply_entries">
<item>Reply</item>
<item>Reply to all</item>
</string-array>
<string-array name="reply_values">
<item>reply</item>
<item>reply_all</item>
</string-array>
</resources>