mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-14 16:25:05 +01:00
Fix #703 and other improvements
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
7cf1cf6025
commit
b1dcada075
@ -159,8 +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"
|
geckoviewChannel = "nightly"
|
||||||
geckoviewVersion = "72.0.20200107212822"
|
geckoviewVersion = "71.0.20200108003105"
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "2c4f372b48cd11e679b04c6d577f1cd8",
|
"identityHash": "40ddfb9547f62f10e95450e4a5495115",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "conversations",
|
"tableName": "conversations",
|
||||||
@ -307,7 +307,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "users",
|
"tableName": "users",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id` TEXT NOT NULL, `username` TEXT NOT NULL, `base_url` TEXT NOT NULL, `token` TEXT, `display_name` TEXT, `push_configuration` TEXT, `capabilities` TEXT, `client_auth_cert` TEXT, `external_signaling` TEXT, `status` INTEGER)",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id` TEXT NOT NULL, `username` TEXT NOT NULL, `base_url` TEXT NOT NULL, `token` TEXT, `display_name` TEXT, `push_configuration` TEXT, `capabilities` TEXT, `client_auth_cert` TEXT, `signaling_settings` TEXT, `status` INTEGER)",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@ -364,8 +364,8 @@
|
|||||||
"notNull": false
|
"notNull": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "externalSignaling",
|
"fieldPath": "signalingSettings",
|
||||||
"columnName": "external_signaling",
|
"columnName": "signaling_settings",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": false
|
"notNull": false
|
||||||
},
|
},
|
||||||
@ -389,7 +389,7 @@
|
|||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2c4f372b48cd11e679b04c6d577f1cd8')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '40ddfb9547f62f10e95450e4a5495115')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -83,10 +83,6 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders
|
|||||||
@BindView(R.id.quotedMessage)
|
@BindView(R.id.quotedMessage)
|
||||||
var quotedMessage: EmojiTextView? = null
|
var quotedMessage: EmojiTextView? = null
|
||||||
|
|
||||||
@JvmField
|
|
||||||
@BindView(R.id.quotedMessageTime)
|
|
||||||
var quotedMessageTime: TextView? = null
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@BindView(R.id.quoteColoredView)
|
@BindView(R.id.quoteColoredView)
|
||||||
var quoteColoredView: View? = null
|
var quoteColoredView: View? = null
|
||||||
@ -227,8 +223,6 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders
|
|||||||
|
|
||||||
quotedUserName?.setTextColor(context.resources.getColor(R.color.colorPrimary))
|
quotedUserName?.setTextColor(context.resources.getColor(R.color.colorPrimary))
|
||||||
|
|
||||||
quotedMessageTime?.text = DateFormatter.format(parentChatMessage.createdAt, DateFormatter.Template.TIME)
|
|
||||||
quotedMessageTime?.setTextColor(context.resources.getColor(R.color.warm_grey_four))
|
|
||||||
quoteColoredView?.setBackgroundResource(R.color.colorPrimary)
|
quoteColoredView?.setBackgroundResource(R.color.colorPrimary)
|
||||||
quotedChatMessageView?.visibility = View.VISIBLE
|
quotedChatMessageView?.visibility = View.VISIBLE
|
||||||
} ?: run {
|
} ?: run {
|
||||||
|
@ -70,10 +70,6 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
|||||||
@BindView(R.id.quotedMessage)
|
@BindView(R.id.quotedMessage)
|
||||||
var quotedMessage: EmojiTextView? = null
|
var quotedMessage: EmojiTextView? = null
|
||||||
|
|
||||||
@JvmField
|
|
||||||
@BindView(R.id.quotedMessageTime)
|
|
||||||
var quotedMessageTime: TextView? = null
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@BindView(R.id.quoteColoredView)
|
@BindView(R.id.quoteColoredView)
|
||||||
var quoteColoredView: View? = null
|
var quoteColoredView: View? = null
|
||||||
@ -152,8 +148,6 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
|||||||
quotedMessage?.setTextColor(context.resources.getColor(R.color.nc_outcoming_text_default))
|
quotedMessage?.setTextColor(context.resources.getColor(R.color.nc_outcoming_text_default))
|
||||||
quotedUserName?.setTextColor(context.resources.getColor(R.color.nc_grey))
|
quotedUserName?.setTextColor(context.resources.getColor(R.color.nc_grey))
|
||||||
|
|
||||||
quotedMessageTime?.text = DateFormatter.format(parentChatMessage.createdAt, DateFormatter.Template.TIME)
|
|
||||||
quotedMessageTime?.setTextColor(context.resources.getColor(R.color.white60))
|
|
||||||
quoteColoredView?.setBackgroundResource(R.color.white)
|
quoteColoredView?.setBackgroundResource(R.color.white)
|
||||||
|
|
||||||
quotedChatMessageView?.visibility = View.VISIBLE
|
quotedChatMessageView?.visibility = View.VISIBLE
|
||||||
|
@ -29,10 +29,7 @@ import androidx.emoji.bundled.BundledEmojiCompatConfig
|
|||||||
import androidx.emoji.text.EmojiCompat
|
import androidx.emoji.text.EmojiCompat
|
||||||
import androidx.lifecycle.LifecycleObserver
|
import androidx.lifecycle.LifecycleObserver
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.*
|
||||||
import androidx.work.OneTimeWorkRequest
|
|
||||||
import androidx.work.PeriodicWorkRequest
|
|
||||||
import androidx.work.WorkManager
|
|
||||||
import coil.Coil
|
import coil.Coil
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import com.bluelinelabs.logansquare.LoganSquare
|
import com.bluelinelabs.logansquare.LoganSquare
|
||||||
@ -46,7 +43,9 @@ import com.nextcloud.talk.models.ExternalSignalingServer
|
|||||||
import com.nextcloud.talk.models.database.UserEntity
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
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.di.module.*
|
import com.nextcloud.talk.newarch.di.module.*
|
||||||
|
import com.nextcloud.talk.newarch.domain.di.module.UseCasesModule
|
||||||
import com.nextcloud.talk.newarch.features.account.di.module.AccountModule
|
import com.nextcloud.talk.newarch.features.account.di.module.AccountModule
|
||||||
import com.nextcloud.talk.newarch.features.conversationslist.di.module.ConversationsListModule
|
import com.nextcloud.talk.newarch.features.conversationslist.di.module.ConversationsListModule
|
||||||
import com.nextcloud.talk.newarch.local.dao.UsersDao
|
import com.nextcloud.talk.newarch.local.dao.UsersDao
|
||||||
@ -72,13 +71,14 @@ import org.koin.android.ext.android.inject
|
|||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.android.ext.koin.androidLogger
|
import org.koin.android.ext.koin.androidLogger
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
import org.webrtc.PeerConnectionFactory
|
import org.webrtc.PeerConnectionFactory
|
||||||
import org.webrtc.voiceengine.WebRtcAudioManager
|
import org.webrtc.voiceengine.WebRtcAudioManager
|
||||||
import org.webrtc.voiceengine.WebRtcAudioUtils
|
import org.webrtc.voiceengine.WebRtcAudioUtils
|
||||||
import java.security.Security
|
import java.security.Security
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class NextcloudTalkApplication : Application(), LifecycleObserver {
|
class NextcloudTalkApplication : Application(), LifecycleObserver, Configuration.Provider {
|
||||||
//region Getters
|
//region Getters
|
||||||
|
|
||||||
val userUtils: UserUtils by inject()
|
val userUtils: UserUtils by inject()
|
||||||
@ -181,7 +181,7 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
|
|||||||
startKoin {
|
startKoin {
|
||||||
androidContext(this@NextcloudTalkApplication)
|
androidContext(this@NextcloudTalkApplication)
|
||||||
androidLogger()
|
androidLogger()
|
||||||
modules(listOf(CommunicationModule, StorageModule, NetworkModule, ConversationsListModule, ServiceModule, AccountModule, ServerModule))
|
modules(listOf(CommunicationModule, StorageModule, NetworkModule, ConversationsListModule, ServiceModule, AccountModule, UseCasesModule))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,8 +211,11 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
|
|||||||
}
|
}
|
||||||
userNg.clientCertificate = user.clientCertificate
|
userNg.clientCertificate = user.clientCertificate
|
||||||
try {
|
try {
|
||||||
userNg.externalSignaling =
|
val external = LoganSquare.parse(user.externalSignalingServer, ExternalSignalingServer::class.java)
|
||||||
LoganSquare.parse(user.externalSignalingServer, ExternalSignalingServer::class.java)
|
val signalingSettings = SignalingSettings()
|
||||||
|
signalingSettings.externalSignalingServer = external.externalSignalingServer
|
||||||
|
signalingSettings.externalSignalingTicket = external.externalSignalingTicket
|
||||||
|
userNg.signalingSettings = signalingSettings
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// no external signaling
|
// no external signaling
|
||||||
}
|
}
|
||||||
@ -259,5 +262,9 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getWorkManagerConfiguration(): Configuration {
|
||||||
|
return Configuration.Builder().build()
|
||||||
|
}
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
|
@ -1408,7 +1408,6 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.maxLines = 2
|
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.maxLines = 2
|
||||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.ellipsize = TextUtils.TruncateAt.END
|
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.ellipsize = TextUtils.TruncateAt.END
|
||||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.text = it.text
|
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)?.text = it.text
|
||||||
messageInputView?.findViewById<TextView>(R.id.quotedMessageTime)?.text = DateFormatter.format(it.createdAt, DateFormatter.Template.TIME)
|
|
||||||
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text = it.actorDisplayName
|
messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text = it.actorDisplayName
|
||||||
?: context.getText(R.string.nc_nick_guest)
|
?: context.getText(R.string.nc_nick_guest)
|
||||||
|
|
||||||
|
@ -593,18 +593,7 @@ class SettingsController : BaseController() {
|
|||||||
)
|
)
|
||||||
.subscribe({ userProfileOverall ->
|
.subscribe({ 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.displayName
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
displayName = userProfileOverall.ocs.data.displayNameAlt
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(displayName) && displayName != currentUser!!.displayName) {
|
if (!TextUtils.isEmpty(displayName) && displayName != currentUser!!.displayName) {
|
||||||
val user = usersRepository.getUserWithId(currentUser!!.id!!)
|
val user = usersRepository.getUserWithId(currentUser!!.id!!)
|
||||||
|
@ -71,7 +71,7 @@ class SignalingSettingsWorker(context: Context, workerParams: WorkerParameters)
|
|||||||
externalSignalingServer.externalSignalingServer = signalingSettingsOverall.ocs.signalingSettings.externalSignalingServer
|
externalSignalingServer.externalSignalingServer = signalingSettingsOverall.ocs.signalingSettings.externalSignalingServer
|
||||||
externalSignalingServer.externalSignalingTicket = signalingSettingsOverall.ocs.signalingSettings.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 {
|
||||||
val result = usersRepository.updateUser(user)
|
val result = usersRepository.updateUser(user)
|
||||||
eventBus.post(EventStatus(user.id!!,
|
eventBus.post(EventStatus(user.id!!,
|
||||||
|
@ -41,7 +41,7 @@ class WebsocketConnectionsWorker(
|
|||||||
var userEntity: UserNgEntity
|
var userEntity: UserNgEntity
|
||||||
for (i in userEntityList.indices) {
|
for (i in userEntityList.indices) {
|
||||||
userEntity = userEntityList[i]
|
userEntity = userEntityList[i]
|
||||||
if (userEntity.externalSignaling != null) {
|
/*if (userEntity.externalSignaling != null) {
|
||||||
if (!userEntity.externalSignaling!!.externalSignalingServer.isNullOrEmpty() &&
|
if (!userEntity.externalSignaling!!.externalSignalingServer.isNullOrEmpty() &&
|
||||||
!userEntity.externalSignaling!!.externalSignalingTicket.isNullOrEmpty()) {
|
!userEntity.externalSignaling!!.externalSignalingTicket.isNullOrEmpty()) {
|
||||||
WebSocketConnectionHelper.getExternalSignalingInstanceForServer(
|
WebSocketConnectionHelper.getExternalSignalingInstanceForServer(
|
||||||
@ -50,8 +50,7 @@ class WebsocketConnectionsWorker(
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.success()
|
return Result.success()
|
||||||
|
@ -57,6 +57,7 @@ import okhttp3.logging.HttpLoggingInterceptor.Logger
|
|||||||
import org.koin.android.ext.koin.androidApplication
|
import org.koin.android.ext.koin.androidApplication
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -72,6 +73,7 @@ import javax.net.ssl.SSLSocketFactory
|
|||||||
import javax.net.ssl.X509KeyManager
|
import javax.net.ssl.X509KeyManager
|
||||||
|
|
||||||
val NetworkModule = module {
|
val NetworkModule = module {
|
||||||
|
single { createGeckoRuntime(androidContext()) }
|
||||||
single { createService(get()) }
|
single { createService(get()) }
|
||||||
single { createLegacyNcApi(get()) }
|
single { createLegacyNcApi(get()) }
|
||||||
single { createRetrofit(get()) }
|
single { createRetrofit(get()) }
|
||||||
@ -89,6 +91,10 @@ val NetworkModule = module {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createGeckoRuntime(context: Context): GeckoRuntime {
|
||||||
|
return GeckoRuntime.create(context)
|
||||||
|
}
|
||||||
|
|
||||||
fun createCookieManager(): CookieManager {
|
fun createCookieManager(): CookieManager {
|
||||||
val cookieManager = CookieManager()
|
val cookieManager = CookieManager()
|
||||||
cookieManager.setCookiePolicy(ACCEPT_ALL)
|
cookieManager.setCookiePolicy(ACCEPT_ALL)
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package com.nextcloud.talk.newarch.di.module
|
|
||||||
|
|
||||||
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.GetCapabilitiesUseCase
|
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
|
||||||
import org.koin.dsl.module
|
|
||||||
|
|
||||||
val ServerModule = module {
|
|
||||||
single { createGetCapabilitiesUseCase(get(), get()) }
|
|
||||||
single { createGetSignalingSettingsUseCase(get(), get()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createGetCapabilitiesUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): GetCapabilitiesUseCase {
|
|
||||||
return GetCapabilitiesUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createGetSignalingSettingsUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): GetSignalingSettingsUseCase {
|
|
||||||
return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.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 UseCasesModule = 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()) }
|
||||||
|
single { createGetProfileUseCase(get(), get()) }
|
||||||
|
single { createGetSignalingUseCase(get(), get()) }
|
||||||
|
single { createGetCapabilitiesUseCase(get(), get()) }
|
||||||
|
factory { createChatViewModelFactory(get(), get(), get(), get(), get(), get()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGetCapabilitiesUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler
|
||||||
|
): GetCapabilitiesUseCase {
|
||||||
|
return GetCapabilitiesUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGetSignalingSettingsUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler
|
||||||
|
): GetSignalingSettingsUseCase {
|
||||||
|
return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGetSignalingUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler
|
||||||
|
): GetSignalingSettingsUseCase {
|
||||||
|
return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGetProfileUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler
|
||||||
|
): GetProfileUseCase {
|
||||||
|
return GetProfileUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
@ -4,8 +4,10 @@ import android.app.Application
|
|||||||
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
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.domain.usecases.GetProfileUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
||||||
import com.nextcloud.talk.newarch.features.account.loginentry.LoginEntryViewModelFactory
|
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 com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import org.koin.android.ext.koin.androidApplication
|
import org.koin.android.ext.koin.androidApplication
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ val AccountModule = module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
factory {
|
factory {
|
||||||
createLoginEntryViewModelFactory(androidApplication(), get(), get(), get())
|
createLoginEntryViewModelFactory(androidApplication(), get(), get(), get(), get(), get() )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,9 +35,11 @@ fun createLoginEntryViewModelFactory(
|
|||||||
application: Application,
|
application: Application,
|
||||||
getProfileUseCase: GetProfileUseCase,
|
getProfileUseCase: GetProfileUseCase,
|
||||||
getCapabilitiesUseCase: GetCapabilitiesUseCase,
|
getCapabilitiesUseCase: GetCapabilitiesUseCase,
|
||||||
|
getSignalingSettingsUseCase: GetSignalingSettingsUseCase,
|
||||||
|
appPreferences: AppPreferences,
|
||||||
usersRepository: UsersRepository
|
usersRepository: UsersRepository
|
||||||
): LoginEntryViewModelFactory {
|
): LoginEntryViewModelFactory {
|
||||||
return LoginEntryViewModelFactory(
|
return LoginEntryViewModelFactory(
|
||||||
application, getProfileUseCase, getCapabilitiesUseCase, usersRepository
|
application, getProfileUseCase, getCapabilitiesUseCase, getSignalingSettingsUseCase, appPreferences, usersRepository
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -29,11 +29,13 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
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.conversationslist.ConversationsListView
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import kotlinx.android.synthetic.main.login_entry_view.view.*
|
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.koin.android.ext.android.inject
|
||||||
import org.mozilla.geckoview.*
|
import org.mozilla.geckoview.*
|
||||||
import org.mozilla.geckoview.GeckoSessionSettings.USER_AGENT_MODE_MOBILE
|
import org.mozilla.geckoview.GeckoSessionSettings.USER_AGENT_MODE_MOBILE
|
||||||
@ -48,6 +50,7 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
|
|
||||||
private lateinit var geckoView: GeckoView
|
private lateinit var geckoView: GeckoView
|
||||||
private lateinit var geckoSession: GeckoSession
|
private lateinit var geckoSession: GeckoSession
|
||||||
|
private val geckoRuntime: GeckoRuntime by inject()
|
||||||
|
|
||||||
private val assembledPrefix = resources?.getString(R.string.nc_talk_login_scheme) + protocolSuffix + "login/"
|
private val assembledPrefix = resources?.getString(R.string.nc_talk_login_scheme) + protocolSuffix + "login/"
|
||||||
|
|
||||||
@ -67,7 +70,32 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
viewModel = viewModelProvider(factory).get(LoginEntryViewModel::class.java)
|
viewModel = viewModelProvider(factory).get(LoginEntryViewModel::class.java)
|
||||||
val view = super.onCreateView(inflater, container)
|
val view = super.onCreateView(inflater, container)
|
||||||
|
|
||||||
geckoView = view.stubImport.inflate() as GeckoView
|
viewModel.state.observe(this@LoginEntryView, Observer {
|
||||||
|
when (it.state) {
|
||||||
|
LoginEntryState.FAILED -> {
|
||||||
|
router.popController(this)
|
||||||
|
}
|
||||||
|
LoginEntryState.PENDING_CHECK -> {
|
||||||
|
// everything is already setup in XML
|
||||||
|
}
|
||||||
|
LoginEntryState.CHECKING -> {
|
||||||
|
view.progressBar.isVisible = true
|
||||||
|
geckoView.isVisible = false
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
if (router?.hasRootController() == true) {
|
||||||
|
router.popController(this)
|
||||||
|
} else {
|
||||||
|
router.setRoot(RouterTransaction.with(ConversationsListView())
|
||||||
|
.pushChangeHandler(HorizontalChangeHandler())
|
||||||
|
.popChangeHandler(HorizontalChangeHandler()))
|
||||||
|
}
|
||||||
|
// all good, proceed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
geckoView = view.geckoView
|
||||||
activity?.let {
|
activity?.let {
|
||||||
val settings = GeckoSessionSettings.Builder()
|
val settings = GeckoSessionSettings.Builder()
|
||||||
//.usePrivateMode(true)
|
//.usePrivateMode(true)
|
||||||
@ -79,8 +107,7 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
|
|
||||||
geckoView.autofillEnabled = true
|
geckoView.autofillEnabled = true
|
||||||
geckoSession = GeckoSession(settings.build())
|
geckoSession = GeckoSession(settings.build())
|
||||||
val runtime = GeckoRuntime.create(it)
|
geckoSession.open(geckoRuntime)
|
||||||
geckoSession.open(runtime)
|
|
||||||
geckoSession.progressDelegate = createProgressDelegate()
|
geckoSession.progressDelegate = createProgressDelegate()
|
||||||
geckoSession.navigationDelegate = createNavigationDelegate()
|
geckoSession.navigationDelegate = createNavigationDelegate()
|
||||||
geckoView.setSession(geckoSession)
|
geckoView.setSession(geckoSession)
|
||||||
@ -89,20 +116,6 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,20 +123,17 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
return object : GeckoSession.NavigationDelegate {
|
return object : GeckoSession.NavigationDelegate {
|
||||||
override fun onLoadRequest(p0: GeckoSession, p1: GeckoSession.NavigationDelegate.LoadRequest): GeckoResult<AllowOrDeny>? {
|
override fun onLoadRequest(p0: GeckoSession, p1: GeckoSession.NavigationDelegate.LoadRequest): GeckoResult<AllowOrDeny>? {
|
||||||
if (p1.uri.startsWith(assembledPrefix)) {
|
if (p1.uri.startsWith(assembledPrefix)) {
|
||||||
|
viewModel.parseData(assembledPrefix, dataSeparator, p1.uri)
|
||||||
return GeckoResult.DENY
|
return GeckoResult.DENY
|
||||||
}
|
}
|
||||||
return super.onLoadRequest(p0, p1)
|
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 {
|
private fun createProgressDelegate(): GeckoSession.ProgressDelegate {
|
||||||
return object : GeckoSession.ProgressDelegate {
|
return object : GeckoSession.ProgressDelegate {
|
||||||
|
private var initialLoad = true
|
||||||
|
|
||||||
override fun onPageStop(session: GeckoSession, success: Boolean) = Unit
|
override fun onPageStop(session: GeckoSession, success: Boolean) = Unit
|
||||||
|
|
||||||
@ -135,8 +145,16 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
|
|||||||
override fun onPageStart(session: GeckoSession, url: String) = Unit
|
override fun onPageStart(session: GeckoSession, url: String) = Unit
|
||||||
|
|
||||||
override fun onProgressChange(session: GeckoSession, progress: Int) {
|
override fun onProgressChange(session: GeckoSession, progress: Int) {
|
||||||
view?.pageProgressBar?.progress = progress
|
if (initialLoad) {
|
||||||
view?.pageProgressBar?.isVisible = progress in 1..99
|
view?.pageProgressBar?.progress = progress
|
||||||
|
view?.pageProgressBar?.isVisible = progress in 1..99
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress == 100) {
|
||||||
|
initialLoad = false
|
||||||
|
view?.pageProgressBar?.isVisible = false
|
||||||
|
view?.geckoView?.isVisible = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,13 +148,13 @@ class LoginEntryViewModel constructor(
|
|||||||
private fun registerForPush() {
|
private fun registerForPush() {
|
||||||
val token = appPreferences.pushToken
|
val token = appPreferences.pushToken
|
||||||
if (!token.isNullOrBlank()) {
|
if (!token.isNullOrBlank()) {
|
||||||
|
registerForPushWithServer(token)
|
||||||
} else {
|
} else {
|
||||||
state.postValue(LoginEntryStateWrapper(LoginEntryState.OK, LoginEntryStateClarification.PUSH_REGISTRATION_MISSING_TOKEN))
|
state.postValue(LoginEntryStateWrapper(LoginEntryState.OK, LoginEntryStateClarification.PUSH_REGISTRATION_MISSING_TOKEN))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerForPushWithServer() {
|
private fun registerForPushWithServer(token: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,10 @@ 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.domain.usecases.GetProfileUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetSignalingSettingsUseCase
|
||||||
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
|
|
||||||
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 {
|
class LoginEntryViewModelFactory constructor(private val application: Application, private val getProfileUseCase: GetProfileUseCase, private val getCapabilitiesUseCase: GetCapabilitiesUseCase, private val getSignalingSettingsUseCase: GetSignalingSettingsUseCase, private val appPreferences: AppPreferences, private val usersRepository: UsersRepository) : ViewModelProvider.Factory {
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return LoginEntryViewModel(application, getProfileUseCase, getCapabilitiesUseCase, getSignalingSettingsUseCase, usersRepository) as T
|
return LoginEntryViewModel(application, getProfileUseCase, getCapabilitiesUseCase, getSignalingSettingsUseCase, appPreferences, usersRepository) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,16 +64,6 @@
|
|||||||
app:layout_flexGrow="1"
|
app:layout_flexGrow="1"
|
||||||
app:layout_wrapBefore="true"
|
app:layout_wrapBefore="true"
|
||||||
tools:text="Hello, this is me!" />
|
tools:text="Hello, this is me!" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/quotedMessageTime"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_alignSelf="center"
|
|
||||||
android:textColor="@color/warm_grey_four"
|
|
||||||
tools:text="16:08" />
|
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
@ -2,21 +2,33 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:background="@color/colorPrimary">
|
android:background="@color/colorPrimary">
|
||||||
|
|
||||||
<ViewStub
|
<ProgressBar
|
||||||
android:id="@+id/stubImport"
|
android:id="@+id/pageProgressBar"
|
||||||
android:layout_width="fill_parent"
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_gravity="bottom"
|
android:layout_height="3dp"
|
||||||
android:inflatedId="@+id/webViewImportLayout"
|
android:layout_centerInParent="true"
|
||||||
android:layout="@layout/login_web_view" />
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:visibility="visible"/>
|
||||||
|
|
||||||
|
<org.mozilla.geckoview.GeckoView
|
||||||
|
android:id="@+id/geckoView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorPrimary"
|
||||||
|
tools:context=".MainActivity"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="@dimen/item_height"
|
android:layout_width="@dimen/item_height"
|
||||||
android:layout_height="@dimen/item_height"
|
android:layout_height="@dimen/item_height"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="gone"
|
||||||
android:indeterminate="true"
|
android:indeterminate="true"
|
||||||
android:indeterminateTint="@color/white"
|
android:indeterminateTint="@color/white"
|
||||||
android:indeterminateTintMode="src_in" />
|
android:indeterminateTintMode="src_in" />
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
<?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>
|
|
Loading…
Reference in New Issue
Block a user