Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch users #5181

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,486 changes: 3,486 additions & 0 deletions app/schemas/one.mixin.android.db.MixinDatabase/64.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/src/main/java/one/mixin/android/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ object Constants {
object DataBase {
const val DB_NAME = "mixin.db"
const val MINI_VERSION = 15
const val CURRENT_VERSION = 63
const val CURRENT_VERSION = 64

const val FTS_DB_NAME = "fts.db"
const val PENDING_DB_NAME = "pending.db"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/one/mixin/android/MixinApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import one.mixin.android.ui.web.refresh
import one.mixin.android.ui.web.releaseAll
import one.mixin.android.util.CursorWindowFixer
import one.mixin.android.util.MemoryCallback
import one.mixin.android.util.UserBatchProcessor
import one.mixin.android.util.debug.FileLogTree
import one.mixin.android.util.initNativeLibs
import one.mixin.android.util.mlkit.entityInitialize
Expand Down Expand Up @@ -296,7 +297,7 @@ open class MixinApplication :
activity.shouldLogout = true
return
}

UserBatchProcessor.getInstance().shutdown()
if (force || isOnline.compareAndSet(true, false)) {
val sessionId = Session.getSessionId()
BlazeMessageService.stopService(this)
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/one/mixin/android/db/MixinDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import one.mixin.android.db.MixinDatabaseMigrations.Companion.MIGRATION_59_60
import one.mixin.android.db.MixinDatabaseMigrations.Companion.MIGRATION_60_61
import one.mixin.android.db.MixinDatabaseMigrations.Companion.MIGRATION_61_62
import one.mixin.android.db.MixinDatabaseMigrations.Companion.MIGRATION_62_63
import one.mixin.android.db.MixinDatabaseMigrations.Companion.MIGRATION_63_64
import one.mixin.android.db.converter.DepositEntryListConverter
import one.mixin.android.db.converter.MembershipConverter
import one.mixin.android.db.converter.MessageStatusConverter
Expand Down Expand Up @@ -116,6 +117,7 @@ import one.mixin.android.vo.TopAsset
import one.mixin.android.vo.Trace
import one.mixin.android.vo.TranscriptMessage
import one.mixin.android.vo.User
import one.mixin.android.vo.UserFetchTime
import one.mixin.android.vo.market.HistoryPrice
import one.mixin.android.vo.market.Market
import one.mixin.android.vo.market.MarketCapRank
Expand Down Expand Up @@ -181,7 +183,8 @@ import kotlin.math.min
(MarketCoin::class),
(MarketFavored::class),
(Alert::class),
(MarketCapRank::class)
(MarketCapRank::class),
(UserFetchTime::class),
],
version = CURRENT_VERSION,
)
Expand Down Expand Up @@ -356,6 +359,7 @@ abstract class MixinDatabase : RoomDatabase() {
MIGRATION_60_61,
MIGRATION_61_62,
MIGRATION_62_63,
MIGRATION_63_64,
)
.enableMultiInstanceInvalidation()
.setQueryExecutor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,15 @@ class MixinDatabaseMigrations private constructor() {
db.execSQL("CREATE INDEX IF NOT EXISTS `index_pin_messages_conversation_id_created_at` ON `pin_messages` (`conversation_id`, `created_at`)")
}
}

val MIGRATION_63_64: Migration =
object : Migration(63, 64) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("CREATE TABLE IF NOT EXISTS `user_fetch_times` (`user_id` TEXT NOT NULL, `last_fetch_at` INTEGER NOT NULL, PRIMARY KEY(`user_id`))")
db.execSQL("ALTER TABLE `raw_transactions` ADD COLUMN `transaction_hash` TEXT")
db.execSQL("CREATE INDEX IF NOT EXISTS `index_raw_transactions_transaction_hash` ON `raw_transactions` (`transaction_hash`)")
}
}
// If you add a new table, be sure to add a clear method to the DatabaseUtil
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/one/mixin/android/db/UserDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package one.mixin.android.db

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.RoomWarnings
import androidx.room.Transaction
Expand All @@ -12,6 +14,7 @@ import one.mixin.android.vo.CallUser
import one.mixin.android.vo.ForwardUser
import one.mixin.android.vo.MentionUser
import one.mixin.android.vo.User
import one.mixin.android.vo.UserFetchTime
import one.mixin.android.vo.UserItem

@Dao
Expand All @@ -29,6 +32,7 @@ interface UserDao : BaseDao<User> {
user.relationship = relationship
update(user)
}
insertFetch(UserFetchTime(user.userId, System.currentTimeMillis()))
}

