mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-22 12:15:00 +01:00
Lots of progress on new login
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
5e8ab11cbf
commit
7cf1cf6025
@ -159,6 +159,8 @@ ext {
|
|||||||
lifecycle_version = '2.2.0-rc03'
|
lifecycle_version = '2.2.0-rc03'
|
||||||
coil_version = "0.9.1"
|
coil_version = "0.9.1"
|
||||||
room_version = "2.2.3"
|
room_version = "2.2.3"
|
||||||
|
geckoviewChannel = "stable"
|
||||||
|
geckoviewVersion = "72.0.20200107212822"
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
@ -185,6 +187,7 @@ dependencies {
|
|||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||||
|
|
||||||
|
implementation "org.mozilla.geckoview:geckoview:${geckoviewVersion}"
|
||||||
implementation "com.github.stateless4j:stateless4j:2.6.0"
|
implementation "com.github.stateless4j:stateless4j:2.6.0"
|
||||||
|
|
||||||
// ViewModel and LiveData
|
// ViewModel and LiveData
|
||||||
|
@ -26,8 +26,6 @@ import android.view.View
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.emoji.widget.EmojiTextView
|
import androidx.emoji.widget.EmojiTextView
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
import butterknife.BindView
|
|
||||||
import butterknife.ButterKnife
|
|
||||||
import coil.api.load
|
import coil.api.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
|
@ -181,7 +181,7 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
|
|||||||
startKoin {
|
startKoin {
|
||||||
androidContext(this@NextcloudTalkApplication)
|
androidContext(this@NextcloudTalkApplication)
|
||||||
androidLogger()
|
androidLogger()
|
||||||
modules(listOf(CommunicationModule, StorageModule, NetworkModule, ConversationsModule, ConversationsListModule, ServiceModule, AccountModule, ServerModule))
|
modules(listOf(CommunicationModule, StorageModule, NetworkModule, ConversationsListModule, ServiceModule, AccountModule, ServerModule))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.controllers
|
package com.nextcloud.talk.controllers
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@ -113,6 +114,7 @@ class AccountVerificationController(args: Bundle?) : BaseController(), KoinCompo
|
|||||||
eventBus.register(this)
|
eventBus.register(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
override fun onViewBound(view: View) {
|
override fun onViewBound(view: View) {
|
||||||
super.onViewBound(view)
|
super.onViewBound(view)
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
@ -257,16 +259,11 @@ class AccountVerificationController(args: Bundle?) : BaseController(), KoinCompo
|
|||||||
override fun onSubscribe(d: Disposable) {}
|
override fun onSubscribe(d: Disposable) {}
|
||||||
|
|
||||||
override fun onNext(userProfileOverall: UserProfileOverall) {
|
override fun onNext(userProfileOverall: UserProfileOverall) {
|
||||||
var displayName: String? = null
|
var displayName: String? = userProfileOverall.ocs.data.displayName
|
||||||
if (!TextUtils.isEmpty(userProfileOverall.ocs.data.displayName)) {
|
|
||||||
displayName = userProfileOverall.ocs.data.displayName
|
|
||||||
} else if (!TextUtils.isEmpty(userProfileOverall.ocs.data.displayNameAlt)) {
|
|
||||||
displayName = userProfileOverall.ocs.data.displayNameAlt
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(displayName)) {
|
if (!TextUtils.isEmpty(displayName)) {
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
storeProfile(displayName, userProfileOverall.ocs.data.userId)
|
storeProfile(displayName, userProfileOverall.ocs.data.userId!!)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
|
@ -900,22 +900,22 @@ class CallController(args: Bundle) : BaseController() {
|
|||||||
override fun onNext(signalingSettingsOverall: SignalingSettingsOverall) {
|
override fun onNext(signalingSettingsOverall: SignalingSettingsOverall) {
|
||||||
var iceServer: IceServer
|
var iceServer: IceServer
|
||||||
if (signalingSettingsOverall.ocs != null &&
|
if (signalingSettingsOverall.ocs != null &&
|
||||||
signalingSettingsOverall.ocs.settings != null
|
signalingSettingsOverall.ocs.signalingSettings != null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
externalSignalingServer = ExternalSignalingServer()
|
externalSignalingServer = ExternalSignalingServer()
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(
|
if (!TextUtils.isEmpty(
|
||||||
signalingSettingsOverall.ocs.settings.externalSignalingServer
|
signalingSettingsOverall.ocs.signalingSettings.externalSignalingServer
|
||||||
) && !TextUtils.isEmpty(
|
) && !TextUtils.isEmpty(
|
||||||
signalingSettingsOverall.ocs
|
signalingSettingsOverall.ocs
|
||||||
.settings
|
.signalingSettings
|
||||||
.externalSignalingTicket
|
.externalSignalingTicket
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
externalSignalingServer = ExternalSignalingServer()
|
externalSignalingServer = ExternalSignalingServer()
|
||||||
externalSignalingServer!!.externalSignalingServer = signalingSettingsOverall.ocs.settings.externalSignalingServer
|
externalSignalingServer!!.externalSignalingServer = signalingSettingsOverall.ocs.signalingSettings.externalSignalingServer
|
||||||
externalSignalingServer!!.externalSignalingTicket = signalingSettingsOverall.ocs.settings.externalSignalingTicket
|
externalSignalingServer!!.externalSignalingTicket = signalingSettingsOverall.ocs.signalingSettings.externalSignalingTicket
|
||||||
hasExternalSignalingServer = true
|
hasExternalSignalingServer = true
|
||||||
} else {
|
} else {
|
||||||
hasExternalSignalingServer = false
|
hasExternalSignalingServer = false
|
||||||
@ -936,9 +936,9 @@ class CallController(args: Bundle) : BaseController() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signalingSettingsOverall.ocs.settings.stunServers != null) {
|
if (signalingSettingsOverall.ocs.signalingSettings.stunServers != null) {
|
||||||
for (i in 0 until signalingSettingsOverall.ocs.settings.stunServers.size) {
|
for (i in 0 until signalingSettingsOverall.ocs.signalingSettings.stunServers!!.size) {
|
||||||
iceServer = signalingSettingsOverall.ocs.settings.stunServers[i]
|
iceServer = signalingSettingsOverall.ocs.signalingSettings.stunServers!![i]
|
||||||
if (TextUtils.isEmpty(iceServer.username) || TextUtils.isEmpty(
|
if (TextUtils.isEmpty(iceServer.username) || TextUtils.isEmpty(
|
||||||
iceServer
|
iceServer
|
||||||
.credential
|
.credential
|
||||||
@ -956,20 +956,20 @@ class CallController(args: Bundle) : BaseController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signalingSettingsOverall.ocs.settings.turnServers != null) {
|
if (signalingSettingsOverall.ocs.signalingSettings.turnServers != null) {
|
||||||
for (i in 0 until signalingSettingsOverall.ocs.settings.turnServers.size) {
|
for (i in 0 until signalingSettingsOverall.ocs.signalingSettings.turnServers!!.size) {
|
||||||
iceServer = signalingSettingsOverall.ocs.settings.turnServers[i]
|
iceServer = signalingSettingsOverall.ocs.signalingSettings.turnServers!![i]
|
||||||
for (j in 0 until iceServer.urls.size) {
|
for (j in 0 until iceServer.urls!!.size) {
|
||||||
if (TextUtils.isEmpty(iceServer.username) || TextUtils.isEmpty(
|
if (TextUtils.isEmpty(iceServer.username) || TextUtils.isEmpty(
|
||||||
iceServer
|
iceServer
|
||||||
.credential
|
.credential
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
iceServers!!.add(PeerConnection.IceServer(iceServer.urls[j]))
|
iceServers!!.add(PeerConnection.IceServer(iceServer.urls!![j]))
|
||||||
} else {
|
} else {
|
||||||
iceServers!!.add(
|
iceServers!!.add(
|
||||||
PeerConnection.IceServer(
|
PeerConnection.IceServer(
|
||||||
iceServer.urls[j],
|
iceServer.urls!![j],
|
||||||
iceServer.username, iceServer.credential
|
iceServer.username, iceServer.credential
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,6 @@ import androidx.work.WorkManager
|
|||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.nextcloud.talk.api.NcApi
|
import com.nextcloud.talk.api.NcApi
|
||||||
import com.nextcloud.talk.events.EventStatus
|
import com.nextcloud.talk.events.EventStatus
|
||||||
import com.nextcloud.talk.jobs.WebsocketConnectionsWorker
|
|
||||||
import com.nextcloud.talk.models.ExternalSignalingServer
|
import com.nextcloud.talk.models.ExternalSignalingServer
|
||||||
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
@ -69,8 +68,8 @@ class SignalingSettingsWorker(context: Context, workerParams: WorkerParameters)
|
|||||||
override fun onNext(signalingSettingsOverall: SignalingSettingsOverall) {
|
override fun onNext(signalingSettingsOverall: SignalingSettingsOverall) {
|
||||||
val externalSignalingServer: ExternalSignalingServer
|
val externalSignalingServer: ExternalSignalingServer
|
||||||
externalSignalingServer = ExternalSignalingServer()
|
externalSignalingServer = ExternalSignalingServer()
|
||||||
externalSignalingServer.externalSignalingServer = signalingSettingsOverall.ocs.settings.externalSignalingServer
|
externalSignalingServer.externalSignalingServer = signalingSettingsOverall.ocs.signalingSettings.externalSignalingServer
|
||||||
externalSignalingServer.externalSignalingTicket = signalingSettingsOverall.ocs.settings.externalSignalingTicket
|
externalSignalingServer.externalSignalingTicket = signalingSettingsOverall.ocs.signalingSettings.externalSignalingTicket
|
||||||
val user = usersRepository.getUserWithId(userEntity.id!!)
|
val user = usersRepository.getUserWithId(userEntity.id!!)
|
||||||
user.externalSignaling = externalSignalingServer
|
user.externalSignaling = externalSignalingServer
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
@ -17,28 +17,30 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
package com.nextcloud.talk.models.json.signaling.settings
|
||||||
|
|
||||||
package com.nextcloud.talk.models.json.signaling.settings;
|
import android.os.Parcelable
|
||||||
|
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.List;
|
import lombok.Data
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@JsonObject
|
@JsonObject
|
||||||
public class IceServer {
|
@Parcelize
|
||||||
@JsonField(name = "url")
|
@Serializable
|
||||||
public String url;
|
data class IceServer @JvmOverloads constructor(
|
||||||
|
@JvmField
|
||||||
@JsonField(name = "urls")
|
@JsonField(name = ["url"])
|
||||||
public List<String> urls;
|
var url: String? = null,
|
||||||
|
@JvmField
|
||||||
@JsonField(name = "username")
|
@JsonField(name = ["urls"])
|
||||||
public String username;
|
var urls: List<String>? = null,
|
||||||
|
@JvmField
|
||||||
@JsonField(name = "credential")
|
@JsonField(name = ["username"])
|
||||||
public String credential;
|
var username: String? = null,
|
||||||
}
|
@JvmField
|
||||||
|
@JsonField(name = ["credential"])
|
||||||
|
var credential: String? = null
|
||||||
|
) : Parcelable
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.nextcloud.talk.models.json.signaling.settings;
|
|
||||||
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@JsonObject
|
|
||||||
public class Settings {
|
|
||||||
@JsonField(name = "stunservers")
|
|
||||||
public List<IceServer> stunServers;
|
|
||||||
|
|
||||||
@JsonField(name = "turnservers")
|
|
||||||
public List<IceServer> turnServers;
|
|
||||||
|
|
||||||
@JsonField(name = "server")
|
|
||||||
public String externalSignalingServer;
|
|
||||||
|
|
||||||
@JsonField(name = "ticket")
|
|
||||||
public String externalSignalingTicket;
|
|
||||||
}
|
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.talk.models.json.signaling.settings
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||||
|
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import lombok.Data
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonObject
|
||||||
|
@Serializable
|
||||||
|
@Parcelize
|
||||||
|
data class SignalingSettings @JvmOverloads constructor(
|
||||||
|
@JvmField
|
||||||
|
@JsonField(name = ["stunservers"])
|
||||||
|
var stunServers: List<IceServer>? = null,
|
||||||
|
@JvmField
|
||||||
|
@JsonField(name = ["turnservers"])
|
||||||
|
var turnServers: List<IceServer>? = null,
|
||||||
|
@JvmField
|
||||||
|
@JsonField(name = ["server"])
|
||||||
|
var externalSignalingServer: String? = null,
|
||||||
|
@JvmField
|
||||||
|
@JsonField(name = ["ticket"])
|
||||||
|
var externalSignalingTicket: String? = null
|
||||||
|
) : Parcelable
|
@ -30,5 +30,5 @@ import lombok.Data;
|
|||||||
@JsonObject
|
@JsonObject
|
||||||
public class SignalingSettingsOcs extends GenericOCS {
|
public class SignalingSettingsOcs extends GenericOCS {
|
||||||
@JsonField(name = "data")
|
@JsonField(name = "data")
|
||||||
public Settings settings;
|
public SignalingSettings signalingSettings;
|
||||||
}
|
}
|
||||||
|
@ -18,25 +18,21 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.models.json.userprofile;
|
package com.nextcloud.talk.models.json.userprofile
|
||||||
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
import com.bluelinelabs.logansquare.annotation.JsonField
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
import com.bluelinelabs.logansquare.annotation.JsonObject
|
||||||
|
import lombok.Data
|
||||||
import org.parceler.Parcel;
|
import org.parceler.Parcel
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Parcel
|
@Parcel
|
||||||
@Data
|
@Data
|
||||||
@JsonObject
|
@JsonObject
|
||||||
public class UserProfileData {
|
class UserProfileData {
|
||||||
@JsonField(name = "display-name")
|
@JvmField
|
||||||
public String displayName;
|
@JsonField(name = ["display-name", "displayname"])
|
||||||
|
var displayName: String? = null
|
||||||
@JsonField(name = "displayname")
|
@JvmField
|
||||||
public String displayNameAlt;
|
@JsonField(name = ["id"])
|
||||||
|
var userId: String? = null
|
||||||
@JsonField(name = "id")
|
|
||||||
public String userId;
|
|
||||||
}
|
}
|
@ -24,6 +24,9 @@ import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
|||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
|
import com.nextcloud.talk.models.json.push.PushRegistrationOverall
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
|
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiService
|
import com.nextcloud.talk.newarch.data.source.remote.ApiService
|
||||||
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
@ -86,6 +89,30 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun registerPushWithServerForUser(user: UserNgEntity, options: Map<String, String>): PushRegistrationOverall {
|
||||||
|
return apiService.registerForPushWithServer(user.getCredentials(), ApiUtils.getUrlNextcloudPush(user.baseUrl), options)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun unregisterPushWithServerForUser(user: UserNgEntity): GenericOverall {
|
||||||
|
return apiService.unregisterForPushWithServer(user.getCredentials(), ApiUtils.getUrlNextcloudPush(user.baseUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun registerPushWithProxyForUser(user: UserNgEntity, options: Map<String, String>): Any {
|
||||||
|
return apiService.unregisterForPushWithProxy(ApiUtils.getUrlPushProxy(), options)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun unregisterPushWithProxyForUser(user: UserNgEntity, options: Map<String, String>): Any {
|
||||||
|
return apiService.unregisterForPushWithProxy(ApiUtils.getUrlPushProxy(), options)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getSignalingSettingsForUser(user: UserNgEntity): SignalingSettingsOverall {
|
||||||
|
return apiService.getSignalingSettings(user.getCredentials(), ApiUtils.getUrlForSignalingSettings(user.baseUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getProfileForUser(user: UserNgEntity): UserProfileOverall {
|
||||||
|
return apiService.getUserProfile(user.getCredentials(), ApiUtils.getUrlForUserProfile(user.baseUrl))
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getConversationsForUser(user: UserNgEntity): List<Conversation> {
|
override suspend fun getConversationsForUser(user: UserNgEntity): List<Conversation> {
|
||||||
return apiService.getConversations(
|
return apiService.getConversations(
|
||||||
user.getCredentials(),
|
user.getCredentials(),
|
||||||
|
@ -24,16 +24,59 @@ import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
|||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
|
import com.nextcloud.talk.models.json.push.PushRegistrationOverall
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
|
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||||
|
import io.reactivex.Observable
|
||||||
import retrofit2.http.*
|
import retrofit2.http.*
|
||||||
|
|
||||||
interface ApiService {
|
interface ApiService {
|
||||||
|
|
||||||
/*
|
|
||||||
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room
|
|
||||||
*/
|
|
||||||
@GET
|
@GET
|
||||||
suspend fun getCapabilities(@Url url: String): CapabilitiesOverall
|
suspend fun getCapabilities(@Url url: String): CapabilitiesOverall
|
||||||
|
|
||||||
|
@GET
|
||||||
|
suspend fun getSignalingSettings(@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String): SignalingSettingsOverall
|
||||||
|
|
||||||
|
@GET
|
||||||
|
suspend fun getUserProfile(@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String): UserProfileOverall
|
||||||
|
|
||||||
|
/*
|
||||||
|
QueryMap items are as follows:
|
||||||
|
- "format" : "json"
|
||||||
|
- "pushTokenHash" : ""
|
||||||
|
- "devicePublicKey" : ""
|
||||||
|
- "proxyServer" : ""
|
||||||
|
|
||||||
|
Server URL is: baseUrl + ocsApiVersion + "/apps/notifications/api/v2/push
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
fun registerForPushWithServer(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String,
|
||||||
|
@QueryMap options: Map<String, String>): PushRegistrationOverall
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
fun unregisterForPushWithServer(@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String): GenericOverall
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST
|
||||||
|
fun registerForPushWithProxy(@Url url: String,
|
||||||
|
@FieldMap fields: Map<String, String>): Any
|
||||||
|
|
||||||
|
/*
|
||||||
|
QueryMap items are as follows:
|
||||||
|
- "deviceIdentifier": "{{deviceIdentifier}}",
|
||||||
|
- "deviceIdentifierSignature": "{{signature}}",
|
||||||
|
- "userPublicKey": "{{userPublicKey}}"
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
fun unregisterForPushWithProxy(@Url url: String?,
|
||||||
|
@QueryMap fields: Map<String, String>): Any
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
suspend fun getConversations(
|
suspend fun getConversations(
|
||||||
@Header(
|
@Header(
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package com.nextcloud.talk.newarch.di.module
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
|
||||||
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
|
||||||
import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
|
|
||||||
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.*
|
|
||||||
import com.nextcloud.talk.newarch.features.chat.ChatViewModelFactory
|
|
||||||
import com.nextcloud.talk.newarch.services.GlobalService
|
|
||||||
import org.koin.dsl.module
|
|
||||||
|
|
||||||
val ConversationsModule = module {
|
|
||||||
single { createGetConversationUseCase(get(), get()) }
|
|
||||||
single { createGetConversationsUseCase(get(), get()) }
|
|
||||||
single { createSetConversationFavoriteValueUseCase(get(), get()) }
|
|
||||||
single { createLeaveConversationUseCase(get(), get()) }
|
|
||||||
single { createDeleteConversationUseCase(get(), get()) }
|
|
||||||
single { createJoinConversationUseCase(get(), get()) }
|
|
||||||
single { createExitConversationUseCase(get(), get()) }
|
|
||||||
factory { createChatViewModelFactory(get(), get(), get(), get(), get(), get()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun createSetConversationFavoriteValueUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): SetConversationFavoriteValueUseCase {
|
|
||||||
return SetConversationFavoriteValueUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createGetConversationUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): GetConversationUseCase {
|
|
||||||
return GetConversationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createGetConversationsUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): GetConversationsUseCase {
|
|
||||||
return GetConversationsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createLeaveConversationUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): LeaveConversationUseCase {
|
|
||||||
return LeaveConversationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createDeleteConversationUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): DeleteConversationUseCase {
|
|
||||||
return DeleteConversationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createJoinConversationUseCase(nextcloudTalkRepository: NextcloudTalkRepository, apiErrorHandler: ApiErrorHandler): JoinConversationUseCase {
|
|
||||||
return JoinConversationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createExitConversationUseCase(nextcloudTalkRepository: NextcloudTalkRepository, apiErrorHandler: ApiErrorHandler): ExitConversationUseCase {
|
|
||||||
return ExitConversationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createChatViewModelFactory(application: Application, joinConversationUseCase: JoinConversationUseCase, exitConversationUseCase: ExitConversationUseCase, conversationsRepository: ConversationsRepository, messagesRepository: MessagesRepository, globalService: GlobalService): ChatViewModelFactory {
|
|
||||||
return ChatViewModelFactory(application, joinConversationUseCase, exitConversationUseCase, conversationsRepository, messagesRepository, globalService)
|
|
||||||
}
|
|
@ -3,10 +3,12 @@ package com.nextcloud.talk.newarch.di.module
|
|||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val ServerModule = module {
|
val ServerModule = module {
|
||||||
single { createGetCapabilitiesUseCase(get(), get()) }
|
single { createGetCapabilitiesUseCase(get(), get()) }
|
||||||
|
single { createGetSignalingSettingsUseCase(get(), get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createGetCapabilitiesUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
fun createGetCapabilitiesUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
@ -14,3 +16,9 @@ fun createGetCapabilitiesUseCase(nextcloudTalkRepository: NextcloudTalkRepositor
|
|||||||
): GetCapabilitiesUseCase {
|
): GetCapabilitiesUseCase {
|
||||||
return GetCapabilitiesUseCase(nextcloudTalkRepository, apiErrorHandler)
|
return GetCapabilitiesUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createGetSignalingSettingsUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler
|
||||||
|
): GetSignalingSettingsUseCase {
|
||||||
|
return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
|
}
|
@ -24,9 +24,19 @@ import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
|||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
|
import com.nextcloud.talk.models.json.push.PushRegistrationOverall
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
|
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
|
||||||
interface NextcloudTalkRepository {
|
interface NextcloudTalkRepository {
|
||||||
|
suspend fun registerPushWithServerForUser(user: UserNgEntity, options: Map<String, String>): PushRegistrationOverall
|
||||||
|
suspend fun unregisterPushWithServerForUser(user: UserNgEntity): GenericOverall
|
||||||
|
suspend fun registerPushWithProxyForUser(user: UserNgEntity, options: Map<String, String>): Any
|
||||||
|
suspend fun unregisterPushWithProxyForUser(user: UserNgEntity, options: Map<String, String>): Any
|
||||||
|
|
||||||
|
suspend fun getSignalingSettingsForUser(user: UserNgEntity): SignalingSettingsOverall
|
||||||
|
suspend fun getProfileForUser(user: UserNgEntity): UserProfileOverall
|
||||||
suspend fun getConversationsForUser(user: UserNgEntity): List<Conversation>
|
suspend fun getConversationsForUser(user: UserNgEntity): List<Conversation>
|
||||||
suspend fun setFavoriteValueForConversation(
|
suspend fun setFavoriteValueForConversation(
|
||||||
user: UserNgEntity,
|
user: UserNgEntity,
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Nextcloud Talk application
|
||||||
|
* *
|
||||||
|
* * @author Mario Danic
|
||||||
|
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* *
|
||||||
|
* * This program is free software: you can redistribute it and/or modify
|
||||||
|
* * it under the terms of the GNU General Public License as published by
|
||||||
|
* * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* * at your option) any later version.
|
||||||
|
* *
|
||||||
|
* * This program is distributed in the hope that it will be useful,
|
||||||
|
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* * GNU General Public License for more details.
|
||||||
|
* *
|
||||||
|
* * You should have received a copy of the GNU General Public License
|
||||||
|
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.newarch.domain.usecases
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||||
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||||
|
import org.koin.core.parameter.DefinitionParameters
|
||||||
|
|
||||||
|
class GetProfileUseCase constructor(
|
||||||
|
private val nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler?
|
||||||
|
) : UseCase<UserProfileOverall, Any?>(apiErrorHandler) {
|
||||||
|
override suspend fun run(params: Any?): UserProfileOverall {
|
||||||
|
val definitionParameters = params as DefinitionParameters
|
||||||
|
return nextcloudTalkRepository.getProfileForUser(definitionParameters[0])
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Nextcloud Talk application
|
||||||
|
* *
|
||||||
|
* * @author Mario Danic
|
||||||
|
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* *
|
||||||
|
* * This program is free software: you can redistribute it and/or modify
|
||||||
|
* * it under the terms of the GNU General Public License as published by
|
||||||
|
* * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* * at your option) any later version.
|
||||||
|
* *
|
||||||
|
* * This program is distributed in the hope that it will be useful,
|
||||||
|
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* * GNU General Public License for more details.
|
||||||
|
* *
|
||||||
|
* * You should have received a copy of the GNU General Public License
|
||||||
|
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.newarch.domain.usecases
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||||
|
import org.koin.core.parameter.DefinitionParameters
|
||||||
|
|
||||||
|
class GetSignalingSettingsUseCase constructor(
|
||||||
|
private val nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler?
|
||||||
|
) : UseCase<SignalingSettingsOverall, Any?>(apiErrorHandler) {
|
||||||
|
override suspend fun run(params: Any?): SignalingSettingsOverall {
|
||||||
|
val definitionParameters = params as DefinitionParameters
|
||||||
|
return nextcloudTalkRepository.getSignalingSettingsForUser(definitionParameters[0])
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
package com.nextcloud.talk.newarch.features.account.di.module
|
package com.nextcloud.talk.newarch.features.account.di.module
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetProfileUseCase
|
||||||
|
import com.nextcloud.talk.newarch.features.account.loginentry.LoginEntryViewModelFactory
|
||||||
import com.nextcloud.talk.newarch.features.account.serverentry.ServerEntryViewModelFactory
|
import com.nextcloud.talk.newarch.features.account.serverentry.ServerEntryViewModelFactory
|
||||||
import org.koin.android.ext.koin.androidApplication
|
import org.koin.android.ext.koin.androidApplication
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
@ -12,6 +15,9 @@ val AccountModule = module {
|
|||||||
androidApplication(), get()
|
androidApplication(), get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
factory {
|
||||||
|
createLoginEntryViewModelFactory(androidApplication(), get(), get(), get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createServerEntryViewModelFactory(
|
fun createServerEntryViewModelFactory(
|
||||||
@ -22,3 +28,14 @@ fun createServerEntryViewModelFactory(
|
|||||||
application, getCapabilitiesUseCase
|
application, getCapabilitiesUseCase
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createLoginEntryViewModelFactory(
|
||||||
|
application: Application,
|
||||||
|
getProfileUseCase: GetProfileUseCase,
|
||||||
|
getCapabilitiesUseCase: GetCapabilitiesUseCase,
|
||||||
|
usersRepository: UsersRepository
|
||||||
|
): LoginEntryViewModelFactory {
|
||||||
|
return LoginEntryViewModelFactory(
|
||||||
|
application, getProfileUseCase, getCapabilitiesUseCase, usersRepository
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Nextcloud Talk application
|
||||||
|
* *
|
||||||
|
* * @author Mario Danic
|
||||||
|
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* *
|
||||||
|
* * This program is free software: you can redistribute it and/or modify
|
||||||
|
* * it under the terms of the GNU General Public License as published by
|
||||||
|
* * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* * at your option) any later version.
|
||||||
|
* *
|
||||||
|
* * This program is distributed in the hope that it will be useful,
|
||||||
|
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* * GNU General Public License for more details.
|
||||||
|
* *
|
||||||
|
* * You should have received a copy of the GNU General Public License
|
||||||
|
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.newarch.features.account.loginentry
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
enum class LoginEntryState {
|
||||||
|
PENDING_CHECK,
|
||||||
|
CHECKING,
|
||||||
|
FAILED,
|
||||||
|
OK
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class LoginEntryStateClarification {
|
||||||
|
INVALID_PARSED_DATA,
|
||||||
|
PROFILE_FETCH_FAILED,
|
||||||
|
CAPABILITIES_FETCH_FAILED,
|
||||||
|
SIGNALING_SETTINGS_FETCH_FAILED,
|
||||||
|
PUSH_REGISTRATION_MISSING_TOKEN,
|
||||||
|
PUSH_REGISTRATION_WITH_SERVER_FAILED,
|
||||||
|
PUSH_REGISTRATION_WITH_PUSH_PROXY_FAILED,
|
||||||
|
ACCOUNT_UPDATED,
|
||||||
|
ACCOUNT_CREATED
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class LoginEntryStateWrapper(val state: LoginEntryState, val clarification: LoginEntryStateClarification?)
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Nextcloud Talk application
|
||||||
|
* *
|
||||||
|
* * @author Mario Danic
|
||||||
|
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* *
|
||||||
|
* * This program is free software: you can redistribute it and/or modify
|
||||||
|
* * it under the terms of the GNU General Public License as published by
|
||||||
|
* * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* * at your option) any later version.
|
||||||
|
* *
|
||||||
|
* * This program is distributed in the hope that it will be useful,
|
||||||
|
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* * GNU General Public License for more details.
|
||||||
|
* *
|
||||||
|
* * You should have received a copy of the GNU General Public License
|
||||||
|
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.newarch.features.account.loginentry
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import com.nextcloud.talk.R
|
||||||
|
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
|
import kotlinx.android.synthetic.main.login_entry_view.view.*
|
||||||
|
import kotlinx.android.synthetic.main.login_web_view.view.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
import org.mozilla.geckoview.*
|
||||||
|
import org.mozilla.geckoview.GeckoSessionSettings.USER_AGENT_MODE_MOBILE
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class LoginEntryView(val bundle: Bundle) : BaseView() {
|
||||||
|
private val protocolSuffix = "://"
|
||||||
|
private val dataSeparator = ":"
|
||||||
|
|
||||||
|
private lateinit var viewModel: LoginEntryViewModel
|
||||||
|
val factory: LoginEntryViewModelFactory by inject()
|
||||||
|
|
||||||
|
private lateinit var geckoView: GeckoView
|
||||||
|
private lateinit var geckoSession: GeckoSession
|
||||||
|
|
||||||
|
private val assembledPrefix = resources?.getString(R.string.nc_talk_login_scheme) + protocolSuffix + "login/"
|
||||||
|
|
||||||
|
private val webLoginUserAgent: String
|
||||||
|
get() = (Build.MANUFACTURER.substring(0, 1).toUpperCase(
|
||||||
|
Locale.getDefault()) +
|
||||||
|
Build.MANUFACTURER.substring(1).toLowerCase(
|
||||||
|
Locale.getDefault()) + " " + Build.MODEL + " ("
|
||||||
|
+ resources!!.getString(R.string.nc_app_name) + ")")
|
||||||
|
|
||||||
|
override fun getLayoutId(): Int {
|
||||||
|
return R.layout.login_entry_view
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||||
|
actionBar?.hide()
|
||||||
|
viewModel = viewModelProvider(factory).get(LoginEntryViewModel::class.java)
|
||||||
|
val view = super.onCreateView(inflater, container)
|
||||||
|
|
||||||
|
geckoView = view.stubImport.inflate() as GeckoView
|
||||||
|
activity?.let {
|
||||||
|
val settings = GeckoSessionSettings.Builder()
|
||||||
|
//.usePrivateMode(true)
|
||||||
|
//.useTrackingProtection(true)
|
||||||
|
.userAgentMode(USER_AGENT_MODE_MOBILE)
|
||||||
|
.userAgentOverride(webLoginUserAgent)
|
||||||
|
.suspendMediaWhenInactive(true)
|
||||||
|
.allowJavascript(true)
|
||||||
|
|
||||||
|
geckoView.autofillEnabled = true
|
||||||
|
geckoSession = GeckoSession(settings.build())
|
||||||
|
val runtime = GeckoRuntime.create(it)
|
||||||
|
geckoSession.open(runtime)
|
||||||
|
geckoSession.progressDelegate = createProgressDelegate()
|
||||||
|
geckoSession.navigationDelegate = createNavigationDelegate()
|
||||||
|
geckoView.setSession(geckoSession)
|
||||||
|
bundle.getString(BundleKeys.KEY_BASE_URL)?.let { baseUrl ->
|
||||||
|
geckoSession.loadUri("$baseUrl/index.php/login/flow", mapOf<String, String>("OCS-APIRequest" to "true"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.state.observe(this@LoginEntryView, Observer {
|
||||||
|
if (it.state == LoginEntryState.FAILED) {
|
||||||
|
router.popController(this)
|
||||||
|
} else if (it.state == LoginEntryState.PENDING_CHECK) {
|
||||||
|
view.progressBar.isVisible = false
|
||||||
|
view.geckoView.isVisible = true
|
||||||
|
} else if (it.state == LoginEntryState.CHECKING) {
|
||||||
|
view.progressBar.isVisible = true
|
||||||
|
view.geckoView.isVisible = false
|
||||||
|
} else {
|
||||||
|
// all good, proceed
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNavigationDelegate(): GeckoSession.NavigationDelegate {
|
||||||
|
return object : GeckoSession.NavigationDelegate {
|
||||||
|
override fun onLoadRequest(p0: GeckoSession, p1: GeckoSession.NavigationDelegate.LoadRequest): GeckoResult<AllowOrDeny>? {
|
||||||
|
if (p1.uri.startsWith(assembledPrefix)) {
|
||||||
|
return GeckoResult.DENY
|
||||||
|
}
|
||||||
|
return super.onLoadRequest(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLocationChange(p0: GeckoSession, p1: String?) {
|
||||||
|
super.onLocationChange(p0, p1)
|
||||||
|
viewModel.parseData(assembledPrefix, dataSeparator, p1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createProgressDelegate(): GeckoSession.ProgressDelegate {
|
||||||
|
return object : GeckoSession.ProgressDelegate {
|
||||||
|
|
||||||
|
override fun onPageStop(session: GeckoSession, success: Boolean) = Unit
|
||||||
|
|
||||||
|
override fun onSecurityChange(
|
||||||
|
session: GeckoSession,
|
||||||
|
securityInfo: GeckoSession.ProgressDelegate.SecurityInformation
|
||||||
|
) = Unit
|
||||||
|
|
||||||
|
override fun onPageStart(session: GeckoSession, url: String) = Unit
|
||||||
|
|
||||||
|
override fun onProgressChange(session: GeckoSession, progress: Int) {
|
||||||
|
view?.pageProgressBar?.progress = progress
|
||||||
|
view?.pageProgressBar?.isVisible = progress in 1..99
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
package com.nextcloud.talk.newarch.features.account.loginentry
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.nextcloud.talk.models.LoginData
|
||||||
|
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
|
||||||
|
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||||
|
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
|
||||||
|
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetProfileUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import java.net.URLDecoder
|
||||||
|
|
||||||
|
class LoginEntryViewModel constructor(
|
||||||
|
application: Application,
|
||||||
|
private val getProfileUseCase: GetProfileUseCase,
|
||||||
|
private val getCapabilitiesUseCase: GetCapabilitiesUseCase,
|
||||||
|
private val getSignalingSettingsUseCase: GetSignalingSettingsUseCase,
|
||||||
|
private val appPreferences: AppPreferences,
|
||||||
|
private val usersRepository: UsersRepository) :
|
||||||
|
BaseViewModel<LoginEntryView>(application) {
|
||||||
|
val state: MutableLiveData<LoginEntryStateWrapper> = MutableLiveData(LoginEntryStateWrapper(LoginEntryState.PENDING_CHECK, null))
|
||||||
|
|
||||||
|
private val user = UserNgEntity(-1, "-1", "", "")
|
||||||
|
|
||||||
|
fun parseData(prefix: String, separator: String, data: String?) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
if (data?.startsWith(prefix) == false) {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.INVALID_PARSED_DATA))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
data as String
|
||||||
|
|
||||||
|
val loginData = LoginData()
|
||||||
|
// format is xxx://login/server:xxx&user:xxx&password:xxx
|
||||||
|
val dataWithoutPrefix = data.substring(prefix.length)
|
||||||
|
val values = dataWithoutPrefix.split("&").toTypedArray()
|
||||||
|
if (values.size != 3) {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.INVALID_PARSED_DATA))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
for (value in values) {
|
||||||
|
when {
|
||||||
|
value.startsWith("user$separator") -> {
|
||||||
|
loginData.username = URLDecoder.decode(
|
||||||
|
value.substring("user$separator".length)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value.startsWith("password$separator") -> {
|
||||||
|
loginData.token = URLDecoder.decode(
|
||||||
|
value.substring("password$separator".length)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value.startsWith("server$separator") -> {
|
||||||
|
loginData.serverUrl = URLDecoder.decode(
|
||||||
|
value.substring("server$separator".length)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// fail
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.INVALID_PARSED_DATA))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loginData.serverUrl.isNullOrEmpty() && !loginData.username.isNullOrEmpty() && !loginData.token.isNullOrEmpty()) {
|
||||||
|
storeCredentialsOrVerify(loginData)
|
||||||
|
} else {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.INVALID_PARSED_DATA))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun storeCredentialsOrVerify(loginData: LoginData) {
|
||||||
|
// username and server url will be null here for sure because we do a check earlier in the process
|
||||||
|
val user = usersRepository.getUserWithUsernameAndServer(loginData.username!!, loginData.serverUrl!!)
|
||||||
|
if (user != null) {
|
||||||
|
user.token = loginData.token
|
||||||
|
usersRepository.updateUser(user)
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.OK, LoginEntryStateClarification.ACCOUNT_UPDATED))
|
||||||
|
} else {
|
||||||
|
getProfile(loginData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getProfile(loginData: LoginData) {
|
||||||
|
user.username = loginData.username!!
|
||||||
|
user.baseUrl = loginData.serverUrl!!
|
||||||
|
getProfileUseCase.invoke(viewModelScope, parametersOf(user), object : UseCaseResponse<UserProfileOverall> {
|
||||||
|
override suspend fun onSuccess(result: UserProfileOverall) {
|
||||||
|
result.ocs.data.userId?.let { userId ->
|
||||||
|
user.displayName = result.ocs.data.displayName
|
||||||
|
user.userId = userId
|
||||||
|
getCapabilities()
|
||||||
|
} ?: run {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.PROFILE_FETCH_FAILED))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onError(errorModel: ErrorModel?) {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.PROFILE_FETCH_FAILED))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCapabilities() {
|
||||||
|
getCapabilitiesUseCase.invoke(viewModelScope, parametersOf(user.baseUrl), object : UseCaseResponse<CapabilitiesOverall> {
|
||||||
|
override suspend fun onSuccess(result: CapabilitiesOverall) {
|
||||||
|
user.capabilities = result.ocs.data.capabilities
|
||||||
|
getSignalingSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onError(errorModel: ErrorModel?) {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.CAPABILITIES_FETCH_FAILED))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSignalingSettings() {
|
||||||
|
getSignalingSettingsUseCase.invoke(viewModelScope, parametersOf(user), object : UseCaseResponse<SignalingSettingsOverall> {
|
||||||
|
override suspend fun onSuccess(result: SignalingSettingsOverall) {
|
||||||
|
user.signalingSettings = result.ocs.signalingSettings
|
||||||
|
registerForPush()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onError(errorModel: ErrorModel?) {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.FAILED, LoginEntryStateClarification.SIGNALING_SETTINGS_FETCH_FAILED))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerForPush() {
|
||||||
|
val token = appPreferences.pushToken
|
||||||
|
if (!token.isNullOrBlank()) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.OK, LoginEntryStateClarification.PUSH_REGISTRATION_MISSING_TOKEN))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerForPushWithServer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerForPushWithProxy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.nextcloud.talk.newarch.features.account.loginentry
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetProfileUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
||||||
|
|
||||||
|
class LoginEntryViewModelFactory constructor(private val application: Application, private val getProfileUseCase: GetProfileUseCase, private val getCapabilitiesUseCase: GetCapabilitiesUseCase, private val getSignalingSettingsUseCase: GetSignalingSettingsUseCase, private val usersRepository: UsersRepository) : ViewModelProvider.Factory {
|
||||||
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
|
return LoginEntryViewModel(application, getProfileUseCase, getCapabilitiesUseCase, getSignalingSettingsUseCase, usersRepository) as T
|
||||||
|
}
|
||||||
|
}
|
@ -30,8 +30,11 @@ import android.view.ViewGroup
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import com.bluelinelabs.conductor.RouterTransaction
|
||||||
|
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView
|
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView
|
||||||
|
import com.nextcloud.talk.newarch.features.account.loginentry.LoginEntryView
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import kotlinx.android.synthetic.main.server_entry_view.view.*
|
import kotlinx.android.synthetic.main.server_entry_view.view.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
@ -67,7 +70,8 @@ class ServerEntryView : BaseView() {
|
|||||||
ServerEntryCapabilitiesCheckState.SERVER_SUPPORTED -> {
|
ServerEntryCapabilitiesCheckState.SERVER_SUPPORTED -> {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(BundleKeys.KEY_BASE_URL, it.url)
|
bundle.putString(BundleKeys.KEY_BASE_URL, it.url)
|
||||||
//router.pushController(RouterTransaction.with(LoginEntryView(bundle)).popChangeHandler(HorizontalChangeHandler()).pushChangeHandler(HorizontalChangeHandler()))
|
router.pushController(RouterTransaction.with(LoginEntryView(bundle))
|
||||||
|
.popChangeHandler(HorizontalChangeHandler()).pushChangeHandler(HorizontalChangeHandler()))
|
||||||
}
|
}
|
||||||
// Unsupported
|
// Unsupported
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -28,7 +28,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
||||||
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
|
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
|
||||||
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.*
|
import com.nextcloud.talk.newarch.domain.usecases.GetCapabilitiesUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
@ -57,7 +57,6 @@ class ServerEntryViewModel constructor(
|
|||||||
checkState.postValue(ServerEntryCapabilitiesCheckStateWrapper(ServerEntryCapabilitiesCheckState.SERVER_UNSUPPORTED, url))
|
checkState.postValue(ServerEntryCapabilitiesCheckStateWrapper(ServerEntryCapabilitiesCheckState.SERVER_UNSUPPORTED, url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -121,8 +121,8 @@ open class ConversationsPresenter(context: Context, onElementClick: ((Page, Hold
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
authorDisplayName = if (!TextUtils.isEmpty(conversation.lastMessage?.actorDisplayName)) {
|
authorDisplayName = if (!TextUtils.isEmpty(conversation.lastMessage?.actorDisplayName)) {
|
||||||
conversation.lastMessage?.actorDisplayName!!.substringBefore(" ") }
|
conversation.lastMessage?.actorDisplayName!!.substringBefore(" ")
|
||||||
else if ("guests" == conversation.lastMessage!!.actorType)
|
} else if ("guests" == conversation.lastMessage!!.actorType)
|
||||||
context.getString(R.string.nc_guest)
|
context.getString(R.string.nc_guest)
|
||||||
else
|
else
|
||||||
""
|
""
|
||||||
|
@ -21,21 +21,23 @@
|
|||||||
package com.nextcloud.talk.newarch.local.converters
|
package com.nextcloud.talk.newarch.local.converters
|
||||||
|
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import com.bluelinelabs.logansquare.LoganSquare
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettings
|
||||||
import com.nextcloud.talk.models.ExternalSignalingServer
|
import com.nextcloud.talk.newarch.utils.MagicJson
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class ExternalSignalingConverter {
|
class SignalingSettingsConverter {
|
||||||
|
val json = Json(MagicJson.customJsonConfiguration)
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun fromExternalSignalingToString(externalSignalingServer: ExternalSignalingServer?): String {
|
fun fromSignalingSettingsToString(signalingSettings: SignalingSettings?): String {
|
||||||
if (externalSignalingServer == null) {
|
return if (signalingSettings == null) {
|
||||||
return ""
|
""
|
||||||
} else {
|
} else {
|
||||||
return LoganSquare.serialize(externalSignalingServer)
|
json.stringify(SignalingSettings.serializer(), signalingSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun fromStringToExternalSignaling(value: String): ExternalSignalingServer? {
|
fun fromStringToSignalingSettings(value: String): SignalingSettings? {
|
||||||
return LoganSquare.parse(value, ExternalSignalingServer::class.java)
|
return json.parse(SignalingSettings.serializer(), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -43,7 +43,7 @@ import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
|||||||
ConversationReadOnlyStateConverter::class, NotificationLevelConverter::class,
|
ConversationReadOnlyStateConverter::class, NotificationLevelConverter::class,
|
||||||
ConversationTypeConverter::class, ParticipantTypeConverter::class,
|
ConversationTypeConverter::class, ParticipantTypeConverter::class,
|
||||||
PushConfigurationConverter::class, CapabilitiesConverter::class,
|
PushConfigurationConverter::class, CapabilitiesConverter::class,
|
||||||
ExternalSignalingConverter::class,
|
SignalingSettingsConverter::class,
|
||||||
UserStatusConverter::class, SystemMessageTypeConverter::class, ParticipantMapConverter::class
|
UserStatusConverter::class, SystemMessageTypeConverter::class, ParticipantMapConverter::class
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ import android.os.Parcelable
|
|||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.nextcloud.talk.models.ExternalSignalingServer
|
|
||||||
import com.nextcloud.talk.models.json.capabilities.Capabilities
|
import com.nextcloud.talk.models.json.capabilities.Capabilities
|
||||||
import com.nextcloud.talk.models.json.push.PushConfigurationState
|
import com.nextcloud.talk.models.json.push.PushConfigurationState
|
||||||
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettings
|
||||||
import com.nextcloud.talk.newarch.local.models.other.UserStatus
|
import com.nextcloud.talk.newarch.local.models.other.UserStatus
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
@ -47,8 +47,8 @@ data class UserNgEntity(
|
|||||||
@ColumnInfo(name = "capabilities") var capabilities: Capabilities? = null,
|
@ColumnInfo(name = "capabilities") var capabilities: Capabilities? = null,
|
||||||
@ColumnInfo(name = "client_auth_cert") var clientCertificate: String? = null,
|
@ColumnInfo(name = "client_auth_cert") var clientCertificate: String? = null,
|
||||||
@ColumnInfo(
|
@ColumnInfo(
|
||||||
name = "external_signaling"
|
name = "signaling_settings"
|
||||||
) var externalSignaling: ExternalSignalingServer? = null,
|
) var signalingSettings: SignalingSettings? = null,
|
||||||
@ColumnInfo(name = "status") var status: UserStatus? = null
|
@ColumnInfo(name = "status") var status: UserStatus? = null
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ data class UserNgEntity(
|
|||||||
if (pushConfiguration != other.pushConfiguration) return false
|
if (pushConfiguration != other.pushConfiguration) return false
|
||||||
if (capabilities != other.capabilities) return false
|
if (capabilities != other.capabilities) return false
|
||||||
if (clientCertificate != other.clientCertificate) return false
|
if (clientCertificate != other.clientCertificate) return false
|
||||||
if (externalSignaling != other.externalSignaling) return false
|
if (signalingSettings != other.signalingSettings) return false
|
||||||
if (status != other.status) return false
|
if (status != other.status) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Nextcloud Talk application
|
||||||
|
* *
|
||||||
|
* * @author Mario Danic
|
||||||
|
* * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* *
|
||||||
|
* * This program is free software: you can redistribute it and/or modify
|
||||||
|
* * it under the terms of the GNU General Public License as published by
|
||||||
|
* * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* * at your option) any later version.
|
||||||
|
* *
|
||||||
|
* * This program is distributed in the hope that it will be useful,
|
||||||
|
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* * GNU General Public License for more details.
|
||||||
|
* *
|
||||||
|
* * You should have received a copy of the GNU General Public License
|
||||||
|
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.newarch.utils
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
|
|
||||||
|
sealed class MagicJson {
|
||||||
|
companion object {
|
||||||
|
private val defaultIndent: String = " "
|
||||||
|
private val defaultDiscriminator = "type"
|
||||||
|
|
||||||
|
val customJsonConfiguration = JsonConfiguration(
|
||||||
|
encodeDefaults = true,
|
||||||
|
strictMode = true,
|
||||||
|
unquoted = false,
|
||||||
|
allowStructuredMapKeys = true,
|
||||||
|
prettyPrint = true,
|
||||||
|
indent = defaultIndent,
|
||||||
|
useArrayPolymorphism = true,
|
||||||
|
classDiscriminator = defaultDiscriminator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
24
app/src/main/res/layout/login_entry_view.xml
Normal file
24
app/src/main/res/layout/login_entry_view.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorPrimary">
|
||||||
|
|
||||||
|
<ViewStub
|
||||||
|
android:id="@+id/stubImport"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:inflatedId="@+id/webViewImportLayout"
|
||||||
|
android:layout="@layout/login_web_view" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="@dimen/item_height"
|
||||||
|
android:layout_height="@dimen/item_height"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:indeterminateTint="@color/white"
|
||||||
|
android:indeterminateTintMode="src_in" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
41
app/src/main/res/layout/login_web_view.xml
Normal file
41
app/src/main/res/layout/login_web_view.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ /*
|
||||||
|
~ * Nextcloud Talk application
|
||||||
|
~ *
|
||||||
|
~ * @author Mario Danic
|
||||||
|
~ * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
|
||||||
|
~ *
|
||||||
|
~ * This program is free software: you can redistribute it and/or modify
|
||||||
|
~ * it under the terms of the GNU General Public License as published by
|
||||||
|
~ * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
~ * at your option) any later version.
|
||||||
|
~ *
|
||||||
|
~ * This program is distributed in the hope that it will be useful,
|
||||||
|
~ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
~ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
~ * GNU General Public License for more details.
|
||||||
|
~ *
|
||||||
|
~ * You should have received a copy of the GNU General Public License
|
||||||
|
~ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
~ */
|
||||||
|
-->
|
||||||
|
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/pageProgressBar"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="3dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<org.mozilla.geckoview.GeckoView
|
||||||
|
android:id="@+id/geckoView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="invisible"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
10
build.gradle
10
build.gradle
@ -31,6 +31,9 @@ buildscript {
|
|||||||
maven {
|
maven {
|
||||||
url 'https://jitpack.io'
|
url 'https://jitpack.io'
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
url 'https://maven.mozilla.org/maven2'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||||
@ -54,10 +57,15 @@ allprojects {
|
|||||||
maven {
|
maven {
|
||||||
url 'https://oss.sonatype.org/content/repositories/snapshots'
|
url 'https://oss.sonatype.org/content/repositories/snapshots'
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
url 'https://maven.mozilla.org/maven2'
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
url 'https://jitpack.io'
|
url 'https://jitpack.io'
|
||||||
}
|
}
|
||||||
maven { url 'https://maven.google.com' }
|
maven {
|
||||||
|
url 'https://maven.google.com'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user