Skip to content

Commit

Permalink
Merge branch 'develop' into feat/move-to-folder
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas committed Jan 9, 2025
2 parents 94e478f + b711329 commit c8eb5ce
Show file tree
Hide file tree
Showing 141 changed files with 3,706 additions and 1,629 deletions.
8 changes: 4 additions & 4 deletions .github/actions/deploy-to-s3/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ runs:
aws-bucket: ${{ inputs.aws-bucket }}
destination-dir: "megazord/android/reloaded/${{ inputs.build-flavour }}/${{ inputs.build-variant }}/PR-${{ github.event.pull_request.number }}/"
file-path: ${{ steps.path.outputs.apk_full_path }}
output-file-url: 'true'
public: true
output-file-url: 'false'
public: false
- name: Upload to S3 from branch
if: github.event.pull_request.number == ''
id: upload-from-branch
Expand All @@ -53,8 +53,8 @@ runs:
aws-bucket: ${{ inputs.aws-bucket }}
destination-dir: "megazord/android/reloaded/${{ inputs.build-flavour }}/${{ inputs.build-variant }}/"
file-path: ${{ steps.path.outputs.apk_full_path }}
output-file-url: 'true'
public: true
output-file-url: 'false'
public: false
- name: Show URL
if: github.event.pull_request.number != ''
shell: bash
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ dependencies {
implementation(libs.aboutLibraries.core)
implementation(libs.aboutLibraries.ui)
implementation(libs.compose.qr.code)
implementation(libs.audio.amplituda)

// screenshot testing
screenshotTestImplementation(libs.compose.ui.tooling)
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/kotlin/com/wire/android/WireApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.wire.android.datastore.UserDataStoreProvider
import com.wire.android.debug.DatabaseProfilingManager
import com.wire.android.di.ApplicationScope
import com.wire.android.di.KaliumCoreLogic
import com.wire.android.feature.analytics.AnonymousAnalyticsManager
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.feature.analytics.AnonymousAnalyticsRecorderImpl
import com.wire.android.feature.analytics.globalAnalyticsManager
Expand All @@ -48,12 +49,15 @@ import com.wire.kalium.logger.KaliumLogLevel
import com.wire.kalium.logger.KaliumLogger
import com.wire.kalium.logic.CoreLogger
import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.logic.feature.session.CurrentSessionResult
import dagger.Lazy
import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
Expand Down Expand Up @@ -93,6 +97,9 @@ class WireApplication : BaseApp() {
@Inject
lateinit var databaseProfilingManager: DatabaseProfilingManager

@Inject
lateinit var analyticsManager: Lazy<AnonymousAnalyticsManager>

override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(wireWorkerFactory.get())
Expand Down Expand Up @@ -121,9 +128,22 @@ class WireApplication : BaseApp() {

appLogger.i("$TAG global observers")
globalObserversManager.get().observe()

observeRecentlyEndedCall()
}
}

private suspend fun observeRecentlyEndedCall() {
coreLogic.get().getGlobalScope().session.currentSessionFlow().filterIsInstance(CurrentSessionResult.Success::class)
.filter { session -> session.accountInfo.isValid() }
.flatMapLatest { session ->
coreLogic.get().getSessionScope(session.accountInfo.userId).calls.observeRecentlyEndedCallMetadata()
}
.collect { metadata ->
analyticsManager.get().sendEvent(AnalyticsEvent.RecentlyEndedCallEvent(metadata))
}
}

private fun enableStrictMode() {
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import linc.com.amplituda.Amplituda
import javax.inject.Qualifier
import javax.inject.Singleton

Expand Down Expand Up @@ -84,6 +85,9 @@ object AppModule {
}
}

@Provides
fun provideAmplituda(appContext: Context): Amplituda = Amplituda(appContext)

@Singleton
@Provides
fun provideCurrentTimestampProvider(): CurrentTimestampProvider = { System.currentTimeMillis() }
Expand Down
10 changes: 8 additions & 2 deletions app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ class UseCaseModule {
fun provideMigrateFromPersonalToTeamUseCase(
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
) =
coreLogic.getSessionScope(currentAccount).migrateFromPersonalToTeam
) = coreLogic.getSessionScope(currentAccount).migrateFromPersonalToTeam

@ViewModelScoped
@Provides
fun provideGetTeamUrlUseCase(
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
) = coreLogic.getSessionScope(currentAccount).getTeamUrlUseCase
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ package com.wire.android.di.accountScoped

import com.wire.android.di.CurrentAccount
import com.wire.android.di.KaliumCoreLogic
import dagger.Module
import dagger.Provides
import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.call.CallsScope
Expand All @@ -40,6 +38,8 @@ import com.wire.kalium.logic.feature.call.usecase.TurnLoudSpeakerOnUseCase
import com.wire.kalium.logic.feature.call.usecase.UnMuteCallUseCase
import com.wire.kalium.logic.feature.call.usecase.video.SetVideoSendStateUseCase
import com.wire.kalium.logic.feature.call.usecase.video.UpdateVideoStateUseCase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.scopes.ViewModelScoped
Expand Down Expand Up @@ -202,4 +202,9 @@ class CallsModule {
@Provides
fun provideObserveConferenceCallingEnabledUseCase(callsScope: CallsScope) =
callsScope.observeConferenceCallingEnabled

@ViewModelScoped
@Provides
fun provideObserveInCallReactionsUseCase(callsScope: CallsScope) =
callsScope.observeInCallReactions
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ import com.wire.kalium.logic.feature.asset.ObserveAssetStatusesUseCase
import com.wire.kalium.logic.feature.asset.ObservePaginatedAssetImageMessages
import com.wire.kalium.logic.feature.asset.ScheduleNewAssetMessageUseCase
import com.wire.kalium.logic.feature.asset.UpdateAssetMessageTransferStatusUseCase
import com.wire.kalium.logic.feature.incallreaction.SendInCallReactionUseCase
import com.wire.kalium.logic.feature.message.DeleteMessageUseCase
import com.wire.kalium.logic.feature.message.GetMessageByIdUseCase
import com.wire.kalium.logic.feature.message.GetNotificationsUseCase
import com.wire.kalium.logic.feature.message.GetPaginatedFlowOfMessagesByConversationUseCase
import com.wire.kalium.logic.feature.message.GetPaginatedFlowOfMessagesBySearchQueryAndConversationIdUseCase
import com.wire.kalium.logic.feature.message.GetSearchedConversationMessagePositionUseCase
import com.wire.kalium.logic.feature.message.GetSenderNameByMessageIdUseCase
import com.wire.kalium.logic.feature.message.MarkMessagesAsNotifiedUseCase
import com.wire.kalium.logic.feature.message.MessageScope
import com.wire.kalium.logic.feature.message.ObserveMessageReactionsUseCase
Expand Down Expand Up @@ -216,4 +218,14 @@ class MessageModule {
@Provides
fun provideRemoveMessageDraftUseCase(messageScope: MessageScope): RemoveMessageDraftUseCase =
messageScope.removeMessageDraftUseCase

@ViewModelScoped
@Provides
fun provideSendInCallReactionUseCase(messageScope: MessageScope): SendInCallReactionUseCase =
messageScope.sendInCallReactionUseCase

@ViewModelScoped
@Provides
fun provideGetSenderNameByMessageIdUseCase(messageScope: MessageScope): GetSenderNameByMessageIdUseCase =
messageScope.getSenderNameByMessageId
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ package com.wire.android.mapper
import com.wire.android.model.ImageAsset
import com.wire.android.ui.calling.model.UICallParticipant
import com.wire.kalium.logic.data.call.Participant
import com.wire.kalium.logic.data.conversation.ClientId
import javax.inject.Inject

class UICallParticipantMapper @Inject constructor(
private val userTypeMapper: UserTypeMapper,
) {
fun toUICallParticipant(participant: Participant) = UICallParticipant(
fun toUICallParticipant(participant: Participant, currentClientId: ClientId) = UICallParticipant(
id = participant.id,
clientId = participant.clientId,
isSelfUser = participant.clientId == currentClientId.value,
name = participant.name,
isMuted = participant.isMuted,
isSpeaking = participant.isSpeaking,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,24 @@
*/
package com.wire.android.media.audiomessage

import androidx.annotation.StringRes
import com.wire.android.R

data class AudioState(
val audioMediaPlayingState: AudioMediaPlayingState,
val currentPositionInMs: Int,
val totalTimeInMs: TotalTimeInMs
val totalTimeInMs: TotalTimeInMs,
val wavesMask: List<Int>
) {
companion object {
val DEFAULT = AudioState(AudioMediaPlayingState.Stopped, 0, TotalTimeInMs.NotKnown)
val DEFAULT = AudioState(AudioMediaPlayingState.Stopped, 0, TotalTimeInMs.NotKnown, listOf())
}

// if the back-end returned the total time, we use that, in case it didn't we use what we get from
// the [ConversationAudioMessagePlayer.kt] which will emit the time once the users play the audio.
fun sanitizeTotalTime(otherClientTotalTime: Int): TotalTimeInMs {
if (otherClientTotalTime != 0) {
return TotalTimeInMs.Known(otherClientTotalTime)
return TotalTimeInMs.Known(otherClientTotalTime)
}

return totalTimeInMs
Expand All @@ -43,6 +47,27 @@ data class AudioState(
}
}

@Suppress("MagicNumber")
enum class AudioSpeed(val value: Float, @StringRes val titleRes: Int) {
NORMAL(1f, R.string.audio_speed_1),
FAST(1.5f, R.string.audio_speed_1_5),
MAX(2f, R.string.audio_speed_2);

fun toggle(): AudioSpeed = when (this) {
NORMAL -> FAST
FAST -> MAX
MAX -> NORMAL
}

companion object {
fun fromFloat(speed: Float): AudioSpeed = when {
(speed < FAST.value) -> NORMAL
(speed < MAX.value) -> FAST
else -> MAX
}
}
}

sealed class AudioMediaPlayingState {
object Playing : AudioMediaPlayingState()
object Stopped : AudioMediaPlayingState()
Expand Down Expand Up @@ -75,6 +100,11 @@ sealed class AudioMediaPlayerStateUpdate(
override val messageId: String,
val totalTimeInMs: Int
) : AudioMediaPlayerStateUpdate(messageId)

data class WaveMaskUpdate(
override val messageId: String,
val waveMask: List<Int>
) : AudioMediaPlayerStateUpdate(messageId)
}

sealed class RecordAudioMediaPlayerStateUpdate {
Expand All @@ -89,4 +119,8 @@ sealed class RecordAudioMediaPlayerStateUpdate {
data class TotalTimeUpdate(
val totalTimeInMs: Int
) : RecordAudioMediaPlayerStateUpdate()

data class WaveMaskUpdate(
val waveMask: List<Int>
) : RecordAudioMediaPlayerStateUpdate()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.android.media.audiomessage

import linc.com.amplituda.Amplituda
import linc.com.amplituda.Cache
import okio.Path
import java.io.File
import javax.inject.Inject
import kotlin.math.roundToInt

class AudioWavesMaskHelper @Inject constructor(
private val amplituda: Amplituda
) {

companion object {
private const val WAVES_AMOUNT = 75
private const val WAVE_MAX = 32
}

fun getWaveMask(decodedAssetPath: Path): List<Int> = getWaveMask(File(decodedAssetPath.toString()))

fun getWaveMask(file: File): List<Int> = amplituda
.processAudio(file, Cache.withParams(Cache.REUSE))
.get()
.amplitudesAsList()
.averageWavesMask()
.equalizeWavesMask()

private fun List<Double>.equalizeWavesMask(): List<Int> {
if (this.isEmpty()) return listOf()

val divider = max() / (WAVE_MAX - 1)
return map { (it / divider).roundToInt() + 1 }
}

private fun List<Int>.averageWavesMask(): List<Double> {
val wavesSize = size
val sectionSize = (wavesSize.toFloat() / WAVES_AMOUNT).roundToInt()

if (wavesSize < WAVES_AMOUNT || sectionSize == 1) return map { it.toDouble() }

val averagedWaves = mutableListOf<Double>()
for (i in 0..<(wavesSize / sectionSize)) {
val startIndex = (i * sectionSize)
if (startIndex >= wavesSize) continue
val endIndex = (startIndex + sectionSize).coerceAtMost(wavesSize - 1)
averagedWaves.add(subList(startIndex, endIndex).averageInt())
}
return averagedWaves
}

private fun List<Int>.averageInt(): Double {
if (isEmpty()) return 0.0
return sum().toDouble() / size
}

fun clear() {
amplituda.clearCache()
}
}
Loading

0 comments on commit c8eb5ce

Please sign in to comment.