Merge pull request #4777 from nextcloud/renovate/com.android.tools.build-gradle-8.x

fix(deps): update dependency com.android.tools.build:gradle to v8.9.0
This commit is contained in:
github-actions[bot] 2025-03-19 17:23:29 +00:00 committed by GitHub
commit b8e6339ca7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 1586 additions and 575 deletions

View File

@ -12,7 +12,6 @@ import android.accounts.Account
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.security.KeyChain import android.security.KeyChain
import android.text.TextUtils import android.text.TextUtils
@ -22,22 +21,24 @@ import android.view.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.widget.TextView import android.widget.TextView
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.databinding.ActivityServerSelectionBinding import com.nextcloud.talk.databinding.ActivityServerSelectionBinding
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
import com.nextcloud.talk.models.json.generic.Status import com.nextcloud.talk.models.json.generic.Status
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.AccountUtils import com.nextcloud.talk.utils.AccountUtils
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.UriUtils import com.nextcloud.talk.utils.UriUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.ADD_ADDITIONAL_ACCOUNT import com.nextcloud.talk.utils.bundle.BundleKeys.ADD_ADDITIONAL_ACCOUNT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
@ -45,7 +46,6 @@ import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.security.cert.CertificateException import java.security.cert.CertificateException
import javax.inject.Inject import javax.inject.Inject
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class ServerSelectionActivity : BaseActivity() { class ServerSelectionActivity : BaseActivity() {
@ -198,10 +198,7 @@ class ServerSelectionActivity : BaseActivity() {
binding.importOrChooseProviderText.setOnClickListener { binding.importOrChooseProviderText.setOnClickListener {
val browserIntent = Intent( val browserIntent = Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse( resources!!.getString(R.string.nc_providers_url).toUri()
resources!!
.getString(R.string.nc_providers_url)
)
) )
startActivity(browserIntent) startActivity(browserIntent)
} }

View File

@ -12,8 +12,8 @@ import android.accounts.Account
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.drawable.toDrawable
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import autodagger.AutoInjector import autodagger.AutoInjector
@ -21,6 +21,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.adapters.items.AdvancedUserItem import com.nextcloud.talk.adapters.items.AdvancedUserItem
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivitySwitchAccountBinding import com.nextcloud.talk.databinding.ActivitySwitchAccountBinding
import com.nextcloud.talk.models.ImportAccount import com.nextcloud.talk.models.ImportAccount
@ -38,7 +39,6 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import org.osmdroid.config.Configuration import org.osmdroid.config.Configuration
import java.net.CookieManager import java.net.CookieManager
import javax.inject.Inject import javax.inject.Inject
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
/** /**
* Parts related to account import were either copied from or inspired by the great work done by David Luhmer at: * Parts related to account import were either copied from or inspired by the great work done by David Luhmer at:
@ -108,7 +108,7 @@ class SwitchAccountActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
supportActionBar?.title = resources!!.getString(R.string.nc_select_an_account) supportActionBar?.title = resources!!.getString(R.string.nc_select_an_account)
} }

View File

@ -49,6 +49,9 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.graphics.toColorInt
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
import com.bluelinelabs.logansquare.LoganSquare import com.bluelinelabs.logansquare.LoganSquare
@ -1262,7 +1265,7 @@ class CallActivity : CallBaseActivity() {
.subHeadingTvColor(resources.getColor(R.color.bg_default, null)) .subHeadingTvColor(resources.getColor(R.color.bg_default, null))
.subHeadingTvSize(SPOTLIGHT_SUBHEADING_SIZE) .subHeadingTvSize(SPOTLIGHT_SUBHEADING_SIZE)
.subHeadingTvText(resources.getString(R.string.nc_push_to_talk_desc)) .subHeadingTvText(resources.getString(R.string.nc_push_to_talk_desc))
.maskColor(Color.parseColor("#dc000000")) .maskColor("#dc000000".toColorInt())
.target(binding!!.microphoneButton) .target(binding!!.microphoneButton)
.lineAnimDuration(FADE_IN_ANIMATION_DURATION) .lineAnimDuration(FADE_IN_ANIMATION_DURATION)
.enableDismissAfterShown(true) .enableDismissAfterShown(true)
@ -2532,7 +2535,7 @@ class CallActivity : CallBaseActivity() {
val screenWidthPx = displayMetrics.widthPixels val screenWidthPx = displayMetrics.widthPixels
val screenWidthDp = DisplayUtils.convertPixelToDp(screenWidthPx.toFloat(), applicationContext).toInt() val screenWidthDp = DisplayUtils.convertPixelToDp(screenWidthPx.toFloat(), applicationContext).toInt()
var newXafterRotate = 0f var newXafterRotate = 0f
val newYafterRotate: Float = if (binding!!.callInfosLinearLayout.visibility == View.VISIBLE) { val newYafterRotate: Float = if (binding!!.callInfosLinearLayout.isVisible) {
Y_POS_CALL_INFO Y_POS_CALL_INFO
} else { } else {
Y_POS_NO_CALL_INFO Y_POS_NO_CALL_INFO
@ -2825,7 +2828,7 @@ class CallActivity : CallBaseActivity() {
val ringtoneUri: Uri? = if (isIncomingCallFromNotification) { val ringtoneUri: Uri? = if (isIncomingCallFromNotification) {
getCallRingtoneUri(applicationContext, appPreferences) getCallRingtoneUri(applicationContext, appPreferences)
} else { } else {
Uri.parse("android.resource://" + applicationContext.packageName + "/raw/tr110_1_kap8_3_freiton1") ("android.resource://" + applicationContext.packageName + "/raw/tr110_1_kap8_3_freiton1").toUri()
} }
if (ringtoneUri != null) { if (ringtoneUri != null) {
mediaPlayer = MediaPlayer() mediaPlayer = MediaPlayer()

View File

@ -8,9 +8,9 @@
package com.nextcloud.talk.adapters.items package com.nextcloud.talk.adapters.items
import android.accounts.Account import android.accounts.Account
import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.adapters.items.AdvancedUserItem.UserItemViewHolder import com.nextcloud.talk.adapters.items.AdvancedUserItem.UserItemViewHolder
@ -75,9 +75,9 @@ class AdvancedUserItem(
holder.binding.userName.text = model.displayName holder.binding.userName.text = model.displayName
} }
if (user != null && !TextUtils.isEmpty(user.baseUrl)) { if (user != null && !TextUtils.isEmpty(user.baseUrl)) {
val host = Uri.parse(user.baseUrl).host val host = user.baseUrl!!.toUri().host
if (!TextUtils.isEmpty(host)) { if (!TextUtils.isEmpty(host)) {
holder.binding.account.text = Uri.parse(user.baseUrl).host holder.binding.account.text = user.baseUrl!!.toUri().host
} else { } else {
holder.binding.account.text = user.baseUrl holder.binding.account.text = user.baseUrl
} }

View File

@ -10,11 +10,11 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import coil.load import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.android.common.ui.theme.utils.ColorRole
@ -100,7 +100,7 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
} }
binding.cardView.setOnClickListener { binding.cardView.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(cardLink)) val browserIntent = Intent(Intent.ACTION_VIEW, cardLink!!.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)
} }

View File

@ -12,13 +12,13 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import coil.load import coil.load
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@ -223,7 +223,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return if (url != null && UriUtils.hasHttpProtocolPrefixed(url) return if (url != null && UriUtils.hasHttpProtocolPrefixed(url)
) { ) {
view?.context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) view?.context?.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()))
true true
} else { } else {
false false
@ -259,7 +259,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
private fun openGeoLink() { private fun openGeoLink() {
if (!locationGeoLink.isNullOrEmpty()) { if (!locationGeoLink.isNullOrEmpty()) {
val geoLinkWithMarker = addMarkerToGeoLink(locationGeoLink!!) val geoLinkWithMarker = addMarkerToGeoLink(locationGeoLink!!)
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(geoLinkWithMarker)) val browserIntent = Intent(Intent.ACTION_VIEW, geoLinkWithMarker.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)
} else { } else {

View File

@ -8,13 +8,13 @@ package com.nextcloud.talk.adapters.messages
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.core.net.toUri
import coil.load import coil.load
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.databinding.ReferenceInsideMessageBinding
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.databinding.ReferenceInsideMessageBinding
import com.nextcloud.talk.models.json.opengraph.OpenGraphOverall import com.nextcloud.talk.models.json.opengraph.OpenGraphOverall
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import io.reactivex.Observer import io.reactivex.Observer
@ -82,7 +82,7 @@ class LinkPreview {
} }
binding.referenceWrapper.setOnClickListener { binding.referenceWrapper.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(referenceLink)) val browserIntent = Intent(Intent.ACTION_VIEW, referenceLink!!.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)
} }

View File

@ -11,12 +11,12 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import coil.load import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.android.common.ui.theme.utils.ColorRole
@ -121,7 +121,7 @@ class OutcomingDeckCardViewHolder(
binding.checkMark.contentDescription = readStatusContentDescriptionString binding.checkMark.contentDescription = readStatusContentDescriptionString
binding.cardView.setOnClickListener { binding.cardView.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(cardLink)) val browserIntent = Intent(Intent.ACTION_VIEW, cardLink!!.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)
} }

View File

@ -11,7 +11,6 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.MotionEvent import android.view.MotionEvent
@ -19,6 +18,7 @@ import android.view.View
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import coil.load import coil.load
import com.google.android.flexbox.FlexboxLayout import com.google.android.flexbox.FlexboxLayout
@ -160,7 +160,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) :
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return if (url != null && UriUtils.hasHttpProtocolPrefixed(url) return if (url != null && UriUtils.hasHttpProtocolPrefixed(url)
) { ) {
view?.context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) view?.context?.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()))
true true
} else { } else {
false false
@ -259,7 +259,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) :
private fun openGeoLink() { private fun openGeoLink() {
if (!locationGeoLink.isNullOrEmpty()) { if (!locationGeoLink.isNullOrEmpty()) {
val geoLinkWithMarker = addMarkerToGeoLink(locationGeoLink!!) val geoLinkWithMarker = addMarkerToGeoLink(locationGeoLink!!)
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(geoLinkWithMarker)) val browserIntent = Intent(Intent.ACTION_VIEW, geoLinkWithMarker.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)
} else { } else {

View File

@ -13,7 +13,6 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Handler import android.os.Handler
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
@ -21,6 +20,7 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.emoji2.widget.EmojiTextView import androidx.emoji2.widget.EmojiTextView
import autodagger.AutoInjector import autodagger.AutoInjector
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
@ -29,12 +29,12 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.filebrowser.models.BrowserFile
import com.nextcloud.talk.filebrowser.webdav.ReadFilesystemOperation
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
import com.nextcloud.talk.extensions.loadChangelogBotAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar
import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.extensions.loadFederatedUserAvatar
import com.nextcloud.talk.filebrowser.models.BrowserFile
import com.nextcloud.talk.filebrowser.webdav.ReadFilesystemOperation
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
@ -140,7 +140,7 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) :
} else { } else {
if (message.messageType == ChatMessage.MessageType.SINGLE_LINK_IMAGE_MESSAGE.name) { if (message.messageType == ChatMessage.MessageType.SINGLE_LINK_IMAGE_MESSAGE.name) {
clickView!!.setOnClickListener { clickView!!.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(message.imageUrl)) val browserIntent = Intent(Intent.ACTION_VIEW, message.imageUrl!!.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context!!.startActivity(browserIntent) context!!.startActivity(browserIntent)
} }

View File

@ -9,7 +9,6 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
import android.text.TextPaint import android.text.TextPaint
@ -18,13 +17,14 @@ import android.text.style.ClickableSpan
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.databinding.ItemSystemMessageBinding
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.databinding.ItemSystemMessageBinding
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
@ -96,7 +96,7 @@ class SystemMessageViewHolder(itemView: View) : MessageHolders
if (newStartIndex != -1) { if (newStartIndex != -1) {
val clickableSpan = object : ClickableSpan() { val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) { override fun onClick(widget: View) {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) val browserIntent = Intent(Intent.ACTION_VIEW, link.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context?.startActivity(browserIntent) context?.startActivity(browserIntent)
} }

View File

@ -24,8 +24,6 @@ import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.AssetFileDescriptor import android.content.res.AssetFileDescriptor
import android.database.Cursor import android.database.Cursor
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -58,6 +56,8 @@ import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toUri
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.text.bold import androidx.core.text.bold
import androidx.emoji2.text.EmojiCompat import androidx.emoji2.text.EmojiCompat
@ -1022,24 +1022,20 @@ class ChatActivity :
} }
if (uiState.userAbsence.replacementUserDisplayName != null) { if (uiState.userAbsence.replacementUserDisplayName != null) {
var imageUri = Uri.parse( var imageUri = ApiUtils.getUrlForAvatar(
ApiUtils.getUrlForAvatar(
conversationUser?.baseUrl, conversationUser?.baseUrl,
uiState.userAbsence uiState.userAbsence
.replacementUserId, .replacementUserId,
false false
) ).toUri()
)
if (DisplayUtils.isDarkModeOn(context)) { if (DisplayUtils.isDarkModeOn(context)) {
imageUri = Uri.parse( imageUri = ApiUtils.getUrlForAvatarDarkTheme(
ApiUtils.getUrlForAvatarDarkTheme(
conversationUser?.baseUrl, conversationUser?.baseUrl,
uiState uiState
.userAbsence .userAbsence
.replacementUserId, .replacementUserId,
false false
) ).toUri()
)
} }
binding.outOfOfficeContainer.findViewById<TextView>(R.id.absenceReplacement).text = binding.outOfOfficeContainer.findViewById<TextView>(R.id.absenceReplacement).text =
context.resources.getString(R.string.user_absence_replacement) context.resources.getString(R.string.user_absence_replacement)
@ -1168,7 +1164,7 @@ class ChatActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
setActionBarTitle() setActionBarTitle()
viewThemeUtils.material.themeToolbar(binding.chatToolbar) viewThemeUtils.material.themeToolbar(binding.chatToolbar)
} }
@ -1511,7 +1507,7 @@ class ChatActivity :
) )
viewThemeUtils.talk.themeStatusDrawable(context, status) viewThemeUtils.talk.themeStatusDrawable(context, status)
binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_avatar) binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_avatar)
.setImageDrawable(BitmapDrawable(resources, bitmap)) .setImageDrawable(bitmap.toDrawable(resources))
binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status) binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status)
.setImageDrawable(status) .setImageDrawable(status)
binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status).contentDescription = binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status).contentDescription =
@ -1967,7 +1963,7 @@ class ChatActivity :
val filenamesWithLineBreaks = StringBuilder("\n") val filenamesWithLineBreaks = StringBuilder("\n")
for (file in filesToUpload) { for (file in filesToUpload) {
val filename = FileUtils.getFileName(Uri.parse(file), context) val filename = FileUtils.getFileName(file.toUri(), context)
filenamesWithLineBreaks.append(filename).append("\n") filenamesWithLineBreaks.append(filename).append("\n")
} }
@ -2043,7 +2039,7 @@ class ChatActivity :
val filenamesWithLineBreaks = StringBuilder("\n") val filenamesWithLineBreaks = StringBuilder("\n")
for (file in filesToUpload) { for (file in filesToUpload) {
val filename = FileUtils.getFileName(Uri.parse(file), context) val filename = FileUtils.getFileName(file.toUri(), context)
filenamesWithLineBreaks.append(filename).append("\n") filenamesWithLineBreaks.append(filename).append("\n")
} }

View File

@ -8,7 +8,6 @@
package com.nextcloud.talk.chat package com.nextcloud.talk.chat
import android.content.res.Resources import android.content.res.Resources
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -40,6 +39,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged import androidx.core.widget.doAfterTextChanged
import androidx.emoji2.widget.EmojiTextView import androidx.emoji2.widget.EmojiTextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@ -476,7 +477,7 @@ class MessageInputFragment : Fragment() {
binding.fragmentMessageInputView.messageSendButton.visibility = binding.fragmentMessageInputView.messageSendButton.visibility =
if (binding.fragmentMessageInputView.inputEditText.text.isEmpty() || if (binding.fragmentMessageInputView.inputEditText.text.isEmpty() ||
binding.fragmentEditView.editMessageView.visibility == View.VISIBLE binding.fragmentEditView.editMessageView.isVisible
) { ) {
View.GONE View.GONE
} else { } else {
@ -608,7 +609,7 @@ class MessageInputFragment : Fragment() {
private fun setupMentionAutocomplete() { private fun setupMentionAutocomplete() {
val elevation = MENTION_AUTO_COMPLETE_ELEVATION val elevation = MENTION_AUTO_COMPLETE_ELEVATION
resources.let { resources.let {
val backgroundDrawable = ColorDrawable(it.getColor(R.color.bg_default, null)) val backgroundDrawable = it.getColor(R.color.bg_default, null).toDrawable()
val presenter = MentionAutocompletePresenter( val presenter = MentionAutocompletePresenter(
requireContext(), requireContext(),
chatActivity.roomToken, chatActivity.roomToken,

View File

@ -13,7 +13,6 @@ package com.nextcloud.talk.conversationinfo
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
@ -27,6 +26,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -321,7 +321,7 @@ class ConversationInfoActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(android.R.color.transparent, null).toDrawable())
supportActionBar?.title = if (hasAvatarSpacing) { supportActionBar?.title = if (hasAvatarSpacing) {
" " + resources!!.getString(R.string.nc_conversation_menu_conversation_info) " " + resources!!.getString(R.string.nc_conversation_menu_conversation_info)
} else { } else {

View File

@ -8,7 +8,6 @@
package com.nextcloud.talk.conversationinfoedit package com.nextcloud.talk.conversationinfoedit
import android.app.Activity import android.app.Activity
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.text.InputFilter import android.text.InputFilter
import android.text.TextUtils import android.text.TextUtils
@ -18,6 +17,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -252,7 +252,7 @@ class ConversationInfoEditActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(android.R.color.transparent, null).toDrawable())
supportActionBar?.title = resources!!.getString(R.string.nc_conversation_menu_conversation_info) supportActionBar?.title = resources!!.getString(R.string.nc_conversation_menu_conversation_info)
viewThemeUtils.material.themeToolbar(binding.conversationInfoEditToolbar) viewThemeUtils.material.themeToolbar(binding.conversationInfoEditToolbar)
@ -319,7 +319,7 @@ class ConversationInfoEditActivity : BaseActivity() {
conversation!!.name conversation!!.name
) )
) { ) {
conversation!!.name?.let { binding.avatarImage.loadUserAvatar(conversationUser, it, true, false) } conversation!!.name.let { binding.avatarImage.loadUserAvatar(conversationUser, it, true, false) }
} }
ConversationEnums.ConversationType.ROOM_GROUP_CALL, ConversationEnums.ConversationType.ROOM_PUBLIC_CALL -> { ConversationEnums.ConversationType.ROOM_GROUP_CALL, ConversationEnums.ConversationType.ROOM_PUBLIC_CALL -> {

View File

@ -19,9 +19,7 @@ import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -42,6 +40,8 @@ import androidx.annotation.OptIn
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toUri
import androidx.core.view.MenuItemCompat import androidx.core.view.MenuItemCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
@ -638,7 +638,7 @@ class ConversationsListActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
supportActionBar?.title = resources!!.getString(R.string.nc_app_product_name) supportActionBar?.title = resources!!.getString(R.string.nc_app_product_name)
viewThemeUtils.material.themeToolbar(binding.conversationListToolbar) viewThemeUtils.material.themeToolbar(binding.conversationListToolbar)
} }
@ -1473,7 +1473,7 @@ class ConversationsListActivity :
if (platformPermissionUtil.isFilesPermissionGranted()) { if (platformPermissionUtil.isFilesPermissionGranted()) {
val fileNamesWithLineBreaks = StringBuilder("\n") val fileNamesWithLineBreaks = StringBuilder("\n")
for (file in filesToShare!!) { for (file in filesToShare!!) {
val filename = FileUtils.getFileName(Uri.parse(file), context) val filename = FileUtils.getFileName(file.toUri(), context)
fileNamesWithLineBreaks.append(filename).append("\n") fileNamesWithLineBreaks.append(filename).append("\n")
} }
val confirmationQuestion: String = if (filesToShare!!.size == 1) { val confirmationQuestion: String = if (filesToShare!!.size == 1) {
@ -1900,11 +1900,11 @@ class ConversationsListActivity :
.setPositiveButton(R.string.nc_dialog_outdated_client_option_update) { _, _ -> .setPositiveButton(R.string.nc_dialog_outdated_client_option_update) { _, _ ->
try { try {
startActivity( startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(CLIENT_UPGRADE_MARKET_LINK + packageName)) Intent(Intent.ACTION_VIEW, (CLIENT_UPGRADE_MARKET_LINK + packageName).toUri())
) )
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
startActivity( startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(CLIENT_UPGRADE_GPLAY_LINK + packageName)) Intent(Intent.ACTION_VIEW, (CLIENT_UPGRADE_GPLAY_LINK + packageName).toUri())
) )
} }
} }

View File

@ -10,7 +10,6 @@ import android.annotation.SuppressLint
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Build.MANUFACTURER import android.os.Build.MANUFACTURER
import android.os.Build.MODEL import android.os.Build.MODEL
@ -28,6 +27,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R import com.nextcloud.talk.R
@ -35,8 +35,8 @@ import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
import com.nextcloud.talk.components.StandardAppBar
import com.nextcloud.talk.components.SetupSystemBars import com.nextcloud.talk.components.SetupSystemBars
import com.nextcloud.talk.components.StandardAppBar
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.BrandingUtils import com.nextcloud.talk.utils.BrandingUtils
import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.ClosedInterfaceImpl
@ -151,7 +151,7 @@ class DiagnoseActivity : BaseActivity() {
val intent = Intent(Intent.ACTION_SENDTO).apply { val intent = Intent(Intent.ACTION_SENDTO).apply {
val appName = context.resources.getString(R.string.nc_app_product_name) val appName = context.resources.getString(R.string.nc_app_product_name)
data = Uri.parse("mailto:") data = "mailto:".toUri()
putExtra(Intent.EXTRA_SUBJECT, appName) putExtra(Intent.EXTRA_SUBJECT, appName)
putExtra(Intent.EXTRA_TEXT, text) putExtra(Intent.EXTRA_TEXT, text)
} }
@ -166,7 +166,7 @@ class DiagnoseActivity : BaseActivity() {
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources!!.getString(R.string.nc_talk_android_issues_url)) resources!!.getString(R.string.nc_talk_android_issues_url).toUri()
) )
) )
} }

View File

@ -11,18 +11,17 @@
package com.nextcloud.talk.extensions package com.nextcloud.talk.extensions
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.util.Log import android.util.Log
import android.widget.ImageView import android.widget.ImageView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.toDrawable
import coil.annotation.ExperimentalCoilApi import coil.annotation.ExperimentalCoilApi
import coil.imageLoader import coil.imageLoader
import coil.load import coil.load
@ -326,7 +325,7 @@ fun ImageView.loadChangelogBotAvatar(): io.reactivex.disposables.Disposable {
fun ImageView.loadBotsAvatar(): io.reactivex.disposables.Disposable { fun ImageView.loadBotsAvatar(): io.reactivex.disposables.Disposable {
val layers = arrayOfNulls<Drawable>(2) val layers = arrayOfNulls<Drawable>(2)
layers[0] = ColorDrawable(context.getColor(R.color.black)) layers[0] = context.getColor(R.color.black).toDrawable()
layers[1] = TextDrawable(context, ">") layers[1] = TextDrawable(context, ">")
val layerDrawable = LayerDrawable(layers) val layerDrawable = LayerDrawable(layers)
val data: Any = layerDrawable val data: Any = layerDrawable
@ -386,7 +385,7 @@ fun ImageView.loadGuestAvatar(baseUrl: String, name: String, big: Boolean): io.r
@Suppress("MagicNumber") @Suppress("MagicNumber")
private fun createTextDrawable(context: Context, letter: String): Drawable { private fun createTextDrawable(context: Context, letter: String): Drawable {
val size = 100 val size = 100
val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888) val bitmap = createBitmap(size, size)
val canvas = Canvas(bitmap) val canvas = Canvas(bitmap)
val paint = Paint().apply { val paint = Paint().apply {
@ -406,7 +405,7 @@ private fun createTextDrawable(context: Context, letter: String): Drawable {
val yPos = (canvas.height / 2 - (textPaint.descent() + textPaint.ascent()) / 2) val yPos = (canvas.height / 2 - (textPaint.descent() + textPaint.ascent()) / 2)
canvas.drawText(letter.take(1), xPos, yPos, textPaint) canvas.drawText(letter.take(1), xPos, yPos, textPaint)
return BitmapDrawable(context.resources, bitmap) return bitmap.toDrawable(context.resources)
} }
private class DisposableWrapper(private val disposable: coil.request.Disposable) : io.reactivex.disposables private class DisposableWrapper(private val disposable: coil.request.Disposable) : io.reactivex.disposables

View File

@ -7,10 +7,10 @@
package com.nextcloud.talk.invitation package com.nextcloud.talk.invitation
import android.content.Intent import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.core.graphics.drawable.toDrawable
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@ -168,7 +168,7 @@ class InvitationsActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
viewThemeUtils.material.themeToolbar(binding.invitationsToolbar) viewThemeUtils.material.themeToolbar(binding.invitationsToolbar)
} }
} }

View File

@ -15,7 +15,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -33,6 +32,7 @@ import androidx.core.app.Person
import androidx.core.app.RemoteInput import androidx.core.app.RemoteInput
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import androidx.emoji2.text.EmojiCompat import androidx.emoji2.text.EmojiCompat
import androidx.work.Data import androidx.work.Data
import androidx.work.Worker import androidx.work.Worker
@ -272,7 +272,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
val soundUri = getCallRingtoneUri(applicationContext, appPreferences) val soundUri = getCallRingtoneUri(applicationContext, appPreferences)
val notificationChannelId = NotificationUtils.NotificationChannels.NOTIFICATION_CHANNEL_CALLS_V4.name val notificationChannelId = NotificationUtils.NotificationChannels.NOTIFICATION_CHANNEL_CALLS_V4.name
val uri = Uri.parse(signatureVerification.user!!.baseUrl!!) val uri = signatureVerification.user!!.baseUrl!!.toUri()
val baseUrl = uri.host val baseUrl = uri.host
val notification = val notification =
@ -499,7 +499,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
0 0
} }
val pendingIntent = PendingIntent.getActivity(context, requestCode, intent, intentFlag) val pendingIntent = PendingIntent.getActivity(context, requestCode, intent, intentFlag)
val uri = Uri.parse(signatureVerification.user!!.baseUrl!!) val uri = signatureVerification.user!!.baseUrl!!.toUri()
val baseUrl = uri.host val baseUrl = uri.host
var contentTitle: CharSequence? = "" var contentTitle: CharSequence? = ""

View File

@ -19,6 +19,7 @@ import android.os.Bundle
import android.os.SystemClock import android.os.SystemClock
import android.util.Log import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.net.toUri
import androidx.work.Data import androidx.work.Data
import androidx.work.ExistingWorkPolicy import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
@ -110,7 +111,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
require(sourceFile.isNotEmpty()) require(sourceFile.isNotEmpty())
checkNotNull(roomToken) checkNotNull(roomToken)
val sourceFileUri = Uri.parse(sourceFile) val sourceFileUri = sourceFile.toUri()
fileName = FileUtils.getFileName(sourceFileUri, context) fileName = FileUtils.getFileName(sourceFileUri, context)
file = FileUtils.getFileFromUri(context, sourceFileUri) file = FileUtils.getFileFromUri(context, sourceFileUri)
val remotePath = getRemotePath(currentUser) val remotePath = getRemotePath(currentUser)

View File

@ -9,7 +9,6 @@ package com.nextcloud.talk.location
import android.app.SearchManager import android.app.SearchManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.text.InputType import android.text.InputType
import android.util.Log import android.util.Log
@ -17,6 +16,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.graphics.drawable.toDrawable
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -132,7 +132,7 @@ class GeocodingActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
supportActionBar?.title = "" supportActionBar?.title = ""
viewThemeUtils.material.themeToolbar(binding.geocodingToolbar) viewThemeUtils.material.themeToolbar(binding.geocodingToolbar)
} }

View File

@ -13,7 +13,6 @@ import android.app.SearchManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.location.Location import android.location.Location
import android.location.LocationListener import android.location.LocationListener
import android.location.LocationManager import android.location.LocationManager
@ -28,6 +27,7 @@ import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.MenuItemCompat import androidx.core.view.MenuItemCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import autodagger.AutoInjector import autodagger.AutoInjector
@ -178,7 +178,7 @@ class LocationPickerActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(android.R.color.transparent, null).toDrawable())
supportActionBar?.title = context.getString(R.string.nc_share_location) supportActionBar?.title = context.getString(R.string.nc_share_location)
viewThemeUtils.material.themeToolbar(binding.locationPickerToolbar) viewThemeUtils.material.themeToolbar(binding.locationPickerToolbar)
} }

View File

@ -7,9 +7,9 @@
package com.nextcloud.talk.openconversations package com.nextcloud.talk.openconversations
import android.content.Intent import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.core.graphics.drawable.toDrawable
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
@ -143,7 +143,7 @@ class ListOpenConversationsActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
viewThemeUtils.material.themeToolbar(binding.openConversationsToolbar) viewThemeUtils.material.themeToolbar(binding.openConversationsToolbar)
} }
} }

View File

@ -11,8 +11,6 @@ package com.nextcloud.talk.profile
import android.app.Activity import android.app.Activity
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextUtils import android.text.TextUtils
@ -27,7 +25,9 @@ import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.net.toUri
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import autodagger.AutoInjector import autodagger.AutoInjector
@ -208,7 +208,7 @@ class ProfileActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(android.R.color.transparent, null).toDrawable())
supportActionBar?.title = context.getString(R.string.nc_profile_personal_info_title) supportActionBar?.title = context.getString(R.string.nc_profile_personal_info_title)
viewThemeUtils.material.themeToolbar(binding.profileToolbar) viewThemeUtils.material.themeToolbar(binding.profileToolbar)
} }
@ -313,7 +313,7 @@ class ProfileActivity : BaseActivity() {
private fun showUserProfile() { private fun showUserProfile() {
if (currentUser!!.baseUrl != null) { if (currentUser!!.baseUrl != null) {
binding.userinfoBaseurl.text = Uri.parse(currentUser!!.baseUrl!!).host binding.userinfoBaseurl.text = currentUser!!.baseUrl!!.toUri().host
} }
DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false) DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false)
if (!TextUtils.isEmpty(userInfo?.displayName)) { if (!TextUtils.isEmpty(userInfo?.displayName)) {

View File

@ -20,7 +20,6 @@ import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.drawable.ColorDrawable
import android.media.RingtoneManager import android.media.RingtoneManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -35,6 +34,8 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toUri
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
@ -199,7 +200,7 @@ class SettingsActivity :
registerChangeListeners() registerChangeListeners()
if (currentUser != null) { if (currentUser != null) {
binding.domainText.text = Uri.parse(currentUser!!.baseUrl).host binding.domainText.text = currentUser!!.baseUrl!!.toUri().host
setupServerAgeWarning() setupServerAgeWarning()
if (currentUser!!.displayName != null) { if (currentUser!!.displayName != null) {
binding.nameText.text = currentUser!!.displayName binding.nameText.text = currentUser!!.displayName
@ -260,7 +261,7 @@ class SettingsActivity :
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(android.R.color.transparent, null).toDrawable())
supportActionBar?.title = context.getString(R.string.nc_settings) supportActionBar?.title = context.getString(R.string.nc_settings)
viewThemeUtils.material.themeToolbar(binding.settingsToolbar) viewThemeUtils.material.themeToolbar(binding.settingsToolbar)
} }
@ -441,7 +442,7 @@ class SettingsActivity :
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources.getString(R.string.notification_checklist_url)) resources.getString(R.string.notification_checklist_url).toUri()
) )
) )
} }
@ -449,7 +450,7 @@ class SettingsActivity :
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources.getString(R.string.dontkillmyapp_url)) resources.getString(R.string.dontkillmyapp_url).toUri()
) )
) )
} }
@ -503,7 +504,7 @@ class SettingsActivity :
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources!!.getString(R.string.nc_source_code_url)) resources!!.getString(R.string.nc_source_code_url).toUri()
) )
) )
} }
@ -525,7 +526,7 @@ class SettingsActivity :
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources!!.getString(R.string.nc_privacy_url)) resources!!.getString(R.string.nc_privacy_url).toUri()
) )
) )
} }
@ -540,7 +541,7 @@ class SettingsActivity :
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(resources!!.getString(R.string.nc_gpl3_url)) resources!!.getString(R.string.nc_gpl3_url).toUri()
) )
) )
} }

View File

@ -7,8 +7,8 @@
*/ */
package com.nextcloud.talk.shareditems.repositories package com.nextcloud.talk.shareditems.repositories
import android.net.Uri
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
@ -135,7 +135,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
actorParameters["id"]!!, actorParameters["id"]!!,
actorParameters["name"]!!, actorParameters["name"]!!,
dateTime, dateTime,
Uri.parse(objectParameters["id"]!!.replace("geo:", "geo:0,0?z=11&q=")) objectParameters["id"]!!.replace("geo:", "geo:0,0?z=11&q=").toUri()
) )
} }
@ -146,7 +146,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
actorParameters["id"]!!, actorParameters["id"]!!,
actorParameters["name"]!!, actorParameters["name"]!!,
dateTime, dateTime,
Uri.parse(objectParameters["link"]!!) objectParameters["link"]!!.toUri()
) )
} }
@ -168,7 +168,7 @@ class SharedItemsRepositoryImpl @Inject constructor(private val ncApi: NcApi, pr
return ncApi.getSharedItemsOverview( return ncApi.getSharedItemsOverview(
credentials, credentials,
ApiUtils.getUrlForChatSharedItemsOverview(1, parameters.baseUrl!!, parameters.roomToken), ApiUtils.getUrlForChatSharedItemsOverview(1, parameters.baseUrl, parameters.roomToken),
1 1
).map { ).map {
val types = mutableSetOf<SharedItemType>() val types = mutableSetOf<SharedItemType>()

View File

@ -11,13 +11,13 @@ import android.app.AlertDialog
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod import android.text.method.ScrollingMovementMethod
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.core.graphics.drawable.toDrawable
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -130,7 +130,7 @@ class TranslateActivity : BaseActivity() {
} }
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent, null))) supportActionBar?.setIcon(resources!!.getColor(R.color.transparent, null).toDrawable())
supportActionBar?.title = resources!!.getString(R.string.translation) supportActionBar?.title = resources!!.getString(R.string.translation)
viewThemeUtils.material.themeToolbar(binding.translationToolbar) viewThemeUtils.material.themeToolbar(binding.translationToolbar)
} }

