Make sure that clicking Notifications does have an active login

Took 25 minutes
master
MTRNord 2019-03-16 20:47:50 +01:00
parent f5648d0b69
commit 27d137a383
No known key found for this signature in database
GPG Key ID: E5B89311FAB91B9F
17 changed files with 149 additions and 129 deletions

View File

@ -42,12 +42,13 @@ class Matrix : KoinComponent {
context.hsBaseUrl = url
context.initialDeviceName = "SimpleMatrix"
account.client = MatrixHttpClient(context, okHttpClient)
account.id = mxid.id
val credentials = MatrixPasswordCredentials(mxid.localPart, password)
try {
account.client.context?.initialDeviceName = "SimpleMatrix"
account.client.login(credentials)
account.client?.context?.initialDeviceName = "SimpleMatrix"
account.client?.login(credentials)
} catch (e: MatrixClientRequestException) {
if (e.cause is UnknownHostException) {
status = State.Error
@ -83,9 +84,10 @@ class Matrix : KoinComponent {
context.initialDeviceName = "SimpleMatrix"
context.domain = mxid.domain
account.client = MatrixHttpClient(context, okHttpClient)
account.id = mxid.id
try {
account.client.discoverSettings()
account.client?.discoverSettings()
} catch (e: IllegalStateException) {
if (e.message == "No valid Homeserver base URL was found") {
status = State.Error
@ -96,7 +98,7 @@ class Matrix : KoinComponent {
val credentials = MatrixPasswordCredentials(mxid.localPart, password)
try {
account.client.login(credentials)
account.client?.login(credentials)
} catch (e: MatrixClientRequestException) {
if (e.cause is UnknownHostException) {
status = State.Error
@ -139,6 +141,7 @@ class Matrix : KoinComponent {
context.setUser(mxid)
context.token = token
account.client = MatrixHttpClient(context, okHttpClient)
account.id = mxid.id
status = State.LoggedIn
account.status = status
callback()

View File

@ -11,6 +11,7 @@ import io.kamax.matrix.json.GsonUtil
*/
class Account {
var status: Matrix.State = Matrix.State.Uninitialized
var id: String = ""
val initialSyncFilter: String by lazy {
val timeline = JsonObject()
@ -45,5 +46,5 @@ class Account {
GsonUtil.get().toJson(filter)
}
lateinit var client: MatrixHttpClient
var client: MatrixHttpClient? = null
}

View File

@ -20,7 +20,7 @@ class SDKAppModule() {
single<Api.MatrixService> {
val account: Account = get()
val retrofit = Retrofit.Builder()
.baseUrl(account.client.context?.hsBaseUrl?.toString()!!)
.baseUrl(account.client?.context?.hsBaseUrl?.toString()!!)
.addConverterFactory(GsonConverterFactory.create())
.build()

View File

@ -35,7 +35,7 @@ class FCMHelper : KoinComponent {
val json = GsonUtil.makeObj(data)
doAsync {
account.client.setPusher(json)
account.client?.setPusher(json)
}
}

View File

@ -19,27 +19,15 @@
package blog.nordgedanken.simplematrix
import android.Manifest
import android.accounts.Account
import android.accounts.AccountManager
import android.accounts.AccountManagerCallback
import android.accounts.AccountManagerFuture
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import blog.nordgedanken.matrix_android_sdk.Matrix
import blog.nordgedanken.simplematrix.accounts.MatrixAccountAuthenticator
import blog.nordgedanken.simplematrix.fcm.FCMHelper
import blog.nordgedanken.simplematrix.roomView.RoomsActivity
import blog.nordgedanken.simplematrix.utils.Accounts
import com.orhanobut.logger.Logger
import io.kamax.matrix.MatrixID
import io.sentry.Sentry
import io.sentry.event.BreadcrumbBuilder
import org.jetbrains.anko.doAsync
import org.koin.android.ext.android.inject
/**
* Main Entry Activity.
@ -52,15 +40,6 @@ import org.koin.android.ext.android.inject
*
*/
class MainActivity : AppCompatActivity() {
/**
* Account manager is needed to work with Android Accounts
*/
val am: AccountManager by inject()
/**
* Holds any available Accounts
*/
val accounts: Array<Account> by inject()
companion object {
/**
@ -81,77 +60,10 @@ class MainActivity : AppCompatActivity() {
permissions()
checkAccounts()
Accounts(this, Intent(this, RoomsActivity::class.java)).checkAccounts()
}
/**
* Checks the [blog.nordgedanken.simplematrix.MainActivity.accounts] Array for existing Accounts
* of the type org.matrix.
*
* If No accounts are present in the Array aka. it is Empty it launches a new Login Request.
* Else it uses the first account in the Array to login with.
*
* TODO Make this Multi Account Capable
*/
private fun checkAccounts() {
if (accounts.isEmpty()) {
firstLogin = true
Sentry.getContext().recordBreadcrumb(
BreadcrumbBuilder().setMessage("First login").build()
)
am.addAccount("org.matrix", "token", null, Bundle(), this, OnTokenAcquired(), null)
} else {
// TODO rework to show available Accounts to the User and let him choose
am.getAuthToken(accounts[0], MatrixAccountAuthenticator.TOKEN_TYPE, null, false, OnTokenAcquired(), null)
}
}
private inner class OnTokenAcquired : AccountManagerCallback<Bundle> {
override fun run(result: AccountManagerFuture<Bundle>?) {
Logger.d("login")
findViewById<blog.nordgedanken.simplematrix.utils.ui.ProgressBar>(R.id.load_progress).visibility = View.VISIBLE
if (result !== null) {
val bundle: Bundle? = try {
result.result
} catch (e: Exception) {
Sentry.capture(e)
null
}
val launch = bundle?.get(AccountManager.KEY_INTENT) as? Intent
if (launch != null) {
startActivityForResult(launch, 0)
} else {
doAsync {
if (!firstLogin) {
val token = bundle
?.getString(AccountManager.KEY_AUTHTOKEN)
val id = MatrixID.Builder(am.getUserData(accounts[0], "idString")).acceptable()
Matrix(id, am.getUserData(accounts[0], "baseUrl"), am.getUserData(accounts[0], "domain")!!, token!!) {
if (BuildConfig.ALLOW_FCM_USE) {
FCMHelper().init(this@MainActivity)
}
val roomsIntent = Intent(this@MainActivity, RoomsActivity::class.java)
startActivity(roomsIntent)
this@MainActivity.finish()
}
} else {
val roomsIntent = Intent(this@MainActivity, RoomsActivity::class.java)
startActivity(roomsIntent)
this@MainActivity.finish()
}
}
}
} else {
throw Exception("Login failed because AccountManagerFuture is null")
}
Logger.d("login done")
}
}
private fun permissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET)

View File

@ -133,11 +133,11 @@ class MatrixAccountActivity : AccountAuthenticatorActivity() {
* We need to save any data in a [Bundle] to access it in onPostExecute
*/
val data = Bundle()
val user = account.client.context?.user?.get()
val user = account.client?.context?.user?.get()
data.putString(AccountManager.KEY_ACCOUNT_NAME, user?.localPart)
data.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType)
data.putString(MatrixAccountAuthenticator.TOKEN_TYPE, "token")
data.putString(AccountManager.KEY_AUTHTOKEN, account.client.accessToken.get())
data.putString(AccountManager.KEY_AUTHTOKEN, account.client?.accessToken?.get())
data.putString(MatrixAccountAuthenticator.SERVER, user?.domain)
val result = Intent()
@ -266,10 +266,10 @@ class MatrixAccountActivity : AccountAuthenticatorActivity() {
val tokenType = intent.getStringExtra(MatrixAccountAuthenticator.TOKEN_TYPE)
val data = Bundle()
data.putString("localpart", account.client.context?.user?.get()?.localPart)
data.putString("baseUrl", account.client.context?.hsBaseUrl.toString())
data.putString("domain", account.client.context?.user?.get()?.domain)
data.putString("idString", account.client.context?.user?.get()?.id)
data.putString("localpart", account.client?.context?.user?.get()?.localPart)
data.putString("baseUrl", account.client?.context?.hsBaseUrl.toString())
data.putString("domain", account.client?.context?.user?.get()?.domain)
data.putString("idString", account.client?.context?.user?.get()?.id)
accountManager!!.addAccountExplicitly(androidAccount, "", data)
accountManager!!.setAuthToken(androidAccount, tokenType, authtoken)

View File

@ -32,6 +32,7 @@ import blog.nordgedanken.simplematrix.data.view.MessageFull
import blog.nordgedanken.simplematrix.data.view.MessageViewModel
import blog.nordgedanken.simplematrix.data.view.RoomFull
import blog.nordgedanken.simplematrix.databinding.ActivityChatRoomBinding
import blog.nordgedanken.simplematrix.utils.Accounts
import blog.nordgedanken.simplematrix.utils.MediaStoreHelper
import blog.nordgedanken.simplematrix.utils.ui.SlideAnimations
import com.airbnb.deeplinkdispatch.DeepLink
@ -115,6 +116,11 @@ class ChatRoom : AppCompatActivity() {
} else {
intent.getStringExtra("roomID")
}
if (account.client == null) {
val resultIntent = Intent(this, ChatRoom::class.java)
resultIntent.putExtra("roomID", roomID)
Accounts(this, resultIntent).checkAccounts()
}
setupInput(activityBinding.content.editText, activityBinding.content.sendButton)
viewModel.messageList(roomID!!).observe(this@ChatRoom, Observer {
@ -124,7 +130,7 @@ class ChatRoom : AppCompatActivity() {
})
pagingController.requestForcedModelBuild()
doAsync {
rawRoom = account.client.getRoom(roomID)
rawRoom = account.client?.getRoom(roomID)!!
if (db.doesRoomExistInDB(roomID)) {
room = db.getRoomByID(roomID)!!
@ -323,7 +329,7 @@ class ChatRoom : AppCompatActivity() {
val filenameSplit = MediaStoreHelper.getFilePath(this, targetUri)?.split("/")
val filename = filenameSplit?.get(filenameSplit.size - 1)!!
val mimeType = MediaStoreHelper.getMimeType(this, targetUri)
val mxurl = account.client.putMedia(
val mxurl = account.client?.putMedia(
MediaStoreHelper.readBytesFromAndroidImageURL(this, targetUri),
mimeType,
filename
@ -333,7 +339,7 @@ class ChatRoom : AppCompatActivity() {
val messageFull = MessageFull()
messageFull.message = message
messageFull.message?.userID = account.client.user.get().id
messageFull.message?.userID = account.client?.user?.get()?.id
messageFull.message?.roomID = room.room?.id
messageFull.message?.image = mxurl!!
@ -378,7 +384,7 @@ class ChatRoom : AppCompatActivity() {
val messageFull = MessageFull()
messageFull.message = message
messageFull.message?.userID = account.client.user.get().id
messageFull.message?.userID = account.client?.user?.get()?.id
messageFull.message?.roomID = room.room?.id
messageFull.message?.text = textS

View File

@ -38,7 +38,7 @@ class PagingMessageController(val context: Context) : PagedListEpoxyController<M
.id(-1 * currentPosition)
}
val id = item?.message?.id + item?.message?.roomID
return if (item?.message?.userID == account.client.user.get().id) {
return if (item?.message?.userID == account.id) {
if (item?.message?.image == "") {
val element = OutgoingTextMessage_()
.id(id.sha512())

View File

@ -47,13 +47,13 @@ class MatrixClient : KoinComponent {
)
// Setup user if empty
val knownUser = account.client.user.get()
val user = db.getUsersFromCache().firstOrNull { user -> user.MXID == knownUser.id }
val knownUser = account.client?.user?.get()
val user = db.getUsersFromCache().firstOrNull { user -> user.MXID == knownUser?.id }
name = user?.name
avatar_url = user?.avatar
var mxUser: _MatrixUser? = null
if (name == null || avatar_url == null || name?.isEmpty() == true || avatar_url?.isEmpty() == true) {
mxUser = account.client.getUser(knownUser)
mxUser = account.client?.getUser(knownUser)
}
if (name == null || name?.isEmpty() == true) {
name = mxUser?.name?.get()!!

View File

@ -47,7 +47,7 @@ class BackgroundSyncService : IntentService("BG_Sync_Service") {
private fun sync(timeout: Long, nextBatchToken: String): _SyncData? {
val jsonString = account.backgroundSyncFilter
return account.client.sync(SyncOptions.Builder().setSince(nextBatchToken).setTimeout(timeout).setFilter(jsonString).get())
return account.client?.sync(SyncOptions.Builder().setSince(nextBatchToken).setTimeout(timeout).setFilter(jsonString).get())
}
// TODO return enum

View File

@ -40,7 +40,7 @@ class InitialSyncService : IntentService("Initial_Sync_Service") {
fun sync(timeout: Long): _SyncData? {
val jsonString = account.initialSyncFilter
return account.client.sync(SyncOptions.build().setTimeout(timeout).setFilter(jsonString).get())
return account.client?.sync(SyncOptions.build().setTimeout(timeout).setFilter(jsonString).get())
}
override fun onCreate() {

View File

@ -39,7 +39,7 @@ class RoomFull : KoinComponent {
account.status == Matrix.State.BackgroundSync ||
account.status == Matrix.State.InitialSync) {
for (user in usersDB) {
if (user.MXID != account.client.user.get().id) {
if (user.MXID != account.client?.user?.get()?.id) {
return user.avatar
}
}
@ -83,7 +83,7 @@ class RoomFull : KoinComponent {
account.status == Matrix.State.BackgroundSync ||
account.status == Matrix.State.InitialSync) {
for (user in usersDB) {
if (user.MXID != account.client.user.get().id) {
if (user.MXID != account.client?.user?.get()?.id) {
return user.name
}
}

View File

@ -63,7 +63,7 @@ class User : KoinComponent {
val person = Person.Builder().setBot(false)
.setName(name)
if (avatar.startsWith("mxc://")) {
person.setIcon(IconCompat.createWithContentUri(account.client.getMedia(avatar)?.permaLink?.toString()))
person.setIcon(IconCompat.createWithContentUri(account.client?.getMedia(avatar)?.permaLink?.toString()))
}
return person
.build()

View File

@ -0,0 +1,106 @@
package blog.nordgedanken.simplematrix.utils
import android.accounts.Account
import android.accounts.AccountManager
import android.accounts.AccountManagerCallback
import android.accounts.AccountManagerFuture
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.core.app.ActivityCompat.startActivityForResult
import androidx.core.content.ContextCompat.startActivity
import blog.nordgedanken.matrix_android_sdk.Matrix
import blog.nordgedanken.simplematrix.BuildConfig
import blog.nordgedanken.simplematrix.MainActivity
import blog.nordgedanken.simplematrix.accounts.MatrixAccountAuthenticator
import blog.nordgedanken.simplematrix.fcm.FCMHelper
import com.orhanobut.logger.Logger
import io.kamax.matrix.MatrixID
import io.sentry.Sentry
import io.sentry.event.BreadcrumbBuilder
import org.jetbrains.anko.doAsync
import org.koin.standalone.KoinComponent
import org.koin.standalone.inject
/**
* Created by MTRNord on 16.03.2019.
*/
class Accounts(val activity: Activity, val target: Intent) : KoinComponent {
/**
* Account manager is needed to work with Android Accounts
*/
val am: AccountManager by inject()
/**
* Holds any available Accounts
*/
val accounts: Array<Account> by inject()
/**
* Checks the [blog.nordgedanken.simplematrix.utils.Accounts.accounts] Array for existing Accounts
* of the type org.matrix.
*
* If No accounts are present in the Array aka. it is Empty it launches a new Login Request.
* Else it uses the first account in the Array to login with.
*
* TODO Make this Multi Account Capable
*/
fun checkAccounts() {
if (accounts.isEmpty()) {
MainActivity.firstLogin = true
Sentry.getContext().recordBreadcrumb(
BreadcrumbBuilder().setMessage("First login").build()
)
am.addAccount("org.matrix", "token", null, Bundle(), activity, OnTokenAcquired(), null)
} else {
// TODO rework to show available Accounts to the User and let him choose
am.getAuthToken(accounts[0], MatrixAccountAuthenticator.TOKEN_TYPE, null, false, OnTokenAcquired(), null)
}
}
private inner class OnTokenAcquired : AccountManagerCallback<Bundle> {
override fun run(result: AccountManagerFuture<Bundle>?) {
Logger.d("login")
if (result !== null) {
val bundle: Bundle? = try {
result.result
} catch (e: Exception) {
Sentry.capture(e)
null
}
val launch = bundle?.get(AccountManager.KEY_INTENT) as? Intent
if (launch != null) {
startActivityForResult(activity, launch, 0, null)
} else {
doAsync {
if (!MainActivity.firstLogin) {
val token = bundle
?.getString(AccountManager.KEY_AUTHTOKEN)
val id = MatrixID.Builder(am.getUserData(accounts[0], "idString")).acceptable()
Matrix(id, am.getUserData(accounts[0], "baseUrl"), am.getUserData(accounts[0], "domain")!!, token!!) {
if (BuildConfig.ALLOW_FCM_USE) {
FCMHelper().init(activity)
}
startActivity(activity, target, null)
activity.finish()
}
} else {
startActivity(activity, target, null)
activity.finish()
}
}
}
} else {
throw Exception("Login failed because AccountManagerFuture is null")
}
Logger.d("login done")
}
}
}

View File

@ -52,7 +52,7 @@ class ImageLoader(val context: Context, val glide: RequestManager) : KoinCompone
if (url.startsWith("mxc://")) {
val future = glide.asBitmap()
.load(account.client.getMedia(url)?.permaLink?.toString())
.load(account.client?.getMedia(url)?.permaLink?.toString())
.apply(requestOptions)
.submit()
@ -95,7 +95,7 @@ class ImageLoader(val context: Context, val glide: RequestManager) : KoinCompone
if (url.startsWith("mxc://")) {
val future = glide.asBitmap()
.load(account.client.getMedia(url)?.permaLink?.toString())
.load(account.client?.getMedia(url)?.permaLink?.toString())
.apply(requestOptions)
.submit()
@ -128,7 +128,7 @@ class ImageLoader(val context: Context, val glide: RequestManager) : KoinCompone
.diskCacheStrategy(DiskCacheStrategy.ALL)
.transforms(RoundedCorners(10))
val future = glide.asBitmap()
.load(account.client.getMedia(url)?.permaLink?.toString())
.load(account.client?.getMedia(url)?.permaLink?.toString())
.apply(requestOptions)
.submit()
@ -174,7 +174,7 @@ class ImageLoader(val context: Context, val glide: RequestManager) : KoinCompone
requestOptions = requestOptions.placeholder(dialog.room?.nameAvatar)
return if (url.startsWith("mxc://")) {
glide.asBitmap().load(account.client.getMedia(url)?.permaLink?.toString())
glide.asBitmap().load(account.client?.getMedia(url)?.permaLink?.toString())
.apply(requestOptions)
.submit()
.get()

View File

@ -66,7 +66,7 @@ class Notification : KoinComponent {
val id = Date().time.toInt()
val room = db.getRoomByID(message.message?.roomID!!)!!
val ownUser = db.getUserByMXIDRoomIDFromCache(
account.client.context?.user?.get()?.id!!,
account.client?.context?.user?.get()?.id!!,
message.message?.roomID!!
)

View File

@ -25,14 +25,6 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<blog.nordgedanken.simplematrix.utils.ui.ProgressBar
android:id="@+id/load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:visibility="gone"/>
<ImageView
android:src="@mipmap/ic_launcher"
android:layout_width="fill_parent"