Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/develop' into fix/r…
Browse files Browse the repository at this point in the history
…esolve-custom-colors
  • Loading branch information
saleniuk committed Nov 22, 2024
2 parents fed26d3 + c911271 commit caf7880
Show file tree
Hide file tree
Showing 83 changed files with 1,530 additions and 765 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build-edge-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,5 @@ jobs:
serviceAccountJson: service_account.json
packageName: com.wire.internal
releaseFiles: app/build/outputs/bundle/internalCompat/*.aab
track: alpha
track: production
status: completed
2 changes: 1 addition & 1 deletion .github/workflows/deploy-adr-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Deploy docs 🚀
if: github.event_name == 'push' && github.ref_name == 'develop'
uses: JamesIves/[email protected].8
uses: JamesIves/[email protected].9
with:
branch: gh-pages
clean: false
Expand Down
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Contributing

## I want to contribute to Wire

You can contribute to Wire in several ways:

## Finding bugs

If you find a bug in how Wire apps work, please submit a ticket to [our support](https://support.wire.com) and we will keep you informed about the progress.
Alternatively, you can submit your finding on [wire issues](https://github.com/wireapp/wire/issues). Please make sure to provide as much information as possible to help us reproduce the issue.

## Contributing to the code

If you wish to contribute source code to one of our repositories you have to sign
our [Contributor Agreement](https://github.com/wireapp/wire/raw/master/assets/Wire%20Contributor%20Agreement.pdf)
first.

When you submit your first pull request, you can sign the agreement electronically by filling in the
required information. You will not have to sign it again for subsequent pull requests from the same
GitHub account.

When opening a pull request, please make sure to follow the next guidelines:

- Make sure to fill in the pull request template to the fullest extent possible, this will help us
understand faster the changes proposed.
- Make sure to run the tests and linters before submitting the pull request.
- Add the necessary tests for the changes you are proposing, this will help us ensure that the
changes are working as expected.

> [!NOTE]
> We accept only bug fixes and code improvements. We cannot accept new features, UI or UX changes – these are decided by Wire and built by the Wire development team.
## I want to help translate Wire

If you want to help Wire to speak more languages, please refer to our [site](https://support.wire.com/hc/en-us/articles/202856874-Language-support), to see the official list of supported languages and those who are open to contribute.

To do so, you will find instructions there, but you can do the following:

1. Create a [Crowdin account](https://crowdin.com/).
2. Request access to add translations in our [project](https://crowdin.com/project/wire-android-reloaded).
3. Translate away.
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,6 @@ It might be that after cloning the Android project, some build issues appear on
- There is a valid SDK path on your `local.properties` AND `kalium/local.properties` files pointing to the Android SDK folder. In Mac, that folder can be usually found under `sdk.dir=/Users/YOUR_USER_FOLDER/Library/Android/sdk`. The IDE **will not** create `kalium/local.properties` automatically, so you might want to copy/paste the one in the project root
- When you've already started working on the project adding some commits, it might occur that your local build breaks, if that is the case, make sure you've updated the `kalium` submodule reference by running: `git submodule update --remote --merge`

## Contributing

If you want to help Wire to speak more languages, please refer to our [site](https://support.wire.com/hc/en-us/articles/202856874-Language-support), to see the official list of supported languages and those who are open to contribute.

To do so, you will find instructions there, but you can do the following:

1. Create a [Crowdin account](https://crowdin.com/).
2. Request access to add translations in our [project](https://crowdin.com/project/wire-android-reloaded).
3. Translate away.

# App flavours

We have a few different app flavours with different intended usages. Each app flavour has a different icon background colour to enable easier distinction.
Expand Down Expand Up @@ -99,3 +89,7 @@ To see how they are customised in details, check [the flavour configuration file
## Build Types

The apps can be built for release or debugging. Debug versions might have extra debugging tools, are not minified, and can be profiled if needed. In general, debug builds _run slower_ due to the lack of minimisation.

## Contributing

If you want to contribute to Wire for Android, please refer to the [CONTRIBUTING.md](./CONTRIBUTING.md) file for more information.
5 changes: 1 addition & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -308,14 +308,11 @@
android:name=".notification.broadcastreceivers.NotificationReplyReceiver"
android:exported="false" />
<receiver
android:name=".notification.broadcastreceivers.DeclineIncomingCallReceiver"
android:name=".notification.broadcastreceivers.IncomingCallActionReceiver"
android:exported="false" />
<receiver
android:name=".notification.broadcastreceivers.EndOngoingCallReceiver"
android:exported="false" />
<receiver
android:name=".notification.broadcastreceivers.CallNotificationDismissedReceiver"
android:exported="false" />

<service
android:name=".services.WireFirebaseMessagingService"
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -492,4 +492,12 @@ class UseCaseModule {
@Provides
fun provideSendFCMTokenToAPIUseCase(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId) =
coreLogic.getSessionScope(currentAccount).debug.sendFCMTokenToServer

@ViewModelScoped
@Provides
fun provideMigrateFromPersonalToTeamUseCase(
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
) =
coreLogic.getSessionScope(currentAccount).migrateFromPersonalToTeam
}
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,14 @@ class ConversationModule {
@Provides
fun provideGetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase(conversationScope: ConversationScope) =
conversationScope.getPaginatedFlowOfConversationDetailsWithEventsBySearchQuery

@ViewModelScoped
@Provides
fun provideObserveConversationsFromFolderUseCase(conversationScope: ConversationScope) =
conversationScope.observeConversationsFromFolder

@ViewModelScoped
@Provides
fun provideGetFavoriteFolderUseCase(conversationScope: ConversationScope) =
conversationScope.getFavoriteFolder
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fun ConversationDetailsWithEvents.toConversationItem(
groupName = conversationDetails.conversation.name.orEmpty(),
conversationId = conversationDetails.conversation.id,
mutedStatus = conversationDetails.conversation.mutedStatus,
isLegalHold = conversationDetails.conversation.legalHoldStatus.showLegalHoldIndicator(),
showLegalHoldIndicator = conversationDetails.conversation.legalHoldStatus.showLegalHoldIndicator(),
lastMessageContent = lastMessage.toUIPreview(unreadEventCount),
badgeEventType = parseConversationEventType(
mutedStatus = conversationDetails.conversation.mutedStatus,
Expand Down Expand Up @@ -83,7 +83,7 @@ fun ConversationDetailsWithEvents.toConversationItem(
),
conversationId = conversationDetails.conversation.id,
mutedStatus = conversationDetails.conversation.mutedStatus,
isLegalHold = conversationDetails.conversation.legalHoldStatus.showLegalHoldIndicator(),
showLegalHoldIndicator = conversationDetails.conversation.legalHoldStatus.showLegalHoldIndicator(),
lastMessageContent = lastMessage.toUIPreview(unreadEventCount),
badgeEventType = parsePrivateConversationEventType(
conversationDetails.otherUser.connectionStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class MessageMapper @Inject constructor(
is SelfUser, null -> Membership.None
},
connectionState = getConnectionState(sender),
isLegalHold = sender?.isUnderLegalHold == true,
showLegalHoldIndicator = sender?.isUnderLegalHold == true,
messageTime = MessageTime(message.date),
messageStatus = getMessageStatus(message),
messageId = message.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import android.app.Notification
import android.content.Context
import android.service.notification.StatusBarNotification
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.CallStyle
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.Person
import com.wire.android.R
import com.wire.android.appLogger
import com.wire.android.notification.NotificationConstants.INCOMING_CALL_ID_PREFIX
Expand All @@ -36,15 +38,11 @@ import com.wire.kalium.logic.data.id.QualifiedID
import com.wire.kalium.logic.data.user.UserId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.scan
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand All @@ -64,7 +62,6 @@ class CallNotificationManager @Inject constructor(
private val notificationManager = NotificationManagerCompat.from(context)
private val scope = CoroutineScope(SupervisorJob() + dispatcherProvider.default())
private val incomingCallsForUsers = MutableStateFlow<Map<UserId, IncomingCallsForUser>>(mapOf())
private val reloadCallNotification = MutableSharedFlow<CallNotificationIds>()

init {
scope.launch {
Expand All @@ -81,16 +78,6 @@ class CallNotificationManager @Inject constructor(
currentCalls to (currentCalls - previousCalls.toSet())
}
.distinctUntilChanged()
.flatMapLatest { (allCurrentCalls, newCalls) ->
reloadCallNotification
.map { (userIdString, conversationIdString) ->
allCurrentCalls to allCurrentCalls.filter { // emit call that needs to be reloaded as newOrUpdated
it.userId.toString() == userIdString && it.conversationId.toString() == conversationIdString
}
}
.filter { (_, newCalls) -> newCalls.isNotEmpty() } // only emit if there is something to reload
.onStart { emit(allCurrentCalls to newCalls) }
}
.collectLatest { (allCurrentCalls, newCalls) ->
// remove outdated incoming call notifications
hideOutdatedIncomingCallNotifications(allCurrentCalls)
Expand All @@ -111,10 +98,6 @@ class CallNotificationManager @Inject constructor(
hideIncomingCallNotifications { _, id -> !currentIncomingCallNotificationIds.contains(id) }
}

fun reloadCallNotifications(reloadCallNotificationIds: CallNotificationIds) = scope.launch {
reloadCallNotification.emit(reloadCallNotificationIds)
}

fun handleIncomingCalls(calls: List<Call>, userId: UserId, userName: String) {
if (calls.isEmpty()) {
incomingCallsForUsers.update {
Expand Down Expand Up @@ -167,8 +150,6 @@ class CallNotificationManager @Inject constructor(
notificationManager.notify(tag, id, notification)
}

// Notifications

companion object {
private const val TAG = "CallNotificationManager"
private const val CANCEL_CALL_NOTIFICATION_DELAY = 300L
Expand All @@ -187,9 +168,11 @@ class CallNotificationBuilder @Inject constructor(
val userIdString = data.userId.toString()
val conversationIdString = data.conversationId.toString()
val channelId = NotificationConstants.getOutgoingChannelId(data.userId)
val person = Person.Builder().setName(data.conversationName).build()

return NotificationCompat.Builder(context, channelId)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
val notificationBuilder = NotificationCompat.Builder(context, channelId)
return notificationBuilder
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setSmallIcon(R.drawable.notification_icon_small)
.setContentTitle(data.conversationName)
Expand All @@ -198,11 +181,16 @@ class CallNotificationBuilder @Inject constructor(
.setAutoCancel(false)
.setOngoing(true)
.setSilent(true)
.setStyle(
CallStyle.forOngoingCall(
person,
endOngoingCallPendingIntent(context, conversationIdString, userIdString)
)
)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.addAction(getHangUpCallAction(context, conversationIdString, userIdString))
.setFullScreenIntent(outgoingCallPendingIntent(context, conversationIdString), true)
.setContentIntent(outgoingCallPendingIntent(context, conversationIdString))
.setDeleteIntent(callNotificationDismissedPendingIntent(context, userIdString, conversationIdString))
.build()
}

Expand All @@ -212,6 +200,7 @@ class CallNotificationBuilder @Inject constructor(
val title = getNotificationTitle(data)
val content = getNotificationBody(data)
val channelId = NotificationConstants.getIncomingChannelId(data.userId)
val person = Person.Builder().setName(title).build()

val notification = NotificationCompat.Builder(context, channelId)
.setPriority(NotificationCompat.PRIORITY_MAX)
Expand All @@ -222,13 +211,17 @@ class CallNotificationBuilder @Inject constructor(
.setSubText(data.userName)
.setAutoCancel(false)
.setOngoing(true)
.setStyle(
CallStyle.forIncomingCall(
person,
declineCallPendingIntent(context, conversationIdString, userIdString),
answerCallPendingIntent(context, conversationIdString, userIdString)
)
)
.setVibrate(VIBRATE_PATTERN)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.addAction(getDeclineCallAction(context, conversationIdString, userIdString))
.addAction(getOpenIncomingCallAction(context, conversationIdString, userIdString))
.setFullScreenIntent(fullScreenIncomingCallPendingIntent(context, conversationIdString, userIdString), true)
.setContentIntent(fullScreenIncomingCallPendingIntent(context, conversationIdString, userIdString))
.setDeleteIntent(callNotificationDismissedPendingIntent(context, userIdString, conversationIdString))
.build()

// Added FLAG_INSISTENT so the ringing sound repeats itself until an action is done.
Expand All @@ -242,6 +235,7 @@ class CallNotificationBuilder @Inject constructor(
val conversationIdString = data.conversationId.toString()
val userIdString = data.userId.toString()
val title = getNotificationTitle(data)
val person = Person.Builder().setName(title).build()

return NotificationCompat.Builder(context, channelId)
.setContentTitle(title)
Expand All @@ -254,11 +248,15 @@ class CallNotificationBuilder @Inject constructor(
.setAutoCancel(true)
.setOngoing(true)
.setUsesChronometer(true)
.addAction(getHangUpCallAction(context, conversationIdString, userIdString))
.addAction(getOpenOngoingCallAction(context, conversationIdString))
.setStyle(
CallStyle.forOngoingCall(
person,
endOngoingCallPendingIntent(context, conversationIdString, userIdString)
)
)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.setFullScreenIntent(openOngoingCallPendingIntent(context, conversationIdString), true)
.setContentIntent(openOngoingCallPendingIntent(context, conversationIdString))
.setDeleteIntent(callNotificationDismissedPendingIntent(context, userIdString, conversationIdString))
.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package com.wire.android.notification

import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import androidx.core.app.NotificationCompat
import androidx.core.app.RemoteInput
Expand Down Expand Up @@ -48,27 +47,3 @@ fun getActionReply(
.build()
}
}

fun getOpenIncomingCallAction(context: Context, conversationId: String, userId: String) = getAction(
context.getString(R.string.notification_action_open_call),
fullScreenIncomingCallPendingIntent(context, conversationId, userId)
)

fun getDeclineCallAction(context: Context, conversationId: String, userId: String) = getAction(
context.getString(R.string.notification_action_decline_call),
declineCallPendingIntent(context, conversationId, userId)
)

fun getOpenOngoingCallAction(context: Context, conversationId: String) = getAction(
context.getString(R.string.notification_action_open_call),
openOngoingCallPendingIntent(context, conversationId)
)

fun getHangUpCallAction(context: Context, conversationId: String, userId: String) = getAction(
context.getString(R.string.notification_action_hang_up_call),
endOngoingCallPendingIntent(context, conversationId, userId)
)

private fun getAction(title: String, intent: PendingIntent) = NotificationCompat.Action
.Builder(null, title, intent)
.build()
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.wire.kalium.logic.data.user.UserId
// TODO: The names need to be localisable
object NotificationConstants {

private const val INCOMING_CALL_CHANNEL_ID = "com.wire.android.notification_incoming_call_channel"
const val INCOMING_CALL_CHANNEL_ID = "com.wire.android.notification_incoming_call_channel"
private const val OUTGOING_CALL_CHANNEL_ID = "com.wire.android.notification_outgoing_call_channel"
const val INCOMING_CALL_CHANNEL_NAME = "Incoming calls"
const val OUTGOING_CALL_CHANNEL_NAME = "Outgoing call"
Expand Down
Loading

0 comments on commit caf7880

Please sign in to comment.