Skip to content

Commit

Permalink
1.0.14 - New FCM handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Troplo committed Jan 23, 2024
1 parent 14b1b1b commit ad42859
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 106 deletions.
15 changes: 1 addition & 14 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
applicationId = "com.troplo.privateuploader"
minSdk = 28
targetSdk = 34
versionCode = 13
versionName = "1.0.13"
versionCode = 14
versionName = "1.0.14"
multiDexEnabled = true
buildConfigField("String", "SERVER_URL", "\"https://flowinity.com\"")
buildConfigField("String", "BUILD_TIME", "\"${DateFormat.getDateTimeInstance().format(System.currentTimeMillis())}\"")
Expand Down
188 changes: 108 additions & 80 deletions app/src/main/java/com/troplo/privateuploader/FirebaseChatService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import coil.request.ImageRequest
import coil.size.Size
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.troplo.privateuploader.api.SessionManager
import com.troplo.privateuploader.api.TpuApi
import com.troplo.privateuploader.api.TpuFunctions
import com.troplo.privateuploader.api.imageLoader
Expand Down Expand Up @@ -60,7 +61,7 @@ class FirebaseChatService : FirebaseMessagingService() {

override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d(TAG, "[NewChatService] Message received")
if (isAppOnForeground(this)) {
if (isAppOnForeground(this) && remoteMessage.data["type"] == "message") {
Log.d(TAG, "[NewChatService] App is on foreground")
return
}
Expand All @@ -73,7 +74,8 @@ class FirebaseChatService : FirebaseMessagingService() {
chatName = remoteMessage.data["chatName"] ?: "",
associationId = remoteMessage.data["associationId"]?.toInt() ?: 0,
avatar = remoteMessage.data["avatar"] ?: "",
id = remoteMessage.data["id"]?.toInt() ?: 0
id = remoteMessage.data["id"]?.toInt() ?: 0,
type = remoteMessage.data["type"] ?: ""
)
)
}
Expand Down Expand Up @@ -140,95 +142,121 @@ class FirebaseChatService : FirebaseMessagingService() {
// for ActivityCompat#requestPermissions for more details.
return
}
asyncLoadIcon(message.avatar, this) {
try {
Log.d("TPU.Untagged", "[ChatService] Loaded icon")
val chatPartner = Person.Builder().apply {
setName(message.username)
setKey(message.userId.toString())
setIcon(it)
setImportant(false)
}.build()

val notificationManager = NotificationManagerCompat.from(this)
val channel = NotificationChannel(
"communications",
"Messages from Communications",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
if (messages[message.associationId] == null) messages[message.associationId] =
mutableListOf()
messages[message.associationId]?.add(
NotificationCompat.MessagingStyle.Message(
message.content,
TpuFunctions.getDate(message.createdAt)?.time ?: 0,
chatPartner

if(message.type == "message") {
asyncLoadIcon(message.avatar, this) {
try {
Log.d("TPU.Untagged", "[ChatService] Loaded icon")
val chatPartner = Person.Builder().apply {
setName(message.username)
setKey(message.userId.toString())
setIcon(it)
setImportant(false)
}.build()

val notificationManager = NotificationManagerCompat.from(this)
val channel = NotificationChannel(
"communications",
"Messages from Communications",
NotificationManager.IMPORTANCE_HIGH
)
)
notificationManager.createNotificationChannel(channel)
if (messages[message.associationId] == null) messages[message.associationId] =
mutableListOf()

val style = NotificationCompat.MessagingStyle(chatPartner)
.setConversationTitle(message.chatName)

for (msg in messages[message.associationId]!!) {
style.addMessage(msg)
}
Log.d("TPU.Firebase", "[ChatService] Secure message")
val rep = Intent(this, InlineNotificationActivity::class.java)
rep.replaceExtras(Bundle())
rep.putExtra("chatId", message.associationId)
Log.d("TPU.Firebase", "[ChatService] ${rep.extras}")
val style = NotificationCompat.MessagingStyle(chatPartner)
.setConversationTitle(message.chatName)
val replyPendingIntent = PendingIntent.getBroadcast(
this@FirebaseChatService,
message.associationId,
rep,
PendingIntent.FLAG_MUTABLE
)

val remoteInput = RemoteInput.Builder("content")
.setLabel("Reply")
.build()

val replyAction = NotificationCompat.Action.Builder(
R.drawable.flowinity_logo,
"Reply",
replyPendingIntent
)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build()
Log.d("TPU.Firebase", "[ChatService] ${message.associationId}")
val builder: NotificationCompat.Builder =
NotificationCompat.Builder(this, "communications")
.addPerson(chatPartner)
.setContentText(message.content)
.setContentTitle(message.username)
.setSmallIcon(R.drawable.flowinity_logo)
.setWhen(TpuFunctions.getDate(message.createdAt)?.time ?: 0)
.addAction(replyAction)
.setContentIntent(
PendingIntent.getActivity(
this,
message.associationId,
Intent(this, MainActivity::class.java).apply {
putExtra("chatId", message.associationId)
},
PendingIntent.FLAG_MUTABLE
)
)
CoroutineScope(Dispatchers.IO).launch {
TpuApi.init(SessionManager(this@FirebaseChatService).getAuthToken() ?: "", this@FirebaseChatService)
val messageRequest = TpuApi.retrofitService.getMessage(
messageId = message.id
).execute()

val rep = Intent(this, InlineNotificationActivity::class.java)
rep.replaceExtras(Bundle())
rep.putExtra("chatId", message.associationId)
val replyPendingIntent = PendingIntent.getBroadcast(
this,
message.associationId,
rep,
PendingIntent.FLAG_MUTABLE
)

val remoteInput = RemoteInput.Builder("content")
.setLabel("Reply")
.build()

val replyAction = NotificationCompat.Action.Builder(
R.drawable.flowinity_logo,
"Reply",
replyPendingIntent
)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build()

val builder: NotificationCompat.Builder =
NotificationCompat.Builder(this, "communications")
.addPerson(chatPartner)
.setStyle(style)
.setContentText(message.content)
.setContentTitle(message.username)
.setSmallIcon(R.drawable.flowinity_logo)
.setWhen(TpuFunctions.getDate(message.createdAt)?.time ?: 0)
.addAction(replyAction)
.setContentIntent(
PendingIntent.getActivity(
this,
message.associationId,
Intent(this, MainActivity::class.java).apply {
putExtra("chatId", message.associationId)
},
PendingIntent.FLAG_MUTABLE
if (messageRequest.isSuccessful) {
Log.d(
"TPU.Firebase",
"New message came through, ${messageRequest.body()?.content}"
)
)
val res = notificationManager.notify(message.associationId, builder.build())
Log.d("TPU.Untagged", "[ChatService] Notification sent, $res")
} catch (e: Exception) {
Log.d(
"TPU.Untagged",
"[ChatService] Error sending notification, ${e.printStackTrace()}"
)
messages[message.associationId]?.add(
NotificationCompat.MessagingStyle.Message(
messageRequest.body()?.content ?: "",
TpuFunctions.getDate(message.createdAt)?.time ?: 0,
chatPartner
)
)
}

Log.d("TPU.Firebase", "[ChatService] Added message to list")

for (msg in messages[message.associationId]!!) {
style.addMessage(msg)
}

builder.setStyle(style)

val res = notificationManager.notify(message.associationId, builder.build())
Log.d("TPU.Untagged", "[ChatService] Notification sent, $res")
}
} catch (e: Exception) {
Log.d(
"TPU.Untagged",
"[ChatService] Error sending notification, ${e.printStackTrace()}"
)
}
}
} else if(message.type == "read") {
val notificationManager = NotificationManagerCompat.from(this)
notificationManager.cancel(message.associationId)
}
}

companion object {
private const val TAG = "FirebaseChatService"
private const val FAKE_MESSAGE_CONTENT = "Please update your version of the Flowinity app."
}

internal class MyWorker(appContext: Context, workerParams: WorkerParameters) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,24 @@ class InlineNotificationActivity : BroadcastReceiver() {
try {
Log.d(
"TPU.Untagged",
"[ChatService] InlineNotificationActivity onCreate, intent: $intent, extras: ${intent.extras}"
"[Firebase] InlineNotificationActivity onCreate, intent: $intent, extras: ${intent.extras}"
)

val chatId = intent.getIntExtra("chatId", 0)
val remoteInput = RemoteInput.getResultsFromIntent(intent)
val content = remoteInput?.getCharSequence("content")?.toString()
Log.d("InlineNotificationAct", "Firebase - chatId: $chatId, content: $content")
TpuApi.init(SessionManager(context).getAuthToken() ?: "", context)
sendReply(chatId, content, context)
} catch (e: Exception) {
Log.d("TPU.InlineNotificationActivity", "Exception: $e")
Log.d("TPU.InlineNotificationAct", "Firebase - Exception: $e")
}
}

private fun sendReply(chatId: Int, content: String?, context: Context) {
try {
if (chatId == 0) return
Log.d("TPU.Untagged", "Sending reply to chatId: $chatId")
Log.d("TPU.Untagged", "Firebase - Sending reply to chatId: $chatId")
CoroutineScope(Dispatchers.IO).launch {
val response = TpuApi.retrofitService.sendMessage(
id = chatId, messageRequest = MessageRequest(
Expand All @@ -43,7 +44,7 @@ class InlineNotificationActivity : BroadcastReceiver() {
).execute()
}
} catch (e: Exception) {
Log.d("TPU.InlineNotificationActivity", "sendReply exception: $e")
Log.d("TPU.InlineNotificationAct", "Firebase - sendReply exception: $e")
}
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/troplo/privateuploader/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.troplo.privateuploader.api.SocketHandler
import com.troplo.privateuploader.api.SocketHandlerService
import com.troplo.privateuploader.api.TpuApi
import com.troplo.privateuploader.api.TpuFunctions
import com.troplo.privateuploader.api.stores.AppStore
import com.troplo.privateuploader.api.stores.CollectionStore
import com.troplo.privateuploader.api.stores.CoreStore
import com.troplo.privateuploader.api.stores.UploadStore
Expand All @@ -42,17 +43,25 @@ import okhttp3.RequestBody.Companion.asRequestBody


class MainActivity : ComponentActivity() {

override fun onResume() {
super.onResume()
AppStore.foreground = true
GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(this)
val socket = SocketHandler.getSocket()
if (socket != null && !socket.connected()) {
socket.connect()
}
}

override fun onPause() {
super.onPause()
AppStore.foreground = false
}

override fun onStart() {
super.onStart()
AppStore.foreground = true
val socket = SocketHandler.getSocket()
if (socket != null && !socket.connected()) {
socket.connect()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ object TpuApi {
@Path("associationId") associationId: Int,
@Body pinRequest: PinRequest
): Call<Unit>

@GET("chats/messages/{messageId}")
fun getMessage(
@Path("messageId") messageId: Int
): Call<Message>
}

val retrofitService: TpuApiService by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import androidx.navigation.NavController

object AppStore {
var navController: NavController? = null
var foreground = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import com.troplo.privateuploader.api.stores.AppStore
import com.troplo.privateuploader.data.model.AddChatUsersEvent
import com.troplo.privateuploader.data.model.Chat
import com.troplo.privateuploader.data.model.PinRequest
Expand Down Expand Up @@ -100,11 +101,16 @@ object ChatStore {
associationId.value = id

// Handle unread count, and init read receipt
// Ensure that the app is in the foreground

val socket = SocketHandler.getSocket()
socket?.emit("readChat", id)
val chat = chats.find { it.association?.id == id }
if (chat != null) {
chat.unread = 0
Log.d("MarkAsRead", "Foreground: ${AppStore.foreground}")
if(AppStore.foreground) {
socket?.emit("readChat", id)
val chat = chats.find { it.association?.id == id }
if (chat != null) {
chat.unread = 0
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ fun getCurrentRouteTitle(route: String): String {
NavRoute.SettingsPreferences.path -> "Preferences"
NavRoute.Friends.path -> "Friends"
NavRoute.SettingsCollections.path -> "Collections"
else -> "PrivateUploader"
NavRoute.Notifications.path -> "Notifications"
else -> "Flowinity"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ data class MessageEventFirebase(
@field:Json(name = "avatar") val avatar: String,
@field:Json(name = "chatName") val chatName: String,
@field:Json(name = "createdAt") val createdAt: String,
@field:Json(name = "type") val type: String,
)

@JsonClass(generateAdapter = true)
Expand Down
Loading

0 comments on commit ad42859

Please sign in to comment.