mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
Merge remote-tracking branch 'origin/master' into feature/edit_messages
This commit is contained in:
commit
9a4bf14e09
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
swap-size-gb: 10
|
swap-size-gb: 10
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0
|
uses: github/codeql-action/init@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
@ -46,4 +46,4 @@ jobs:
|
|||||||
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
|
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
|
||||||
./gradlew assembleDebug
|
./gradlew assembleDebug
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0
|
uses: github/codeql-action/analyze@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
||||||
|
@ -19,4 +19,4 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- uses: gradle/wrapper-validation-action@27152f6fa06a6b8062ef7195c795692e51fc2c81 # v2.0.0
|
- uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1
|
||||||
|
2
.github/workflows/scorecard.yml
vendored
2
.github/workflows/scorecard.yml
vendored
@ -37,6 +37,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0
|
uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
2
.github/workflows/unit-tests.yml
vendored
2
.github/workflows/unit-tests.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
java-version: 17
|
java-version: 17
|
||||||
- name: Run unit tests with coverage
|
- name: Run unit tests with coverage
|
||||||
uses: gradle/gradle-build-action@3b1b3b9a2104c2b47fbae53f3938079c00c9bb87 # v3.0.0
|
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e # v3.1.0
|
||||||
with:
|
with:
|
||||||
arguments: testGplayDebugUnit
|
arguments: testGplayDebugUnit
|
||||||
- name: Upload test artifacts
|
- name: Upload test artifacts
|
||||||
|
@ -48,8 +48,8 @@ android {
|
|||||||
|
|
||||||
// mayor.minor.hotfix.increment (for increment: 01-50=Alpha / 51-89=RC / 90-99=stable)
|
// mayor.minor.hotfix.increment (for increment: 01-50=Alpha / 51-89=RC / 90-99=stable)
|
||||||
// xx .xxx .xx .xx
|
// xx .xxx .xx .xx
|
||||||
versionCode 180010010
|
versionCode 190000001
|
||||||
versionName "18.1.0 Alpha 10"
|
versionName "19.0.0 Alpha 01"
|
||||||
|
|
||||||
flavorDimensions "default"
|
flavorDimensions "default"
|
||||||
renderscriptTargetApi 19
|
renderscriptTargetApi 19
|
||||||
@ -247,7 +247,7 @@ dependencies {
|
|||||||
implementation 'com.github.wooplr:Spotlight:1.3'
|
implementation 'com.github.wooplr:Spotlight:1.3'
|
||||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
implementation 'com.github.nextcloud-deps:ChatKit:0.4.2'
|
implementation 'com.github.nextcloud-deps:ChatKit:0.4.2'
|
||||||
implementation 'joda-time:joda-time:2.12.6'
|
implementation 'joda-time:joda-time:2.12.7'
|
||||||
implementation "io.coil-kt:coil:${coilKtVersion}"
|
implementation "io.coil-kt:coil:${coilKtVersion}"
|
||||||
implementation "io.coil-kt:coil-gif:${coilKtVersion}"
|
implementation "io.coil-kt:coil-gif:${coilKtVersion}"
|
||||||
implementation "io.coil-kt:coil-svg:${coilKtVersion}"
|
implementation "io.coil-kt:coil-svg:${coilKtVersion}"
|
||||||
@ -308,11 +308,11 @@ dependencies {
|
|||||||
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
|
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
|
||||||
|
|
||||||
gplayImplementation 'com.google.android.gms:play-services-base:18.3.0'
|
gplayImplementation 'com.google.android.gms:play-services-base:18.3.0'
|
||||||
gplayImplementation "com.google.firebase:firebase-messaging:23.4.0"
|
gplayImplementation "com.google.firebase:firebase-messaging:23.4.1"
|
||||||
|
|
||||||
implementation 'androidx.activity:activity-ktx:1.8.2'
|
implementation 'androidx.activity:activity-ktx:1.8.2'
|
||||||
|
|
||||||
implementation 'com.github.nextcloud.android-common:ui:0.14.0'
|
implementation 'com.github.nextcloud.android-common:ui:0.15.0'
|
||||||
|
|
||||||
implementation 'com.github.nextcloud-deps:android-talk-webrtc:110.5481.0'
|
implementation 'com.github.nextcloud-deps:android-talk-webrtc:110.5481.0'
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".application.NextcloudTalkApplication"
|
android:name=".application.NextcloudTalkApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -1117,7 +1117,7 @@ class CallActivity : CallBaseActivity() {
|
|||||||
micInputAudioRecorder.read(byteArr, 0, byteArr.size)
|
micInputAudioRecorder.read(byteArr, 0, byteArr.size)
|
||||||
val isCurrentlySpeaking = abs(byteArr[0].toDouble()) > MICROPHONE_VALUE_THRESHOLD
|
val isCurrentlySpeaking = abs(byteArr[0].toDouble()) > MICROPHONE_VALUE_THRESHOLD
|
||||||
|
|
||||||
if (isCurrentlySpeaking && !isSpeakingLongTerm) {
|
if (microphoneOn && isCurrentlySpeaking && !isSpeakingLongTerm) {
|
||||||
isSpeakingLongTerm = true
|
isSpeakingLongTerm = true
|
||||||
sendIsSpeakingMessage(true)
|
sendIsSpeakingMessage(true)
|
||||||
} else if (!isCurrentlySpeaking && isSpeakingLongTerm) {
|
} else if (!isCurrentlySpeaking && isSpeakingLongTerm) {
|
||||||
|
@ -31,10 +31,12 @@ package com.nextcloud.talk.chat
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
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.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.AssetFileDescriptor
|
import android.content.res.AssetFileDescriptor
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
@ -42,7 +44,9 @@ import android.database.Cursor
|
|||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.media.AudioFocusRequest
|
||||||
import android.media.AudioFormat
|
import android.media.AudioFormat
|
||||||
|
import android.media.AudioManager
|
||||||
import android.media.AudioRecord
|
import android.media.AudioRecord
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import android.media.MediaRecorder
|
import android.media.MediaRecorder
|
||||||
@ -389,6 +393,20 @@ class ChatActivity :
|
|||||||
private var lastRecordMediaPosition: Int = 0
|
private var lastRecordMediaPosition: Int = 0
|
||||||
private var lastRecordedSeeked: Boolean = false
|
private var lastRecordedSeeked: Boolean = false
|
||||||
|
|
||||||
|
private val audioFocusChangeListener = getAudioFocusChangeListener()
|
||||||
|
|
||||||
|
private val noisyAudioStreamReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
chatViewModel.isPausedDueToBecomingNoisy = true
|
||||||
|
if (isVoicePreviewPlaying) {
|
||||||
|
pausePreviewVoicePlaying()
|
||||||
|
}
|
||||||
|
if (currentlyPlayedVoiceMessage != null) {
|
||||||
|
pausePlayback(currentlyPlayedVoiceMessage!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var participantPermissions: ParticipantPermissions
|
private lateinit var participantPermissions: ParticipantPermissions
|
||||||
|
|
||||||
private var videoURI: Uri? = null
|
private var videoURI: Uri? = null
|
||||||
@ -1217,7 +1235,9 @@ class ChatActivity :
|
|||||||
|
|
||||||
binding.messageInputView.micInputCloud.setOnClickListener {
|
binding.messageInputView.micInputCloud.setOnClickListener {
|
||||||
if (mediaRecorderState == MediaRecorderState.RECORDING) {
|
if (mediaRecorderState == MediaRecorderState.RECORDING) {
|
||||||
recorder?.stop()
|
audioFocusRequest(false) {
|
||||||
|
recorder?.stop()
|
||||||
|
}
|
||||||
mediaRecorderState = MediaRecorderState.INITIAL
|
mediaRecorderState = MediaRecorderState.INITIAL
|
||||||
stopMicInputRecordingAnimation()
|
stopMicInputRecordingAnimation()
|
||||||
showPreviewVoiceRecording(true)
|
showPreviewVoiceRecording(true)
|
||||||
@ -1446,8 +1466,11 @@ class ChatActivity :
|
|||||||
duration = it.duration.toLong()
|
duration = it.duration.toLong()
|
||||||
interpolator = LinearInterpolator()
|
interpolator = LinearInterpolator()
|
||||||
}
|
}
|
||||||
voicePreviewMediaPlayer!!.start()
|
audioFocusRequest(true) {
|
||||||
voicePreviewObjectAnimator!!.start()
|
voicePreviewMediaPlayer!!.start()
|
||||||
|
voicePreviewObjectAnimator!!.start()
|
||||||
|
handleBecomingNoisyBroadcast(register = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnCompletionListener {
|
setOnCompletionListener {
|
||||||
@ -1461,15 +1484,21 @@ class ChatActivity :
|
|||||||
if (voicePreviewMediaPlayer == null) {
|
if (voicePreviewMediaPlayer == null) {
|
||||||
initPreviewVoiceRecording()
|
initPreviewVoiceRecording()
|
||||||
} else {
|
} else {
|
||||||
voicePreviewMediaPlayer!!.start()
|
audioFocusRequest(true) {
|
||||||
voicePreviewObjectAnimator!!.resume()
|
voicePreviewMediaPlayer!!.start()
|
||||||
|
voicePreviewObjectAnimator!!.resume()
|
||||||
|
handleBecomingNoisyBroadcast(register = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pausePreviewVoicePlaying() {
|
private fun pausePreviewVoicePlaying() {
|
||||||
Log.d(TAG, "paused preview voice recording")
|
Log.d(TAG, "paused preview voice recording")
|
||||||
voicePreviewMediaPlayer!!.pause()
|
audioFocusRequest(false) {
|
||||||
voicePreviewObjectAnimator!!.pause()
|
voicePreviewMediaPlayer!!.pause()
|
||||||
|
voicePreviewObjectAnimator!!.pause()
|
||||||
|
handleBecomingNoisyBroadcast(register = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopPreviewVoicePlaying() {
|
private fun stopPreviewVoicePlaying() {
|
||||||
@ -1479,9 +1508,12 @@ class ChatActivity :
|
|||||||
voicePreviewObjectAnimator!!.end()
|
voicePreviewObjectAnimator!!.end()
|
||||||
voicePreviewObjectAnimator = null
|
voicePreviewObjectAnimator = null
|
||||||
binding.messageInputView.seekBar.clearAnimation()
|
binding.messageInputView.seekBar.clearAnimation()
|
||||||
voicePreviewMediaPlayer!!.stop()
|
audioFocusRequest(false) {
|
||||||
voicePreviewMediaPlayer!!.release()
|
voicePreviewMediaPlayer!!.stop()
|
||||||
voicePreviewMediaPlayer = null
|
voicePreviewMediaPlayer!!.release()
|
||||||
|
voicePreviewMediaPlayer = null
|
||||||
|
handleBecomingNoisyBroadcast(register = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1935,6 +1967,73 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getAudioFocusChangeListener(): AudioManager.OnAudioFocusChangeListener {
|
||||||
|
return AudioManager.OnAudioFocusChangeListener { flag ->
|
||||||
|
when (flag) {
|
||||||
|
AudioManager.AUDIOFOCUS_LOSS -> {
|
||||||
|
chatViewModel.isPausedDueToBecomingNoisy = false
|
||||||
|
if (isVoicePreviewPlaying) {
|
||||||
|
stopPreviewVoicePlaying()
|
||||||
|
}
|
||||||
|
if (currentlyPlayedVoiceMessage != null) {
|
||||||
|
stopMediaPlayer(currentlyPlayedVoiceMessage!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
|
||||||
|
chatViewModel.isPausedDueToBecomingNoisy = false
|
||||||
|
if (isVoicePreviewPlaying) {
|
||||||
|
pausePreviewVoicePlaying()
|
||||||
|
}
|
||||||
|
if (currentlyPlayedVoiceMessage != null) {
|
||||||
|
pausePlayback(currentlyPlayedVoiceMessage!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun audioFocusRequest(shouldRequestFocus: Boolean, onGranted: () -> Unit) {
|
||||||
|
if (chatViewModel.isPausedDueToBecomingNoisy) {
|
||||||
|
onGranted()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
val duration = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
|
||||||
|
|
||||||
|
val isGranted: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val focusRequest = AudioFocusRequest.Builder(duration)
|
||||||
|
.setOnAudioFocusChangeListener(audioFocusChangeListener)
|
||||||
|
.build()
|
||||||
|
if (shouldRequestFocus) {
|
||||||
|
audioManager.requestAudioFocus(focusRequest)
|
||||||
|
} else {
|
||||||
|
audioManager.abandonAudioFocusRequest(focusRequest)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@Deprecated("This method was deprecated in API level 26.")
|
||||||
|
if (shouldRequestFocus) {
|
||||||
|
audioManager.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, duration)
|
||||||
|
} else {
|
||||||
|
audioManager.abandonAudioFocus(audioFocusChangeListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isGranted == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||||
|
onGranted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleBecomingNoisyBroadcast(register: Boolean) {
|
||||||
|
if (register && !chatViewModel.receiverRegistered) {
|
||||||
|
registerReceiver(noisyAudioStreamReceiver, IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY))
|
||||||
|
chatViewModel.receiverRegistered = true
|
||||||
|
} else if (!chatViewModel.receiverUnregistered) {
|
||||||
|
unregisterReceiver(noisyAudioStreamReceiver)
|
||||||
|
chatViewModel.receiverUnregistered = true
|
||||||
|
chatViewModel.receiverRegistered = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun startPlayback(message: ChatMessage) {
|
private fun startPlayback(message: ChatMessage) {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// don't begin to play voice message if screen is not visible anymore.
|
// don't begin to play voice message if screen is not visible anymore.
|
||||||
@ -1948,8 +2047,10 @@ class ChatActivity :
|
|||||||
|
|
||||||
mediaPlayer?.let {
|
mediaPlayer?.let {
|
||||||
if (!it.isPlaying) {
|
if (!it.isPlaying) {
|
||||||
it.start()
|
audioFocusRequest(true) {
|
||||||
Log.d(TAG, "MediaPlayer has Started")
|
it.start()
|
||||||
|
handleBecomingNoisyBroadcast(register = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaPlayerHandler = Handler()
|
mediaPlayerHandler = Handler()
|
||||||
@ -1984,8 +2085,10 @@ class ChatActivity :
|
|||||||
|
|
||||||
private fun pausePlayback(message: ChatMessage) {
|
private fun pausePlayback(message: ChatMessage) {
|
||||||
if (mediaPlayer!!.isPlaying) {
|
if (mediaPlayer!!.isPlaying) {
|
||||||
mediaPlayer!!.pause()
|
audioFocusRequest(false) {
|
||||||
Log.d(TAG, "MediaPlayer is paused")
|
mediaPlayer!!.pause()
|
||||||
|
handleBecomingNoisyBroadcast(register = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message.isPlayingVoiceMessage = false
|
message.isPlayingVoiceMessage = false
|
||||||
@ -2043,7 +2146,10 @@ class ChatActivity :
|
|||||||
mediaPlayer?.let {
|
mediaPlayer?.let {
|
||||||
if (it.isPlaying) {
|
if (it.isPlaying) {
|
||||||
Log.d(TAG, "media player is stopped")
|
Log.d(TAG, "media player is stopped")
|
||||||
it.stop()
|
audioFocusRequest(false) {
|
||||||
|
it.stop()
|
||||||
|
handleBecomingNoisyBroadcast(register = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
@ -2259,8 +2365,10 @@ class ChatActivity :
|
|||||||
private fun stopMicInputRecordingAnimation() {
|
private fun stopMicInputRecordingAnimation() {
|
||||||
if (micInputAudioRecordThread != null) {
|
if (micInputAudioRecordThread != null) {
|
||||||
Log.d(TAG, "Mic Animation Ended")
|
Log.d(TAG, "Mic Animation Ended")
|
||||||
micInputAudioRecorder.stop()
|
audioFocusRequest(false) {
|
||||||
micInputAudioRecorder.release()
|
micInputAudioRecorder.stop()
|
||||||
|
micInputAudioRecorder.release()
|
||||||
|
}
|
||||||
isMicInputAudioThreadRunning = false
|
isMicInputAudioThreadRunning = false
|
||||||
micInputAudioRecordThread = null
|
micInputAudioRecordThread = null
|
||||||
}
|
}
|
||||||
@ -2311,7 +2419,9 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
start()
|
audioFocusRequest(true) {
|
||||||
|
start()
|
||||||
|
}
|
||||||
mediaRecorderState = MediaRecorderState.RECORDING
|
mediaRecorderState = MediaRecorderState.RECORDING
|
||||||
Log.d(TAG, "recording started")
|
Log.d(TAG, "recording started")
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
@ -2352,8 +2462,10 @@ class ChatActivity :
|
|||||||
recorder?.apply {
|
recorder?.apply {
|
||||||
try {
|
try {
|
||||||
if (mediaRecorderState == MediaRecorderState.RECORDING) {
|
if (mediaRecorderState == MediaRecorderState.RECORDING) {
|
||||||
stop()
|
audioFocusRequest(false) {
|
||||||
reset()
|
stop()
|
||||||
|
reset()
|
||||||
|
}
|
||||||
mediaRecorderState = MediaRecorderState.INITIAL
|
mediaRecorderState = MediaRecorderState.INITIAL
|
||||||
Log.d(TAG, "stopped recorder")
|
Log.d(TAG, "stopped recorder")
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,11 @@ class ChatViewModel @Inject constructor(private val repository: ChatRepository)
|
|||||||
open class GetReminderExistState(val reminder: Reminder) : ViewState
|
open class GetReminderExistState(val reminder: Reminder) : ViewState
|
||||||
|
|
||||||
private val _getReminderExistState: MutableLiveData<ViewState> = MutableLiveData(GetReminderStartState)
|
private val _getReminderExistState: MutableLiveData<ViewState> = MutableLiveData(GetReminderStartState)
|
||||||
|
|
||||||
|
var isPausedDueToBecomingNoisy = false
|
||||||
|
var receiverRegistered = false
|
||||||
|
var receiverUnregistered = false
|
||||||
|
|
||||||
val getReminderExistState: LiveData<ViewState>
|
val getReminderExistState: LiveData<ViewState>
|
||||||
get() = _getReminderExistState
|
get() = _getReminderExistState
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ import androidx.core.view.marginBottom
|
|||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.media3.common.AudioAttributes
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
@ -165,7 +166,10 @@ class FullScreenMediaActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initializePlayer() {
|
private fun initializePlayer() {
|
||||||
player = ExoPlayer.Builder(applicationContext).build()
|
player = ExoPlayer.Builder(applicationContext)
|
||||||
|
.setAudioAttributes(AudioAttributes.DEFAULT, true)
|
||||||
|
.setHandleAudioBecomingNoisy(true)
|
||||||
|
.build()
|
||||||
binding.playerView.player = player
|
binding.playerView.player = player
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +206,7 @@ class FullScreenMediaActivity : AppCompatActivity() {
|
|||||||
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||||
supportActionBar?.show()
|
supportActionBar?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun applyWindowInsets() {
|
private fun applyWindowInsets() {
|
||||||
val playerView = binding.playerView
|
val playerView = binding.playerView
|
||||||
val exoControls = playerView.findViewById<FrameLayout>(R.id.exo_bottom_bar)
|
val exoControls = playerView.findViewById<FrameLayout>(R.id.exo_bottom_bar)
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
* Nextcloud Talk application
|
* Nextcloud Talk application
|
||||||
*
|
*
|
||||||
* @author Marcel Hibbe
|
* @author Marcel Hibbe
|
||||||
|
* @author Parneet Singh
|
||||||
* Copyright (C) 2021-2022 Marcel Hibbe <dev@mhibbe.de>
|
* Copyright (C) 2021-2022 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
* Copyright (C) 2024-2025 Parneet Singh <gurayaparneet@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -22,7 +24,6 @@ package com.nextcloud.talk.jobs
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -86,7 +87,6 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
|
|
||||||
private var mNotifyManager: NotificationManager? = null
|
private var mNotifyManager: NotificationManager? = null
|
||||||
private var mBuilder: NotificationCompat.Builder? = null
|
private var mBuilder: NotificationCompat.Builder? = null
|
||||||
private lateinit var notification: Notification
|
|
||||||
private var notificationId: Int = 0
|
private var notificationId: Int = 0
|
||||||
|
|
||||||
lateinit var roomToken: String
|
lateinit var roomToken: String
|
||||||
@ -168,7 +168,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uploadSuccess) {
|
if (uploadSuccess) {
|
||||||
mNotifyManager?.cancel(notificationId)
|
cancelNotification()
|
||||||
return Result.success()
|
return Result.success()
|
||||||
} else if (isStopped) {
|
} else if (isStopped) {
|
||||||
// since work is cancelled the result would be ignored anyways
|
// since work is cancelled the result would be ignored anyways
|
||||||
@ -196,12 +196,12 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onTransferProgress(percentage: Int) {
|
override fun onTransferProgress(percentage: Int) {
|
||||||
notification = mBuilder!!
|
val progressUpdateNotification = mBuilder!!
|
||||||
.setProgress(HUNDRED_PERCENT, percentage, false)
|
.setProgress(HUNDRED_PERCENT, percentage, false)
|
||||||
.setContentText(getNotificationContentText(percentage))
|
.setContentText(getNotificationContentText(percentage))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
mNotifyManager!!.notify(notificationId, notification)
|
mNotifyManager!!.notify(notificationId, progressUpdateNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStopped() {
|
override fun onStopped() {
|
||||||
@ -223,22 +223,60 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initNotificationWithPercentage() {
|
private fun initNotificationWithPercentage() {
|
||||||
notification = mBuilder!!
|
val initNotification = mBuilder!!
|
||||||
.setContentTitle(getResourceString(context, R.string.nc_upload_in_progess))
|
.setContentTitle(context.resources.getString(R.string.nc_upload_in_progess))
|
||||||
.setContentText(getNotificationContentText(ZERO_PERCENT))
|
.setContentText(getNotificationContentText(ZERO_PERCENT))
|
||||||
.setSmallIcon(R.drawable.upload_white)
|
.setSmallIcon(R.drawable.upload_white)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setProgress(HUNDRED_PERCENT, ZERO_PERCENT, false)
|
.setProgress(HUNDRED_PERCENT, ZERO_PERCENT, false)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
.setGroup(NotificationUtils.KEY_UPLOAD_GROUP)
|
||||||
.setContentIntent(getIntentToOpenConversation())
|
.setContentIntent(getIntentToOpenConversation())
|
||||||
.addAction(
|
.addAction(
|
||||||
R.drawable.ic_cancel_white_24dp, getResourceString(context, R.string.nc_cancel),
|
R.drawable.ic_cancel_white_24dp,
|
||||||
|
getResourceString(context, R.string.nc_cancel),
|
||||||
getCancelUploadIntent()
|
getCancelUploadIntent()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
notificationId = SystemClock.uptimeMillis().toInt()
|
notificationId = SystemClock.uptimeMillis().toInt()
|
||||||
mNotifyManager!!.notify(notificationId, notification)
|
mNotifyManager!!.notify(notificationId, initNotification)
|
||||||
|
// only need one summary notification but multiple upload worker can call it more than once but it is safe
|
||||||
|
// because of the same notification object config and id.
|
||||||
|
makeSummaryNotification()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSummaryNotification() {
|
||||||
|
// summary notification encapsulating the group of notifications
|
||||||
|
val summaryNotification = NotificationCompat.Builder(
|
||||||
|
context,
|
||||||
|
NotificationUtils.NotificationChannels
|
||||||
|
.NOTIFICATION_CHANNEL_UPLOADS.name
|
||||||
|
).setSmallIcon(R.drawable.upload_white)
|
||||||
|
.setGroup(NotificationUtils.KEY_UPLOAD_GROUP)
|
||||||
|
.setGroupSummary(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
mNotifyManager?.notify(NotificationUtils.GROUP_SUMMARY_NOTIFICATION_ID, summaryNotification)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getActiveUploadNotifications(): Int? {
|
||||||
|
// filter out active notifications that are upload notifications using group
|
||||||
|
return mNotifyManager?.activeNotifications?.filter {
|
||||||
|
it.notification.group == NotificationUtils
|
||||||
|
.KEY_UPLOAD_GROUP
|
||||||
|
}?.size
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelNotification() {
|
||||||
|
mNotifyManager?.cancel(notificationId)
|
||||||
|
// summary notification would not get dismissed automatically
|
||||||
|
// if child notifications are cancelled programmatically
|
||||||
|
// so check if only 1 notification left if yes
|
||||||
|
// then cancel it (which is summary notification)
|
||||||
|
if (getActiveUploadNotifications() == 1) {
|
||||||
|
mNotifyManager?.cancel(NotificationUtils.GROUP_SUMMARY_NOTIFICATION_ID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNotificationContentText(percentage: Int): String {
|
private fun getNotificationContentText(percentage: Int): String {
|
||||||
@ -289,17 +327,21 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
getResourceString(context, R.string.nc_upload_failed_notification_text),
|
getResourceString(context, R.string.nc_upload_failed_notification_text),
|
||||||
fileName
|
fileName
|
||||||
)
|
)
|
||||||
notification = mBuilder!!
|
val failureNotification = NotificationCompat.Builder(
|
||||||
|
context,
|
||||||
|
NotificationUtils.NotificationChannels
|
||||||
|
.NOTIFICATION_CHANNEL_UPLOADS.name
|
||||||
|
)
|
||||||
.setContentTitle(failureTitle)
|
.setContentTitle(failureTitle)
|
||||||
.setContentText(failureText)
|
.setContentText(failureText)
|
||||||
.setSmallIcon(R.drawable.baseline_error_24)
|
.setSmallIcon(R.drawable.baseline_error_24)
|
||||||
|
.setGroup(NotificationUtils.KEY_UPLOAD_GROUP)
|
||||||
.setOngoing(false)
|
.setOngoing(false)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// Cancel original notification
|
|
||||||
mNotifyManager?.cancel(notificationId)
|
mNotifyManager?.cancel(notificationId)
|
||||||
// Then show information about failure
|
// update current notification with failure info
|
||||||
mNotifyManager!!.notify(SystemClock.uptimeMillis().toInt(), notification)
|
mNotifyManager!!.notify(SystemClock.uptimeMillis().toInt(), failureNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getResourceString(context: Context, resourceId: Int): String {
|
private fun getResourceString(context: Context, resourceId: Int): String {
|
||||||
|
@ -68,6 +68,10 @@ object NotificationUtils {
|
|||||||
// RemoteInput key - used for replies sent directly from notification
|
// RemoteInput key - used for replies sent directly from notification
|
||||||
const val KEY_DIRECT_REPLY = "key_direct_reply"
|
const val KEY_DIRECT_REPLY = "key_direct_reply"
|
||||||
|
|
||||||
|
// notification group keys
|
||||||
|
const val KEY_UPLOAD_GROUP = "com.nextcloud.talk.utils.KEY_UPLOAD_GROUP"
|
||||||
|
const val GROUP_SUMMARY_NOTIFICATION_ID = -1
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
private fun createNotificationChannel(
|
private fun createNotificationChannel(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -109,6 +109,7 @@
|
|||||||
<string name="nc_conversations_empty">会話に参加するか、新しいのを開始</string>
|
<string name="nc_conversations_empty">会話に参加するか、新しいのを開始</string>
|
||||||
<string name="nc_conversations_empty_details">友達や同僚に挨拶しましょう!</string>
|
<string name="nc_conversations_empty_details">友達や同僚に挨拶しましょう!</string>
|
||||||
<string name="nc_copy_message">コピー</string>
|
<string name="nc_copy_message">コピー</string>
|
||||||
|
<string name="nc_create_poll">投票を作成</string>
|
||||||
<string name="nc_date_header_today">今日</string>
|
<string name="nc_date_header_today">今日</string>
|
||||||
<string name="nc_date_header_yesterday">昨日</string>
|
<string name="nc_date_header_yesterday">昨日</string>
|
||||||
<string name="nc_delete">削除</string>
|
<string name="nc_delete">削除</string>
|
||||||
@ -144,6 +145,7 @@
|
|||||||
<string name="nc_expire_message_one_day">1日</string>
|
<string name="nc_expire_message_one_day">1日</string>
|
||||||
<string name="nc_expire_message_one_hour">1時間</string>
|
<string name="nc_expire_message_one_hour">1時間</string>
|
||||||
<string name="nc_expire_message_one_week">1週間</string>
|
<string name="nc_expire_message_one_week">1週間</string>
|
||||||
|
<string name="nc_expire_messages_explanation">チャットメッセージは、一定時間経過後に期限切れにすることができます。注意: チャットで共有されたファイルは、ファイル所有者は削除されませんが、会話では共有されなくなります。</string>
|
||||||
<string name="nc_external_server_failed">シグナリング設定を取得できませんでした</string>
|
<string name="nc_external_server_failed">シグナリング設定を取得できませんでした</string>
|
||||||
<string name="nc_failed_signaling_settings">ターゲットのサーバーは、モバイル経由での公開の会話への参加をサポートしていません。Webブラウザー経由で会話への参加を試みてください。</string>
|
<string name="nc_failed_signaling_settings">ターゲットのサーバーは、モバイル経由での公開の会話への参加をサポートしていません。Webブラウザー経由で会話への参加を試みてください。</string>
|
||||||
<string name="nc_failed_to_perform_operation">申し訳ありませんが、何かがおかしいです!</string>
|
<string name="nc_failed_to_perform_operation">申し訳ありませんが、何かがおかしいです!</string>
|
||||||
@ -330,6 +332,7 @@
|
|||||||
<string name="nc_settings_theme_key">テーマ</string>
|
<string name="nc_settings_theme_key">テーマ</string>
|
||||||
<string name="nc_settings_theme_light">ライト</string>
|
<string name="nc_settings_theme_light">ライト</string>
|
||||||
<string name="nc_settings_theme_title">テーマ</string>
|
<string name="nc_settings_theme_title">テーマ</string>
|
||||||
|
<string name="nc_settings_typing_status_desc">自分のタイピング状況を共有し、他の人のタイピング状況を表示する</string>
|
||||||
<string name="nc_settings_use_credentials_title">プロキシは資格情報を必要とします</string>
|
<string name="nc_settings_use_credentials_title">プロキシは資格情報を必要とします</string>
|
||||||
<string name="nc_settings_warning">警告</string>
|
<string name="nc_settings_warning">警告</string>
|
||||||
<string name="nc_settings_wrong_account">現在のアカウントのみ再認可できます</string>
|
<string name="nc_settings_wrong_account">現在のアカウントのみ再認可できます</string>
|
||||||
@ -377,8 +380,11 @@
|
|||||||
<string name="open_in_files_app">アプリでファイルを開く</string>
|
<string name="open_in_files_app">アプリでファイルを開く</string>
|
||||||
<string name="play_pause_voice_message">音声メッセージを再生/一時停止</string>
|
<string name="play_pause_voice_message">音声メッセージを再生/一時停止</string>
|
||||||
<string name="polls_add_option">オプションを追加</string>
|
<string name="polls_add_option">オプションを追加</string>
|
||||||
|
<string name="polls_end_poll">投票を終了する</string>
|
||||||
|
<string name="polls_multiple_answers">複数の答え</string>
|
||||||
<string name="polls_options">オプション</string>
|
<string name="polls_options">オプション</string>
|
||||||
<string name="polls_private_poll">プライベート投票</string>
|
<string name="polls_private_poll">プライベート投票</string>
|
||||||
|
<string name="polls_question">質問</string>
|
||||||
<string name="polls_results_subtitle">結果</string>
|
<string name="polls_results_subtitle">結果</string>
|
||||||
<string name="polls_settings">設定</string>
|
<string name="polls_settings">設定</string>
|
||||||
<string name="polls_submit_vote">投票</string>
|
<string name="polls_submit_vote">投票</string>
|
||||||
@ -386,9 +392,13 @@
|
|||||||
<string name="reactions_tab_all">すべて</string>
|
<string name="reactions_tab_all">すべて</string>
|
||||||
<string name="read_storage_no_permission">ストレージからのファイル共有は権限がなければ不可能です</string>
|
<string name="read_storage_no_permission">ストレージからのファイル共有は権限がなければ不可能です</string>
|
||||||
<string name="record_cancel_start">録画開始をキャンセル</string>
|
<string name="record_cancel_start">録画開始をキャンセル</string>
|
||||||
|
<string name="record_failed_info">レコーディングが失敗しました。あなたの管理者に連絡してください。</string>
|
||||||
<string name="record_start_description">録画を開始</string>
|
<string name="record_start_description">録画を開始</string>
|
||||||
<string name="record_stop_description">録画を停止</string>
|
<string name="record_stop_description">録画を停止</string>
|
||||||
|
<string name="recording_consent_all">全ての通話には録音の同意が必要です。</string>
|
||||||
|
<string name="recording_consent_for_conversation_description">この会話に参加する前に、録音の同意が必要です。</string>
|
||||||
<string name="recording_consent_for_conversation_title">レコーディングの同意</string>
|
<string name="recording_consent_for_conversation_title">レコーディングの同意</string>
|
||||||
|
<string name="recording_consent_title">通話は録音されるかもしれません。</string>
|
||||||
<string name="recording_settings_title">記録中</string>
|
<string name="recording_settings_title">記録中</string>
|
||||||
<string name="save">保存</string>
|
<string name="save">保存</string>
|
||||||
<string name="scope_federated_description">信頼できるサーバーのみと同期</string>
|
<string name="scope_federated_description">信頼できるサーバーのみと同期</string>
|
||||||
@ -417,6 +427,7 @@
|
|||||||
<string name="shared_items_file">ファイル</string>
|
<string name="shared_items_file">ファイル</string>
|
||||||
<string name="shared_items_media">メディア</string>
|
<string name="shared_items_media">メディア</string>
|
||||||
<string name="shared_items_other">その他</string>
|
<string name="shared_items_other">その他</string>
|
||||||
|
<string name="shared_items_poll">投票</string>
|
||||||
<string name="shared_items_voice">音声番号</string>
|
<string name="shared_items_voice">音声番号</string>
|
||||||
<string name="starred">お気に入り</string>
|
<string name="starred">お気に入り</string>
|
||||||
<string name="startCallForbidden">通話を開始することが許可されていません</string>
|
<string name="startCallForbidden">通話を開始することが許可されていません</string>
|
||||||
@ -436,6 +447,7 @@
|
|||||||
<string name="today">今日</string>
|
<string name="today">今日</string>
|
||||||
<string name="tomorrow">明日</string>
|
<string name="tomorrow">明日</string>
|
||||||
<string name="translate">翻訳</string>
|
<string name="translate">翻訳</string>
|
||||||
|
<string name="translation_copy_translated_text">翻訳されたテキストをコピー</string>
|
||||||
<string name="translation_detect_language">言語を検出する</string>
|
<string name="translation_detect_language">言語を検出する</string>
|
||||||
<string name="translation_device_settings">デバイスの設定</string>
|
<string name="translation_device_settings">デバイスの設定</string>
|
||||||
<string name="translation_error_message">言語を検出できませんでした</string>
|
<string name="translation_error_message">言語を検出できませんでした</string>
|
||||||
|
@ -264,7 +264,7 @@
|
|||||||
<string name="nc_settings">Impostatziones</string>
|
<string name="nc_settings">Impostatziones</string>
|
||||||
<string name="nc_settings_account_updated">Su contu chi tenias giai est istadu agiornadu, imbetzes de nd\'agiùnghere unu nou</string>
|
<string name="nc_settings_account_updated">Su contu chi tenias giai est istadu agiornadu, imbetzes de nd\'agiùnghere unu nou</string>
|
||||||
<string name="nc_settings_advanced_title">Avantzadu</string>
|
<string name="nc_settings_advanced_title">Avantzadu</string>
|
||||||
<string name="nc_settings_appearance">Visibilidade</string>
|
<string name="nc_settings_appearance">Aspetu</string>
|
||||||
<string name="nc_settings_call_ringtone">Mutidas</string>
|
<string name="nc_settings_call_ringtone">Mutidas</string>
|
||||||
<string name="nc_settings_incognito_keyboard_desc">Imparat a sa tastiera a disativare s\'imparu personale (chene garantzias)</string>
|
<string name="nc_settings_incognito_keyboard_desc">Imparat a sa tastiera a disativare s\'imparu personale (chene garantzias)</string>
|
||||||
<string name="nc_settings_incognito_keyboard_title">Tastiera in incògnita</string>
|
<string name="nc_settings_incognito_keyboard_title">Tastiera in incògnita</string>
|
||||||
|
@ -143,7 +143,10 @@
|
|||||||
<trusted-key id="AFCC4C7594D09E2182C60E0F7A01B0F236E5430F" group="com.google.code.gson"/>
|
<trusted-key id="AFCC4C7594D09E2182C60E0F7A01B0F236E5430F" group="com.google.code.gson"/>
|
||||||
<trusted-key id="B02335AA54CCF21E52BBF9ABD9C565AA72BA2FDD" group="io.grpc"/>
|
<trusted-key id="B02335AA54CCF21E52BBF9ABD9C565AA72BA2FDD" group="io.grpc"/>
|
||||||
<trusted-key id="B087A0EB8416563AFE64CEBA4604091C01C3086A" group="com.mebigfatguy.fb-contrib" name="fb-contrib" version="7.6.4"/>
|
<trusted-key id="B087A0EB8416563AFE64CEBA4604091C01C3086A" group="com.mebigfatguy.fb-contrib" name="fb-contrib" version="7.6.4"/>
|
||||||
<trusted-key id="B41089A2DA79B0FA5810252872385FF0AF338D52" group="joda-time" name="joda-time" version="2.12.6"/>
|
<trusted-key id="B41089A2DA79B0FA5810252872385FF0AF338D52">
|
||||||
|
<trusting group="joda-time" name="joda-time" version="2.12.6"/>
|
||||||
|
<trusting group="joda-time" name="joda-time" version="2.12.7"/>
|
||||||
|
</trusted-key>
|
||||||
<trusted-key id="B6E73D84EA4FCC47166087253FAAD2CD5ECBB314" group="org.apache.commons" name="commons-parent" version="52"/>
|
<trusted-key id="B6E73D84EA4FCC47166087253FAAD2CD5ECBB314" group="org.apache.commons" name="commons-parent" version="52"/>
|
||||||
<trusted-key id="B801E2F8EF035068EC1139CC29579F18FA8FD93B" group="com.google.j2objc" name="j2objc-annotations" version="1.3"/>
|
<trusted-key id="B801E2F8EF035068EC1139CC29579F18FA8FD93B" group="com.google.j2objc" name="j2objc-annotations" version="1.3"/>
|
||||||
<trusted-key id="BC87A3FD0A54480F0BADBEBD21939FF0CA2A6567" group="commons-codec" name="commons-codec" version="1.15"/>
|
<trusted-key id="BC87A3FD0A54480F0BADBEBD21939FF0CA2A6567" group="commons-codec" name="commons-codec" version="1.15"/>
|
||||||
@ -1879,6 +1882,14 @@
|
|||||||
<sha256 value="89c21ebe5a3aedd8c910bbe0f7c0c6ea6f30dc9dba58d68b39bee3759a7dc52f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="89c21ebe5a3aedd8c910bbe0f7c0c6ea6f30dc9dba58d68b39bee3759a7dc52f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="com.github.nextcloud.android-common" name="core" version="0.15.0">
|
||||||
|
<artifact name="core-0.15.0.aar">
|
||||||
|
<sha256 value="d370010eeae5928f525f31c09e33f9c78ed5e610af4b9f84b1ba68ce0727267b" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="core-0.15.0.module">
|
||||||
|
<sha256 value="609090237e7d6c9745dcb883819e53bb4c9337b89740aa88fd1c56d73ecfa56b" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="com.github.nextcloud.android-common" name="material-color-utilities" version="0.14.0">
|
<component group="com.github.nextcloud.android-common" name="material-color-utilities" version="0.14.0">
|
||||||
<artifact name="material-color-utilities-0.14.0.jar">
|
<artifact name="material-color-utilities-0.14.0.jar">
|
||||||
<sha256 value="bfcd5205b056b948bc6ff9a556898188f4a4e92179c723906e10f1164b776eed" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="bfcd5205b056b948bc6ff9a556898188f4a4e92179c723906e10f1164b776eed" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
@ -1887,6 +1898,14 @@
|
|||||||
<sha256 value="b12eadfbfe39b7fb6e62a13c9aca93b468e66a0cf0a2d841b849fe86ebc2d605" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="b12eadfbfe39b7fb6e62a13c9aca93b468e66a0cf0a2d841b849fe86ebc2d605" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="com.github.nextcloud.android-common" name="material-color-utilities" version="0.15.0">
|
||||||
|
<artifact name="material-color-utilities-0.15.0.jar">
|
||||||
|
<sha256 value="ced5cd660ebfa6aa7461a2157f67a8e76ae12830f759adec0b51631de4ac5434" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="material-color-utilities-0.15.0.module">
|
||||||
|
<sha256 value="edc221870d47808e96595f11d58dc6f45e50a9d8979658f024ae9a816778ecfb" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="com.github.nextcloud.android-common" name="ui" version="0.14.0">
|
<component group="com.github.nextcloud.android-common" name="ui" version="0.14.0">
|
||||||
<artifact name="ui-0.14.0.aar">
|
<artifact name="ui-0.14.0.aar">
|
||||||
<sha256 value="2ff1b8ca1ce4d4151ce967c4704a4def19a128d3f710491872e007217f3ac84f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="2ff1b8ca1ce4d4151ce967c4704a4def19a128d3f710491872e007217f3ac84f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
@ -1895,6 +1914,14 @@
|
|||||||
<sha256 value="a600ef42a3ffe9a5900893f7f68052272ed8749ae2c5c44471f792f9d1d9d01f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="a600ef42a3ffe9a5900893f7f68052272ed8749ae2c5c44471f792f9d1d9d01f" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="com.github.nextcloud.android-common" name="ui" version="0.15.0">
|
||||||
|
<artifact name="ui-0.15.0.aar">
|
||||||
|
<sha256 value="7e520034d730a11f5089548a8f15fbdd5d5054f8f0465f711664235b3939b78d" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="ui-0.15.0.module">
|
||||||
|
<sha256 value="ac04b3a93aae2e9e8585d01447210fe0c5c85dec13e241b5e7c8956a3ed8a962" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="com.github.wooplr" name="Spotlight" version="1.3">
|
<component group="com.github.wooplr" name="Spotlight" version="1.3">
|
||||||
<artifact name="Spotlight-1.3.aar">
|
<artifact name="Spotlight-1.3.aar">
|
||||||
<sha256 value="2216a78710c8626623d3fd8f6519ec49e26d86930757b51288b7889653b7b44e" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="2216a78710c8626623d3fd8f6519ec49e26d86930757b51288b7889653b7b44e" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
@ -2225,6 +2252,14 @@
|
|||||||
<sha256 value="f376e72c66dac4215b25d8dcda887ca355c661f630d2d155160e0c6dca7d4ace" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="f376e72c66dac4215b25d8dcda887ca355c661f630d2d155160e0c6dca7d4ace" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="com.google.firebase" name="firebase-messaging" version="23.4.1">
|
||||||
|
<artifact name="firebase-messaging-23.4.1.aar">
|
||||||
|
<sha256 value="15c2637c28fb6895b6a4c998a191b663f3b78ac815f6ac59ab7d673a8d9af202" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="firebase-messaging-23.4.1.pom">
|
||||||
|
<sha256 value="188ee169e2d73488e9b14c7610bf3fd9a834658c0759af51b16b0b255865f7c6" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="com.google.guava" name="failureaccess" version="1.0.1">
|
<component group="com.google.guava" name="failureaccess" version="1.0.1">
|
||||||
<artifact name="failureaccess-1.0.1.pom">
|
<artifact name="failureaccess-1.0.1.pom">
|
||||||
<sha256 value="e96042ce78fecba0da2be964522947c87b40a291b5fd3cd672a434924103c4b9" origin="Generated by Gradle"/>
|
<sha256 value="e96042ce78fecba0da2be964522947c87b40a291b5fd3cd672a434924103c4b9" origin="Generated by Gradle"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user