View File

@ -14,16 +14,17 @@ import android.graphics.Paint
import android.util.AttributeSet import android.util.AttributeSet
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatSeekBar import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.graphics.toColorInt
import com.nextcloud.talk.utils.AudioUtils import com.nextcloud.talk.utils.AudioUtils
import kotlin.math.roundToInt import kotlin.math.roundToInt
class WaveformSeekBar : AppCompatSeekBar { class WaveformSeekBar : AppCompatSeekBar {
@ColorInt @ColorInt
private var primary: Int = Color.parseColor("#679ff5") private var primary: Int = "#679ff5".toColorInt()
@ColorInt @ColorInt
private var secondary: Int = Color.parseColor("#a6c6f7") private var secondary: Int = "#a6c6f7".toColorInt()
private var rawData: FloatArray = floatArrayOf() private var rawData: FloatArray = floatArrayOf()
private var waveData: FloatArray = floatArrayOf() private var waveData: FloatArray = floatArrayOf()
private var savedMeasure: Int = 0 private var savedMeasure: Int = 0

View File

@ -12,16 +12,17 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.bottomsheet.items.BasicListItemWithImage
import com.nextcloud.talk.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.bottomsheet.items.listItemsWithImage
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.hovercard.HoverCardAction import com.nextcloud.talk.models.json.hovercard.HoverCardAction
import com.nextcloud.talk.models.json.hovercard.HoverCardOverall import com.nextcloud.talk.models.json.hovercard.HoverCardOverall
@ -161,14 +162,14 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User, val viewThemeUti
private fun composeEmail(address: String, context: Context) { private fun composeEmail(address: String, context: Context) {
val addresses = arrayListOf(address) val addresses = arrayListOf(address)
val intent = Intent(Intent.ACTION_SENDTO).apply { val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:") // only email apps should handle this data = "mailto:".toUri() // only email apps should handle this
putExtra(Intent.EXTRA_EMAIL, addresses) putExtra(Intent.EXTRA_EMAIL, addresses)
} }
context.startActivity(intent) context.startActivity(intent)
} }
private fun openProfile(hyperlink: String, context: Context) { private fun openProfile(hyperlink: String, context: Context) {
val webpage: Uri = Uri.parse(hyperlink) val webpage: Uri = hyperlink.toUri()
val intent = Intent(Intent.ACTION_VIEW, webpage) val intent = Intent(Intent.ACTION_VIEW, webpage)
context.startActivity(intent) context.startActivity(intent)
} }

View File

@ -10,11 +10,11 @@ package com.nextcloud.talk.ui.dialog
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Dialog import android.app.Dialog
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import autodagger.AutoInjector import autodagger.AutoInjector
@ -78,7 +78,7 @@ class ChooseAccountShareToDialogFragment : DialogFragment() {
if (user != null) { if (user != null) {
binding!!.currentAccount.userName.text = user.displayName binding!!.currentAccount.userName.text = user.displayName
binding!!.currentAccount.ticker.visibility = View.GONE binding!!.currentAccount.ticker.visibility = View.GONE
binding!!.currentAccount.account.text = Uri.parse(user.baseUrl!!).host binding!!.currentAccount.account.text = user.baseUrl!!.toUri().host
viewThemeUtils!!.platform.colorImageView(binding!!.currentAccount.accountMenu, ColorRole.PRIMARY) viewThemeUtils!!.platform.colorImageView(binding!!.currentAccount.accountMenu, ColorRole.PRIMARY)
if (user.baseUrl != null && if (user.baseUrl != null &&
(user.baseUrl!!.startsWith("http://") || user.baseUrl!!.startsWith("https://")) (user.baseUrl!!.startsWith("http://") || user.baseUrl!!.startsWith("https://"))

View File

@ -20,7 +20,6 @@ import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
import android.text.Spanned import android.text.Spanned
@ -46,7 +45,9 @@ import androidx.annotation.XmlRes
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.net.toUri
import androidx.emoji2.text.EmojiCompat import androidx.emoji2.text.EmojiCompat
import coil.Coil.imageLoader import coil.Coil.imageLoader
import coil.request.ImageRequest import coil.request.ImageRequest
@ -87,12 +88,12 @@ object DisplayUtils {
return currentNightMode == Configuration.UI_MODE_NIGHT_YES return currentNightMode == Configuration.UI_MODE_NIGHT_YES
} }
fun setClickableString(string: String, url: String?, textView: TextView) { fun setClickableString(string: String, url: String, textView: TextView) {
val spannableString = SpannableString(string) val spannableString = SpannableString(string)
spannableString.setSpan( spannableString.setSpan(
object : ClickableSpan() { object : ClickableSpan() {
override fun onClick(widget: View) { override fun onClick(widget: View) {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
sharedApplication!!.applicationContext.startActivity(browserIntent) sharedApplication!!.applicationContext.startActivity(browserIntent)
} }
@ -111,11 +112,7 @@ object DisplayUtils {
} }
fun getBitmap(drawable: Drawable): Bitmap { fun getBitmap(drawable: Drawable): Bitmap {
val bitmap = Bitmap.createBitmap( val bitmap = createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable.intrinsicWidth,
drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap) val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas) drawable.draw(canvas)

View File

@ -16,6 +16,7 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.emoji2.widget.EmojiTextView import androidx.emoji2.widget.EmojiTextView
import androidx.work.Data import androidx.work.Data
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
@ -23,13 +24,13 @@ import androidx.work.WorkInfo
import androidx.work.WorkManager import androidx.work.WorkManager
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.adapters.messages.PreviewMessageViewHolder
import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.fullscreenfile.FullScreenImageActivity import com.nextcloud.talk.fullscreenfile.FullScreenImageActivity
import com.nextcloud.talk.fullscreenfile.FullScreenMediaActivity import com.nextcloud.talk.fullscreenfile.FullScreenMediaActivity
import com.nextcloud.talk.fullscreenfile.FullScreenTextViewerActivity import com.nextcloud.talk.fullscreenfile.FullScreenTextViewerActivity
import com.nextcloud.talk.adapters.messages.PreviewMessageViewHolder
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.utils.AccountUtils.canWeOpenFilesApp import com.nextcloud.talk.utils.AccountUtils.canWeOpenFilesApp
import com.nextcloud.talk.utils.Mimetype.AUDIO_MPEG import com.nextcloud.talk.utils.Mimetype.AUDIO_MPEG
import com.nextcloud.talk.utils.Mimetype.AUDIO_OGG import com.nextcloud.talk.utils.Mimetype.AUDIO_OGG
@ -212,7 +213,7 @@ class FileViewerUtils(private val context: Context, private val user: User) {
} else { } else {
val browserIntent = Intent( val browserIntent = Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse(link) link.toUri()
) )
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent) context.startActivity(browserIntent)

View File

@ -18,6 +18,7 @@ import android.service.notification.StatusBarNotification
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.IconCompat
import androidx.core.net.toUri
import coil.executeBlocking import coil.executeBlocking
import coil.imageLoader import coil.imageLoader
import coil.request.ImageRequest import coil.request.ImageRequest
@ -287,14 +288,14 @@ object NotificationUtils {
// Ringtone uris are required to register the notification channels -> get uri from preferences. // Ringtone uris are required to register the notification channels -> get uri from preferences.
return if (TextUtils.isEmpty(ringtonePreferencesString)) { return if (TextUtils.isEmpty(ringtonePreferencesString)) {
Uri.parse(defaultRingtoneUri) defaultRingtoneUri.toUri()
} else { } else {
try { try {
val ringtoneSettings = val ringtoneSettings =
LoganSquare.parse(ringtonePreferencesString, RingtoneSettings::class.java) LoganSquare.parse(ringtonePreferencesString, RingtoneSettings::class.java)
ringtoneSettings.ringtoneUri ringtoneSettings.ringtoneUri
} catch (exception: IOException) { } catch (exception: IOException) {
Uri.parse(defaultRingtoneUri) defaultRingtoneUri.toUri()
} }
} }
} }

View File

@ -9,7 +9,7 @@ package com.nextcloud.talk.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import androidx.core.net.toUri
import com.nextcloud.talk.R import com.nextcloud.talk.R
object ShareUtils { object ShareUtils {
@ -26,7 +26,7 @@ object ShareUtils {
return return
} }
val uriBuilder = Uri.parse(baseUrl) val uriBuilder = baseUrl.toUri()
.buildUpon() .buildUpon()
if (!canGeneratePrettyURL) { if (!canGeneratePrettyURL) {

View File

@ -7,7 +7,7 @@
*/ */
package com.nextcloud.talk.utils package com.nextcloud.talk.utils
import android.net.Uri import androidx.core.net.toUri
class UriUtils { class UriUtils {
companion object { companion object {
@ -17,7 +17,7 @@ class UriUtils {
fun extractInstanceInternalFileFileId(url: String): String { fun extractInstanceInternalFileFileId(url: String): String {
// https://cloud.nextcloud.com/apps/files/?dir=/Engineering&fileid=41 // https://cloud.nextcloud.com/apps/files/?dir=/Engineering&fileid=41
return Uri.parse(url).getQueryParameter("fileid").toString() return url.toUri().getQueryParameter("fileid").toString()
} }
fun isInstanceInternalFileShareUrl(baseUrl: String, url: String): Boolean { fun isInstanceInternalFileShareUrl(baseUrl: String, url: String): Boolean {
@ -35,12 +35,12 @@ class UriUtils {
fun extractInstanceInternalFileShareFileId(url: String): String { fun extractInstanceInternalFileShareFileId(url: String): String {
// https://cloud.nextcloud.com/f/41 // https://cloud.nextcloud.com/f/41
return Uri.parse(url).lastPathSegment ?: "" return url.toUri().lastPathSegment ?: ""
} }
fun extractRoomTokenFromTalkUrl(url: String): String { fun extractRoomTokenFromTalkUrl(url: String): String {
// https://cloud.nextcloud.com/call/123456789 // https://cloud.nextcloud.com/call/123456789
return Uri.parse(url).lastPathSegment ?: "" return url.toUri().lastPathSegment ?: ""
} }
fun isInstanceInternalFileUrl(baseUrl: String, url: String): Boolean { fun isInstanceInternalFileUrl(baseUrl: String, url: String): Boolean {
@ -49,7 +49,7 @@ class UriUtils {
url.startsWith("$baseUrl/apps/files/") || url.startsWith("$baseUrl/apps/files/") ||
url.startsWith("$baseUrl/index.php/apps/files/") url.startsWith("$baseUrl/index.php/apps/files/")
) && ) &&
Uri.parse(url).queryParameterNames.contains("fileid") && url.toUri().queryParameterNames.contains("fileid") &&
Regex(""".*fileid=\d*""").matches(url) Regex(""".*fileid=\d*""").matches(url)
} }
@ -61,7 +61,7 @@ class UriUtils {
fun extractInstanceInternalFileFileIdNew(url: String): String { fun extractInstanceInternalFileFileIdNew(url: String): String {
// https://cloud.nextcloud.com/apps/files/files/41?dir=/ // https://cloud.nextcloud.com/apps/files/files/41?dir=/
return Uri.parse(url).lastPathSegment ?: "" return url.toUri().lastPathSegment ?: ""
} }
} }
} }

View File

@ -9,13 +9,13 @@ package com.nextcloud.talk.utils.message
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
import android.net.Uri
import android.text.SpannableString import android.text.SpannableString
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.Spanned import android.text.Spanned
import android.text.style.StyleSpan import android.text.style.StyleSpan
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.core.net.toUri
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
@ -139,7 +139,7 @@ class MessageUtils(val context: Context) {
"file" -> { "file" -> {
itemView.setOnClickListener { v -> itemView.setOnClickListener { v ->
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(individualHashMap["link"])) val browserIntent = Intent(Intent.ACTION_VIEW, individualHashMap["link"]!!.toUri())
context.startActivity(browserIntent) context.startActivity(browserIntent)
} }
} }

View File

@ -21,7 +21,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.8.2' classpath 'com.android.tools.build:gradle:8.9.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
classpath "org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}"
classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.1.7' classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.1.7'

View File

@ -1129,6 +1129,50 @@ R2u/WbxTrhDdrrjoFCFo/ZoYzRY46LR+HdytaEmE
=EiTD =EiTD
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub AC7A514BC9F9BB70
uid Punyashloka Biswal <punya@google.com>
sub 7B92B768F9D37337
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=XaPu
-----END PGP PUBLIC KEY BLOCK-----
pub B0F3710FA64900E7 pub B0F3710FA64900E7
sub 7892707E9657EBD4 sub 7892707E9657EBD4
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@ -1339,8 +1383,6 @@ vCeonVI7Q1CkIHt8u7eMgzfEkaiPLZlI0l0RpfT4pnNieqg=
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub BAC30622339994C4 pub BAC30622339994C4
uid Chris Povirk <cpovirk@google.com>
sub FC9BDC25FB378008 sub FC9BDC25FB378008
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@ -1349,21 +1391,20 @@ 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 i8/b+PwSW+nW3EpQZdLqZtOU
0upm05Q= =2H2i
=Gf3Y
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub BCF4173966770193 pub BCF4173966770193
@ -1452,6 +1493,42 @@ lQyC8nl8P5PgkEZ5CHcGymZlpzihR3ECrPJTk39Sb7D3SxCW4WrChV3kVfmLgvc=
=WqT9 =WqT9
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub C020E96222A31FB3
uid Eric Li <eric@swiftzer.net>
sub 55CDD67958ACCA47
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGAephsBDADH0j84tkTcmvOYskQWjA3M8hLNJI5QdagcYviR2yDTBq7paSP6
hLDrcCwTfvCNIatYI4hGau31RlkNKJHZumMZzF8OarWuKKkwwik3Z8pulMHgC8kR
SX5QM8k4wIeZLbD0UzW22gr0oLDilb3cFr86Y9T4AD6Ke0JATFRU+TrMAT5e5iYe
iVcNGuRQMvjncJobNIt4AeP12GV14p0GhAlka8Hwq24dTue5xwBJ9GwYWwPz6dbo
k83dZJdhLDfvL6ojG4umByeqCn/ARuJCuI0YABLO7BoqsAJvMfCMciP6Upu4iVT8
DduCd7mV7YaByqtktRJDzaNiJa36riYOnzAVsKB1QbnWD2tP2kcR0N37104+WtkH
GYkSfnZujfvmoHf4hws+6oUgfPs+1vMMYj0AnlotcDVez8sHSAwQN+rzfqqii8lj
9DdpScq+yamQratHBHIkdyx1xyd+Xy00Vs9NY03gIeFFM2Rjat+XDfK+uO/Mpkkx
Gcf9d6lC+OGUO88AEQEAAbQbRXJpYyBMaSA8ZXJpY0Bzd2lmdHplci5uZXQ+uQGN
BGAephsBDACvxELzqfLQrmLHOlpJru6cCqQgPCE6DIQnNYJ6nTyAow6tBLQ7b2MP
ACn1yqRskE1qzh415B2tcZqN8IpguN9NssqINyKdxcOYogmcdfnhN8TWYYUCKBD9
DssMhz24bq2GjcLxyPagrvACI5O+k+LYE3TQbLE/t/6oG3grgkWHJWKLA/ou812+
eDOI+/HaME/1uT3DwsGv57zoZaIwADWmdotoEyU/d+cK+5A2727PCS0hfDleDJ1T
rJoT2YRN9YJhGTl3xq/XmhfmcYX3KlTKakENZXsi/x9n2sxpCpE1xMa1kIB6SmZi
l88oxa7+zunRVNK3ymGxVxnLlltTyO/VyxQh1AJFhI6n35ls3l4BSEmUjNRi76VX
cuFH0TnyKEIHxZYv1K5FjTF84yukKrLbWKgWsvr8exHQuKjz+iU5NvmhY0g2CLwa
9P2fjA+nGWuKhLZyDh8M0+sXEuVTbiHgq8dkr94yBwqCs8quqC4PHW4bSivZj5ml
nrgujB35H/EAEQEAAYkBtgQYAQgAIBYhBNvV4c9Kf/PYynRZ2MAg6WIiox+zBQJg
HqYbAhsMAAoJEMAg6WIiox+zi/UL/1/OT875lTWbpoPIIi63ymL/dpkinRZQMQWY
jEsMd6Ea2/tVCbYt6zFXZNBIbJ3WmPN1/ZWFh+PWHla/GlUhksPuSFt8Jf3YL0QQ
0vHwErdulWBLssWMGmlQmISeRVYPkjha1gpBcbKCaWHhXRuf/FsrYpb0NqkArRf1
+fdhRdsOdy9avioy5l+/Ld+puaJWMKJbet2ARzQ9lOWCyOK6JoxO8U11jupKOMfa
gp5iowztQHcZ53IvIFJGPDCe0pb8l5owFpG8rmOrLuPVlRTMvR/n+MnI3hkswg+4
2Y9hslJKenF2utD0q0eU6VYnsquSHbsypDjx6zwUZvaa6olCIxNZoVJw/wSv1ZDe
/8U0TEL7OXe9jA6QLEDYAPytSF/mVIqSp4dgAPrADXSt8UOvq3jQoNMTESbJWWX8
169pc1yMD6HBdGShunnJ+slCQ/nJ6zFSMKLTJgOp3pRJYxfDlWoZVm5mSLsif8yD
yc0PGiCz66h9jPMKXJJ1o9MGQKvydw==
=+Ahq
-----END PGP PUBLIC KEY BLOCK-----
pub C21CE653B639E41A pub C21CE653B639E41A
sub 4F80368F9034B8D0 sub 4F80368F9034B8D0
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@ -1477,6 +1554,34 @@ yFe0+OWOuDHdhQgvnZwtl4e3
=DwNF =DwNF
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub C3BAB45F4AF71FAB
uid Yang Song <songya@google.com>
sub 34FEB51E33761BEA
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFkeN88BCAC4rvR3Dc6nDYhbXUC5IQ6SJWvV98+tvZ117J/VD07el7dicryY
H3OAWl62iLjHJFP/+AEra1plpiWbPioDlzjOWC2AJjUCtqVLHdyVbY0Gv3sSRZXJ
3H7CyGO1QbT79m4Gwk9vX5si3aBTzJNqYF6Kn1C386ZSZd6l618YSPUzJRXi1mst
rP2iV1hP+kydcFxB0+F8/IjzK9kngtp/k1z2x0tbIRTnUYnvS/GNbLHlVzrxvA1S
izbVLBzeuzmSyqT7xy6dPjsLEIoSK3cyR9x5tzmcSEA3dMN36N7j+mbqVI25Md0p
gd3vgIqGXQsRSezG1Kj5pQglPKl2Jufx5CEPABEBAAG0HVlhbmcgU29uZyA8c29u
Z3lhQGdvb2dsZS5jb20+uQENBFkeN88BCAChDNcKrhc2DHhIBmGvPvua+JiR3bAD
4pQZbMfisr70ZFHox7mVxTGGK7UDY4TpgeaWElWY0FJuQmnfP90Z4z+0Aqn24OoI
XyddFzt5JF1jCT79QX95t0KBhmPgqQssCNHfz6tpQSgK3NRaVJSjtgaTaVu6zJ++
ZJj772LQt0hqzcjMlpOaX2Jkdj8hDhsw3PZiCO4Hq52pIS987sPQRdbT+Tv6V4WO
Z7cuWqQIdfWOQwxVn3MAIIL3l9a4iMKIAWuj3kHxaHZ3gLj/51b/nlh3chDzhGbo
YpZWk1pmlCXFZnctoRO9Tk25bKRUgTJJP8sKgAsNK37n8zGAzUc3yXhRABEBAAGJ
AR8EGAECAAkFAlkeN88CGwwACgkQw7q0X0r3H6tJqgf/ZXG41Egf1gHv2d2c4hYI
xFFKhVJFZI0EfMq7ZCPZXrjphtgTrLLUYyxaRoW8dRstf/sNyb+yiZr8PGyKmk+6
LutzHStJFyk+h9b/sRKWzKnAnUzxzMggfFChMsMdwrmd4nmy6II+A0bjxM0eee4A
vEyd9/q8LNswtqaVJf7Az2HADvPUxxqcrtFvUFvD1GuTNYaSEKsZcr/EAmP8zq6L
vXKCmVnnIiP5JwBYMOfBqnsG6r504vpfmhfJBycCsyZlJbVjV0sL9514Ph7MJysI
uwCK4i39LRwL4i3O2PDZgv5Oal/V0cfrEEfJD4px/gfmZF2LRkpMS+qZrRJ2Nu7K
6g==
=jgaB
-----END PGP PUBLIC KEY BLOCK-----
pub C488A74FCAE540C6 pub C488A74FCAE540C6
uid Michael Evans <michaelcevans10@gmail.com> uid Michael Evans <michaelcevans10@gmail.com>
@ -2275,6 +2380,43 @@ N8xI5kHJ/ihT12hebEP+EzZPnA==
=WExy =WExy
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub EB095DA7D2F6AC0E
uid TensorFlow Authors <tensorflow-sonatype-authors@google.com>
sub 603D72C90616CD6B
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGBm/LQBDADMr/VPcTvE6k3wEYxq5kZusnDCDTsI6RK51d4oMwaRc3Z0jtZ0
CfyWocZBok4rMbZAVnE3Q8pMyikGGUnc8ZsWoPEmJyCpw/2Orj0QqZhIgYMQ31Uq
tiGZF/G4w9phLIkFgU9BLGYjRNM69R0oE/Tj8mjguvnKzYM3GjkY6nDsgWCM5TJX
01k4sdLs0dVg86m4keq+SeS9uEwnINZTh6kQUKsW6aHvvPXze/UPoaZqxgXDjF+F
JrPwW8yDllkbzpbo53ulz1TL5RsIH3daUwxXG3ciovUXG/b2ZRuWjtH7Gn/AvCNL
0RXdHK3A2I23zCooOE+we2D45QUHm/vcmvsnbxOU7Tslm2DsnYxBjf5dAl2yZn+J
FSrV91Bbd5ZXi1UkkGjBzAgbHDwdMvL9K6fTO9NwjXyBpiHy6ukIOObn9uIgDSSa
xPnqgeykSv+RZEea8ML4BSif5RJYlmILEzJhH4rtX9X+t8BZv+ZoaN6p/qYg4/2+
XfSUPmCJjlUaIUUAEQEAAbQ7VGVuc29yRmxvdyBBdXRob3JzIDx0ZW5zb3JmbG93
LXNvbmF0eXBlLWF1dGhvcnNAZ29vZ2xlLmNvbT65AY0EYGb8tAEMALbsrC+JdcC4
wyIL2v/pg++nHpMUbueLO82DpIf/OzSGerT5D5cP8PpuwhKIbq8drEEj6wpSaGjK
sZT4EQppo+SUFRAu/faZLyWW/kMLJQ+ez/OC2J7Yqqa/p5pker4A5WcWokWujlVJ
ZVE2MA6R3EPDKHF2p3uIgHmvfWnMS+tMzopj3mj1SvbV2UNZyj1SFrOkUmJ2ueBR
WZ9Ll3xuEMfMRAF2HXFI+aBIeCRbRHD/ueWFVqKX4vsyEMMCeyWjumWYR3KODqQs
E2rgf4V9klXUoo1d9jvSIR1zt8TyIvuUQv4sB64Rd5HsTS5X1VjJ2/0Vgu0TkF3V
BCuGEBi8u/nRXe5SkOYG1KAIbqljpx8mkgMjZRRrptxUeaK6GndHikuY85Np+FDD
zQwKKO8hItXHQq8pAyXm9RkA+rnEMfqKi5HNThsKlYyVNxQ0I/8r0gjyprLfZUhk
tyR/ZemnNN9w29qgD5FMZ4cNsTeCx5NiKKL5+UmbtSFMx/P4vh4aXwARAQABiQG2
BBgBCgAgFiEEdEDx99J7rBFflT1V6wldp9L2rA4FAmBm/LQCGwwACgkQ6wldp9L2
rA5EgQv/dXw1tFelPKUcFuhxa7gJ6v9LkNoCEq5g5aSc7IEjuh0EH4aNU/+7rmIZ
wRslOHcSBeBvQPhIYdosIQfdCcwjS7LU1urnkljCvuIbwaX8d5Am7NqMbtM/GR66
MRPSO3uV6g0DmswDZ3i0WSeUgK4NXRRmL3gUZcoxOeQpg0Mo+fGiZDGywACa3azJ
BWR8G3gSjrN6YdM5+Tb0gQ1D/AN8JVF7ksknl2AlCI9pOEOsyaHZ4T++or36btHm
Z+FJw9LCPGHaCTrDSoA0Tun0fZBBIf1xmNPNgdQHerTtp3mtTCFRdBiIH4d3s3d2
HBuEYqdLqiD6+8saU5lRAPMFb6VoPPsGNv8by7h7WQ+fWyuCpUPZvuFuVobq7K3V
H0iNhLlzae8WMDUVX3pQKZrDjlqjjaloOJXoq8ZFlDM+1wwKwz7nouEJPFReP9Mn
xjlUofFR0KyGrs6qzaeC22AvbIotX6sUExVRjz4b+lro3f3lLlHlEWWyoKRyH54g
1y4mk1Mn
=iteQ
-----END PGP PUBLIC KEY BLOCK-----
pub EB380DC13C39F675 pub EB380DC13C39F675
uid Mark Vedder <mark.vedder.key@my-accounts.info> uid Mark Vedder <mark.vedder.key@my-accounts.info>
@ -5637,15 +5779,13 @@ xOcUt3JhIGtKwRMO4mte4wmT6Ko+Nj4uy6tFjbTfN2eBins/1F9qLU4YJUqC4QD4
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 7721F63BD38B4796 pub 7721F63BD38B4796
uid Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com> sub 4EB27DB2A3B88B8B
sub 1397BC53640DB551
sub 78BD65473CB3BD13
sub 6494C6D6997C215E
sub FD533C07C264648F sub FD533C07C264648F
sub 32EE5355A6BC6E42 sub 32EE5355A6BC6E42
sub E88979FB9B30ACF2 sub E88979FB9B30ACF2
sub 1397BC53640DB551
sub 6494C6D6997C215E
sub 78BD65473CB3BD13
sub 4EB27DB2A3B88B8B
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFcMjNMBEAC6Wr5QuLIFgz1V1EFPlg8ty2TsjQEl4VWftUAqWlMevJFWvYEx mQINBFcMjNMBEAC6Wr5QuLIFgz1V1EFPlg8ty2TsjQEl4VWftUAqWlMevJFWvYEx
@ -5659,411 +5799,331 @@ xeqTWDlzONUpOs5yBjF1cfJSdVxsfshvln2JXUwgIdKl4DLbZybuNFXnPffNLb2v
PtRJHO48O2UbeXS8n27PcuMoLRd7+r7TsqG2vBH4t/cB/1vsvWMbqnQlaJ5VsjeW PtRJHO48O2UbeXS8n27PcuMoLRd7+r7TsqG2vBH4t/cB/1vsvWMbqnQlaJ5VsjeW
Tp8Gv9FJiKuU8PKiWsF4EGR/kAFyCB8QbJeQ6HrOT0CXLOaYHRu2TvJ4taY9doXn Tp8Gv9FJiKuU8PKiWsF4EGR/kAFyCB8QbJeQ6HrOT0CXLOaYHRu2TvJ4taY9doXn
98TgU03XTLcYoSp49cdkkis4K+9hd2dUqARVCG7UVd9PY60VVCKi47BVKQARAQAB 98TgU03XTLcYoSp49cdkkis4K+9hd2dUqARVCG7UVd9PY60VVCKi47BVKQARAQAB
tFRHb29nbGUgSW5jLiAoTGludXggUGFja2FnZXMgU2lnbmluZyBBdXRob3JpdHkp uQINBGF4DJ8BEACk2Gwau+s/pKmOTnGLMnB3ybQsiVGLRhsw2SqSTvSyBthAyW1U
IDxsaW51eC1wYWNrYWdlcy1rZXltYXN0ZXJAZ29vZ2xlLmNvbT65Ag0EZ31b7QEQ AqdRqNA8/FdMlvVuppG8+vCLXPmpP63C+9M2tyQeOR2aVQp+u1EIwN4lPu4wrh6v
AMEWM0g1KKIxE7q8JK7QblKom7++NYn92E3suHv3WxqzrhRT9tYNDSaoOazQP+ha dtgSRim8uxBdLIHG16z0xxVhE2rM/Ot/gucfkpoEw289VaR7sPmIxfVTm1QcqCGi
NA2BqkdFcB7G4jKdtK2VLFc7RBpcR2rnQEJWgpeP03DHrdZYFdpH9zABoFsotgZR FQl3rZnma6Bz8UOXJoE8wO+LK5WkcdmFz6+Z3BLSb5IL9lhsArFToNq5dN2SSTbC
KwwTOoxdm6XtV+47LEY9yAefPrt1gPJQ4h1SKwWIFSRPChQ1cThBz2QD2LaPAGtj TdHRzrRuoCdefYHdxoLCM4kJfggRRgWhKoEJro+ZipESq1T5yHV/iAJy+3DuC8Lb
Wzr6+0xf0nm4xTDvya0EbdTpMOvtyDCUp7qe41u34RelGxoo0+rmoL/0cTJGCr2L YLvsjt9VZYARw8xIGb90Vj3ThWuMoVr/IVmKT7foC5Whe0PTI/b2frNaWCxxC4cR
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 c8LNGrDaCFdXnOdlNV/zT9VvBk/RkV+Tl/Lk4g==
HIeEIESNX9LdmvB+kQMW7d1d7Bs0aW2okPDt02vgwH2VEtQTtfq5B98jbwNW9mbX =AP/d
TvMQAKKCKl+H8T72WdueqgPKHEkXDZtJmTn6nyneYlETvdmHGEIb1ejxuJ5URlAY -----END PGP PUBLIC KEY BLOCK-----
nciY+kvSQ/boKjVHNGmf6+JBexd+HqPhkeextV6Jcnmi47HDvIU/TSynhuqZeK/3
SZAV7ESqQl42q7wm7Pqw0dkv4jjFCRxDA+Qq2aH6szJ7DZxTRWqfR3Zbe78NyFVX pub 7905DE25C78AD456
KxhFQO72zHzC3pFu/Ak59hmTU23yoXVo5t+5O+Q21kX2dbuLd6Px1bnT+EmyneoP uid Protobuf Release <protobuf@googlegroups.com>
P1Emea5jgsw2/ECqHnvNt6cbp+42XYldGh+PBHBmucC3Mn7sALajHe5k2XkNlfbj
SNlmutxQFH1qq9rh/JVyxJNHeGzV5G0timAwfdJFUzE1vNU5P0w4O8HrCsX5Ecfg sub DBC5123E2E98FEFE
cw2BQ9vPCE3OfG+11xp6oiNMRVsR5pTu7RiI1BQAyICWUW/wXuhhHkkwNTiwfciJ -----BEGIN PGP PUBLIC KEY BLOCK-----
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 =z4dc
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
Y7Iyz4ygr8etweBPnEIvjwpAZxOu
=wwl/
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 79752DB6C966F0B8 pub 79752DB6C966F0B8

File diff suppressed because it is too large Load Diff