Files
fast-messenger/app/src/main/kotlin/dev/meloda/fast/presentation/MainActivity.kt
T

190 lines
6.5 KiB
Kotlin

package dev.meloda.fast.presentation
import android.Manifest
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.core.content.ContextCompat
import androidx.lifecycle.compose.LifecycleResumeEffect
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import dev.meloda.fast.MainViewModel
import dev.meloda.fast.MainViewModelImpl
import dev.meloda.fast.common.AppConstants
import dev.meloda.fast.datastore.AppSettings
import dev.meloda.fast.logger.FastLogger
import dev.meloda.fast.service.OnlineService
import dev.meloda.fast.service.longpolling.LongPollingService
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.common.LocalLogger
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
class MainActivity : AppCompatActivity() {
@SuppressLint("HardwareIds", "InlinedApi")
@OptIn(ExperimentalPermissionsApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppSettings.deviceId = Settings.Secure.getString(
contentResolver,
Settings.Secure.ANDROID_ID
)
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
val systemBarStyle = when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> SystemBarStyle.light(
Color.Transparent.toArgb(),
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Color.Gray.copy(alpha = 0.85f).toArgb()
} else {
Color.Transparent.toArgb()
}
)
Configuration.UI_MODE_NIGHT_YES -> SystemBarStyle.dark(Color.Transparent.toArgb())
else -> error("Illegal State, current mode is $currentNightMode")
}
enableEdgeToEdge(
statusBarStyle = systemBarStyle,
navigationBarStyle = systemBarStyle,
)
createNotificationChannels()
requestNotificationPermissions()
setContent {
val logger: FastLogger = koinInject()
val viewModel: MainViewModel = koinViewModel<MainViewModelImpl>()
LifecycleResumeEffect(true) {
viewModel.onAppResumed(intent)
onPauseOrDispose {}
}
CompositionLocalProvider(LocalLogger provides logger) {
RootScreen(
toggleLongPollService = { enable, inBackground ->
toggleLongPollService(
enable = enable,
inBackground = inBackground
?: AppSettings.Experimental.longPollInBackground
)
},
toggleOnlineService = ::toggleOnlineService
)
}
}
}
private fun createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val noCategoryName = getString(R.string.notification_channel_no_category_name)
val noCategoryDescriptionText =
getString(R.string.notification_channel_no_category_description)
val noCategoryChannel =
NotificationChannel(
AppConstants.NOTIFICATION_CHANNEL_UNCATEGORIZED,
noCategoryName,
NotificationManager.IMPORTANCE_HIGH
).apply {
description = noCategoryDescriptionText
}
val longPollName = getString(R.string.notification_channel_long_polling_service_name)
val longPollDescriptionText =
getString(R.string.notification_channel_long_polling_service_description)
val longPollChannel =
NotificationChannel(
AppConstants.NOTIFICATION_CHANNEL_LONG_POLLING,
longPollName,
NotificationManager.IMPORTANCE_NONE
).apply {
description = longPollDescriptionText
}
val notificationManager: NotificationManager =
getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannels(
listOf(
noCategoryChannel,
longPollChannel
)
)
}
}
private fun requestNotificationPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions(
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
REQUEST_NOTIFICATION_PERMISSION_CODE
)
}
}
private val longPollingServiceIntent by lazy {
Intent(this, LongPollingService::class.java)
}
private val onlineServiceIntent by lazy {
Intent(this, OnlineService::class.java)
}
private fun toggleLongPollService(
enable: Boolean,
inBackground: Boolean = AppSettings.Experimental.longPollInBackground
) {
if (enable) {
val longPollIntent = longPollingServiceIntent
if (inBackground) {
ContextCompat.startForegroundService(this, longPollIntent)
} else {
startService(longPollIntent)
}
} else {
stopService(longPollingServiceIntent)
}
}
private fun toggleOnlineService(enable: Boolean) {
if (enable) {
startService(onlineServiceIntent)
} else {
stopService(onlineServiceIntent)
}
}
private fun stopServices() {
toggleOnlineService(enable = false)
val asForeground = AppSettings.Experimental.longPollInBackground
if (!asForeground) {
toggleLongPollService(enable = false)
}
}
override fun onDestroy() {
super.onDestroy()
stopServices()
}
companion object {
private const val REQUEST_NOTIFICATION_PERMISSION_CODE = 1
}
}