@Transaction
Expand All @@ -45,6 +49,10 @@ interface UserDao : BaseDao<User> {
}
appDao.insertList(apps)
insertList(users)
val currentTime = System.currentTimeMillis()
insertAllFetch(users.map { user ->
UserFetchTime(user.userId, currentTime)
})
}

@Transaction
Expand All @@ -62,8 +70,22 @@ interface UserDao : BaseDao<User> {
} else {
update(user)
}
insertFetch(UserFetchTime(user.userId, System.currentTimeMillis()))
}

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertFetch(userFetchTime: UserFetchTime)

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAllFetch(userFetchTimes: List<UserFetchTime>)

@Query("""
SELECT user_id FROM user_fetch_times
WHERE user_id IN (:userIds)
AND (strftime('%s','now') - last_fetch_at) < 24 * 60 * 60 * 1000
""")
suspend fun filterUserIdsNotFetchedIn24Hours(userIds: List<String>): List<String>

@Query("SELECT * FROM users WHERE relationship = 'FRIEND' ORDER BY full_name, identity_number ASC")
fun findFriends(): LiveData<List<User>>

Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/one/mixin/android/job/RestoreTransactionJob.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ class RestoreTransactionJob : BaseJob(
Timber.e("Restore Transaction(${transaction.requestId}): db begin")
runInTransaction {
Timber.e("Restore Transaction(${transaction.requestId}): update raw transaction ${transaction.requestId}")
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.spent.name)
Timber.e("Restore Transaction(${transaction.requestId}): update raw transaction $feeTraceId")
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.spent.name)
}
Timber.e("Restore Transaction(${transaction.requestId}): db end")
if (feeTransaction == null) {
Expand All @@ -83,9 +83,9 @@ class RestoreTransactionJob : BaseJob(
Timber.e("Restore Transaction(${transaction.requestId}): db begin")
runInTransaction {
Timber.e("Restore Transaction(${transaction.requestId}): update raw transaction ${transaction.requestId}")
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.spent.name)
Timber.e("Restore Transaction(${transaction.requestId}): update raw transaction $feeTraceId")
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.spent.name)
}
Timber.e("Restore Transaction(${transaction.requestId}): db end")
if (feeTransaction == null && transaction.receiverId.isNotBlank()) {
Expand All @@ -94,8 +94,8 @@ class RestoreTransactionJob : BaseJob(
} else {
Timber.e("Restore Transaction(${transaction.requestId}): Post Transaction Error ${transactionRsp.errorDescription}")
reportException(e = Throwable("Transaction Error ${transactionRsp.errorDescription}"))
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.signed.name)
rawTransactionDao.updateRawTransaction(transaction.requestId, OutputState.spent.name)
rawTransactionDao.updateRawTransaction(feeTraceId, OutputState.spent.name)
}
jobManager.addJobInBackground(SyncOutputJob())
} else if (response.errorCode >= 500) {
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/java/one/mixin/android/job/UserBatchProcessorJob.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package one.mixin.android.job

import com.birbit.android.jobqueue.Params
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.util.concurrent.TimeUnit

class UserBatchProcessorJob(
private val userIds: List<String>
) : BaseJob(Params(PRIORITY_UI_HIGH).addTags(GROUP).requireNetwork().persist()) {

companion object {
private const val serialVersionUID = 1L
private const val GROUP = "UserBatchProcessorJob"
private const val FETCH_INTERVAL_HOURS = 24L
}

override fun onRun() = runBlocking {
val filterId = userDao.filterUserIdsNotFetchedIn24Hours(userIds)
(userIds - filterId).let { ids ->
if (ids.isNotEmpty()) {
jobManager.addJobInBackground(RefreshUserJob(ids, forceRefresh = true))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package one.mixin.android.ui.common
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.protobuf.Mixin
import dagger.hilt.android.lifecycle.HiltViewModel
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
Expand Down Expand Up @@ -74,7 +73,6 @@ import one.mixin.android.util.uniqueObjectId
import one.mixin.android.vo.Account
import one.mixin.android.vo.Address
import one.mixin.android.vo.AddressItem
import one.mixin.android.vo.App
import one.mixin.android.vo.AssetPrecision
import one.mixin.android.vo.Circle
import one.mixin.android.vo.CircleConversation
Expand Down Expand Up @@ -306,9 +304,9 @@ class BottomSheetViewModel
Timber.e("Kernel Withdrawal($traceId): db insert fee snapshot")
tokenRepository.insertSafeSnapshot(UUID.nameUUIDFromBytes("$senderId:$feeTransactionHash".toByteArray()).toString(), senderId, receiverId, feeTransactionHash, feeTraceId, feeAssetId, feeAmount, "", SafeSnapshotType.snapshot)
Timber.e("Kernel Withdrawal($traceId): db raw transaction")
tokenRepository.insetRawTransaction(RawTransaction(withdrawalData.requestId, signWithdrawalResult.raw, formatDestination(destination, tag), RawTransactionType.WITHDRAWAL, OutputState.unspent, nowInUtc(), withdrawalUtxos.inscriptionHash))
tokenRepository.insetRawTransaction(RawTransaction(withdrawalData.requestId, signWithdrawalResult.raw, formatDestination(destination, tag), RawTransactionType.WITHDRAWAL, OutputState.unspent, nowInUtc(), withdrawalUtxos.inscriptionHash, transactionHash))
Timber.e("Kernel Withdrawal($traceId): db insert fee raw transaction")
tokenRepository.insetRawTransaction(RawTransaction(feeData.requestId, signFeeResult.raw, receiverId, RawTransactionType.FEE, OutputState.unspent, nowInUtc(), null))
tokenRepository.insetRawTransaction(RawTransaction(feeData.requestId, signFeeResult.raw, receiverId, RawTransactionType.FEE, OutputState.unspent, nowInUtc(), null, transactionHash))
}
Timber.e("Kernel Withdrawal($traceId): db end")
jobManager.addJobInBackground(CheckBalanceJob(arrayListOf(assetIdToAsset(assetId), assetIdToAsset(feeAssetId))))
Expand Down Expand Up @@ -341,7 +339,7 @@ class BottomSheetViewModel
),
)
Timber.e("Kernel Withdrawal($traceId): db update raw transaction")
tokenRepository.insetRawTransaction(RawTransaction(withdrawalData.requestId, signWithdrawalResult.raw, formatDestination(destination, tag), RawTransactionType.WITHDRAWAL, OutputState.unspent, nowInUtc(), withdrawalUtxos.inscriptionHash))
tokenRepository.insetRawTransaction(RawTransaction(withdrawalData.requestId, signWithdrawalResult.raw, formatDestination(destination, tag), RawTransactionType.WITHDRAWAL, OutputState.unspent, nowInUtc(), withdrawalUtxos.inscriptionHash, transactionHash))
}
Timber.e("Kernel Withdrawal($traceId): db end")
jobManager.addJobInBackground(CheckBalanceJob(arrayListOf(assetIdToAsset(assetId))))
Expand All @@ -357,12 +355,12 @@ class BottomSheetViewModel
if (transactionRsp.error != null) {
Timber.e("Kernel Withdrawal($traceId): withdrawal error ${transactionRsp.errorDescription}")
reportException(Throwable("Transaction Error ${transactionRsp.errorDescription}"))
tokenRepository.updateRawTransaction(traceId, OutputState.signed.name)
tokenRepository.updateRawTransaction(feeTraceId, OutputState.signed.name)
tokenRepository.updateRawTransaction(traceId, OutputState.spent.name)
tokenRepository.updateRawTransaction(feeTraceId, OutputState.spent.name)
return transactionRsp
} else {
tokenRepository.updateRawTransaction(traceId, OutputState.signed.name)
tokenRepository.updateRawTransaction(feeTraceId, OutputState.signed.name)
tokenRepository.updateRawTransaction(traceId, OutputState.spent.name)
tokenRepository.updateRawTransaction(feeTraceId, OutputState.spent.name)
}
jobManager.addJobInBackground(SyncOutputJob())
Timber.e("Kernel Withdrawal($traceId): withdrawal end")
Expand Down Expand Up @@ -435,7 +433,7 @@ class BottomSheetViewModel
Timber.e("Kernel Address Transaction($trace): sign db insert snapshot")
tokenRepository.insertSafeSnapshot(UUID.nameUUIDFromBytes("$senderId:$transactionHash".toByteArray()).toString(), senderId, kernelAddress, transactionHash, trace, assetId, amount, memo, SafeSnapshotType.snapshot, reference = reference)
Timber.e("Kernel Address Transaction($trace): sign db insert raw transaction")
tokenRepository.insetRawTransaction(RawTransaction(transactionResponse.data!!.first().requestId, signResult.raw, "", RawTransactionType.TRANSFER, OutputState.unspent, nowInUtc(), utxoWrapper.inscriptionHash))
tokenRepository.insetRawTransaction(RawTransaction(transactionResponse.data!!.first().requestId, signResult.raw, "", RawTransactionType.TRANSFER, OutputState.unspent, nowInUtc(), utxoWrapper.inscriptionHash, transactionHash))
Timber.e("Kernel Address Transaction($trace): sign db mark utxo ${utxoWrapper.ids.joinToString(", ")}")
tokenRepository.updateUtxoToSigned(utxoWrapper.ids)
Timber.e("Kernel Address Transaction: sign end")
Expand Down Expand Up @@ -530,8 +528,13 @@ class BottomSheetViewModel
Timber.e("Kernel Transaction($trace): sign db insert snapshot")
tokenRepository.insertSafeSnapshot(UUID.nameUUIDFromBytes("${senderIds.first()}:$transactionHash".toByteArray()).toString(), senderIds.first(), opponentId, transactionHash, trace, assetId, amount, memo, SafeSnapshotType.snapshot, reference = reference ?: (if (release == true) null else inscriptionHash))
}
val transactionHash = if (!isConsolidation) {
sign.hash
} else {
null
}
Timber.e("Kernel Transaction($trace): sign db insert raw transaction")
tokenRepository.insetRawTransaction(RawTransaction(transactionResponse.data!!.first().requestId, signResult.raw, receiverIds.joinToString(","), RawTransactionType.TRANSFER, OutputState.unspent, nowInUtc(), if (release == true) null else utxoWrapper.inscriptionHash))
tokenRepository.insetRawTransaction(RawTransaction(transactionResponse.data!!.first().requestId, signResult.raw, receiverIds.joinToString(","), RawTransactionType.TRANSFER, OutputState.unspent, nowInUtc(), if (release == true) null else utxoWrapper.inscriptionHash, transactionHash))
Timber.e("Kernel Transaction($trace): sign db mark utxo ${utxoWrapper.ids.joinToString(", ")}")
tokenRepository.updateUtxoToSigned(utxoWrapper.ids)
Timber.e("Kernel Transaction: sign end")
Expand Down Expand Up @@ -561,11 +564,11 @@ class BottomSheetViewModel
if (transactionRsp.error != null) {
Timber.e("Kernel Transaction($traceId): innerTransaction error ${transactionRsp.errorDescription}")
reportException(Throwable("Transaction Error ${transactionRsp.errorDescription}"))
tokenRepository.updateRawTransaction(transactionRsp.data!!.first().requestId, OutputState.signed.name)
tokenRepository.updateRawTransaction(transactionRsp.data!!.first().requestId, OutputState.spent.name)
return transactionRsp
} else {
Timber.e("Kernel Transaction($traceId): innerTransaction update raw transaction")
tokenRepository.updateRawTransaction(transactionRsp.data!!.first().requestId, OutputState.signed.name)
tokenRepository.updateRawTransaction(transactionRsp.data!!.first().requestId, OutputState.spent.name)
}
if (receiverIds.size == 1 && !isConsolidation) {
// Workaround with only the case of a single transfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.launch
import one.mixin.android.R
import one.mixin.android.extension.replaceFragment
import one.mixin.android.job.MixinJobManager
import one.mixin.android.repository.ConversationRepository
import one.mixin.android.repository.UserRepository
import one.mixin.android.session.Session
Expand All @@ -20,6 +21,7 @@ import one.mixin.android.ui.conversation.ConversationFragment.Companion.CONVERSA
import one.mixin.android.ui.conversation.ConversationFragment.Companion.RECIPIENT
import one.mixin.android.ui.conversation.ConversationFragment.Companion.RECIPIENT_ID
import one.mixin.android.ui.home.MainActivity
import one.mixin.android.util.UserBatchProcessor
import one.mixin.android.vo.TranscriptData
import one.mixin.android.vo.User
import javax.inject.Inject
Expand All @@ -30,6 +32,7 @@ class ConversationActivity : BlazeBaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
WindowCompat.setDecorFitsSystemWindows(window, false)
UserBatchProcessor.getInstance().init(jobManager)
if (savedInstanceState == null) {
if (intent.getBooleanExtra(ARGS_FAST_SHOW, false)) {
replaceFragment(
Expand Down Expand Up @@ -62,6 +65,9 @@ class ConversationActivity : BlazeBaseActivity() {
@Inject
lateinit var userRepository: UserRepository

@Inject
lateinit var jobManager: MixinJobManager

private fun showConversation(intent: Intent) {
val bundle = intent.extras ?: return
lifecycleScope.launch(
Expand Down
Loading
Loading