From bfcef725c3619b3027a3dde821102813bb2580e5 Mon Sep 17 00:00:00 2001 From: humblerookie <1428864+humblerookie@users.noreply.github.com> Date: Sat, 9 Mar 2024 22:27:52 +0530 Subject: [PATCH] chore(*): apply pr recommendations --- .github/workflows/pr_check.yml | 12 +- .../binanceninja/data/NotificationService.kt | 114 ++++++++--------- .../binanceninja/domain/PlatformScheduler.kt | 68 +++++----- .../core/ui/presentation/BasePresenter.kt | 120 +++++++++--------- 4 files changed, 161 insertions(+), 153 deletions(-) diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml index 7de6da3..8fd8673 100644 --- a/.github/workflows/pr_check.yml +++ b/.github/workflows/pr_check.yml @@ -3,13 +3,23 @@ on: pull_request: branches: [ main ] +env: + VERSION: ${{ vars.VERSION }} + DESKTOP_VERSION: ${{ vars.DESKTOP_VERSION }} + VERSION_CODE: ${{ vars.VERSION_CODE }} + IS_DEBUG: ${{ vars.IS_DEBUG }} + SENTRY_ORG: ${{ vars.SENTRY_ORG }} + SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} + SENTRY_ENVIRONMENT: ${{ vars.SENTRY_ENVIRONMENT }} + concurrency: group: pr-check-${{ github.ref }} cancel-in-progress: true jobs: - build: + run-checks: runs-on: macos-latest + environment: development steps: - name: Checkout Branch diff --git a/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/data/NotificationService.kt b/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/data/NotificationService.kt index be49354..52e2649 100644 --- a/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/data/NotificationService.kt +++ b/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/data/NotificationService.kt @@ -23,74 +23,72 @@ import me.tatarka.inject.annotations.Inject @Inject actual class NotificationService( - private val context: Context, - private val userDataStore: UserDataStore, - private val permissionHandler: PermissionHandler + private val context: Context, + private val userDataStore: UserDataStore, + private val permissionHandler: PermissionHandler ) { - private val channelId = "MATCH_ORDERS" + private val channelId = "MATCH_ORDERS" - @SuppressLint("MissingPermission") - actual fun notify(items: List) { - with(NotificationManagerCompat.from(context)) { - permissionHandler.hasPermission(PermissionType.NOTIFICATION) { hasPermission -> - if (hasPermission) { - createNotificationChannel() - createNotification(items).forEach { - val id = userDataStore.notificationId + 1 - userDataStore.notificationId = id - notify(id, it) - } - } - } + @SuppressLint("MissingPermission") + actual fun notify(items: List) { + with(NotificationManagerCompat.from(context)) { + permissionHandler.hasPermission(PermissionType.NOTIFICATION) { hasPermission -> + if (hasPermission) { + createNotificationChannel() + createNotification(items).forEach { + val id = userDataStore.notificationId + 1 + userDataStore.notificationId = id + notify(id, it) + } } + } } + } - private fun createNotification(items: List): List { - val intent = - Intent(Intent.ACTION_VIEW).apply { - data = Uri.parse(Constants.APP_SCHEME) - flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - } + private fun createNotification(items: List): List { + val intent = + Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse(Constants.APP_SCHEME) + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } - val pendingIntent: PendingIntent = - PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) + val pendingIntent: PendingIntent = + PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) - val uuid = UUID.randomUUID().toString() - return buildList { - items.forEach { - add( - NotificationCompat.Builder(context, channelId) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle(it.title) - .setContentText(it.message) - .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setContentIntent(pendingIntent) - .setAutoCancel(true) - .setGroup(uuid) - .build() - ) - } - } + val uuid = UUID.randomUUID().toString() + return buildList { + items.forEach { + add( + NotificationCompat.Builder(context, channelId) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(it.title) + .setContentText(it.message) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .setGroup(uuid) + .build() + ) + } } + } - private fun createNotificationChannel() { - val notificationManager: NotificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + private fun createNotificationChannel() { + val notificationManager: NotificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - if ( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - notificationManager.getNotificationChannel(channelId) == null - ) { - val name = getLocaleStrings().matchNotificationTitle - val descriptionText = getLocaleStrings().matchNotificationDescription - val importance = NotificationManager.IMPORTANCE_DEFAULT - val channel = - NotificationChannel(channelId, name, importance).apply { - description = descriptionText - } - // Register the channel with the system. - notificationManager.createNotificationChannel(channel) - } + if ( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + notificationManager.getNotificationChannel(channelId) == null + ) { + val name = getLocaleStrings().matchNotificationTitle + val descriptionText = getLocaleStrings().matchNotificationDescription + val importance = NotificationManager.IMPORTANCE_DEFAULT + val channel = + NotificationChannel(channelId, name, importance).apply { description = descriptionText } + // Register the channel with the system. + notificationManager.createNotificationChannel(channel) } + } } diff --git a/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/domain/PlatformScheduler.kt b/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/domain/PlatformScheduler.kt index 714180b..039f070 100644 --- a/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/domain/PlatformScheduler.kt +++ b/composeApp/src/androidMain/kotlin/dev/anvith/binanceninja/domain/PlatformScheduler.kt @@ -17,42 +17,42 @@ import me.tatarka.inject.annotations.Inject @Inject @AppScope actual class PlatformScheduler(private val context: Context) { - private lateinit var filterOrdersRequest: PeriodicWorkRequest - private lateinit var resetOrdersRequest: PeriodicWorkRequest - private val constraints = - Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() - private val refreshOrdersKey = "RefreshOrdersTask" - private val resetOrdersKey = "ResetOrdersTask" + private lateinit var filterOrdersRequest: PeriodicWorkRequest + private lateinit var resetOrdersRequest: PeriodicWorkRequest + private val constraints = + Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() + private val refreshOrdersKey = "RefreshOrdersTask" + private val resetOrdersKey = "ResetOrdersTask" - actual fun schedule(executor: RequestExecutor) { - // Ignore Parameter on android since we rely on inject - with(WorkManager.getInstance(context)) { - filterOrdersRequest = - PeriodicWorkRequest.Builder( - RefreshOrdersTask::class.java, - INTERVAL_MINUTES, - TimeUnit.MINUTES, - ) - .setConstraints(constraints) - .build() - enqueueUniquePeriodicWork(refreshOrdersKey, CANCEL_AND_REENQUEUE, filterOrdersRequest) - resetOrdersRequest = - PeriodicWorkRequest.Builder( - ResetOrdersTask::class.java, - INTERVAL_DAYS, - TimeUnit.DAYS, - ) - .build() - enqueueUniquePeriodicWork(resetOrdersKey, CANCEL_AND_REENQUEUE, resetOrdersRequest) - } + actual fun schedule(executor: RequestExecutor) { + // Ignore Parameter on android since we rely on inject + with(WorkManager.getInstance(context)) { + filterOrdersRequest = + PeriodicWorkRequest.Builder( + RefreshOrdersTask::class.java, + INTERVAL_MINUTES, + TimeUnit.MINUTES, + ) + .setConstraints(constraints) + .build() + enqueueUniquePeriodicWork(refreshOrdersKey, CANCEL_AND_REENQUEUE, filterOrdersRequest) + resetOrdersRequest = + PeriodicWorkRequest.Builder( + ResetOrdersTask::class.java, + INTERVAL_DAYS, + TimeUnit.DAYS, + ) + .build() + enqueueUniquePeriodicWork(resetOrdersKey, CANCEL_AND_REENQUEUE, resetOrdersRequest) } + } - actual fun cancel() { - if (::filterOrdersRequest.isInitialized) { - with(WorkManager.getInstance(context)) { - cancelWorkById(filterOrdersRequest.id) - cancelWorkById(resetOrdersRequest.id) - } - } + actual fun cancel() { + if (::filterOrdersRequest.isInitialized) { + with(WorkManager.getInstance(context)) { + cancelWorkById(filterOrdersRequest.id) + cancelWorkById(resetOrdersRequest.id) + } } + } } diff --git a/composeApp/src/commonMain/kotlin/dev/anvith/binanceninja/core/ui/presentation/BasePresenter.kt b/composeApp/src/commonMain/kotlin/dev/anvith/binanceninja/core/ui/presentation/BasePresenter.kt index 8fc122c..727949c 100644 --- a/composeApp/src/commonMain/kotlin/dev/anvith/binanceninja/core/ui/presentation/BasePresenter.kt +++ b/composeApp/src/commonMain/kotlin/dev/anvith/binanceninja/core/ui/presentation/BasePresenter.kt @@ -23,76 +23,76 @@ import kotlinx.coroutines.sync.Mutex abstract class BasePresenter(dispatcherProvider: DispatcherProvider) { - fun dispatchEvent(event: E) = onEvent(event) + fun dispatchEvent(event: E) = onEvent(event) - protected abstract fun onEvent(event: E) + protected abstract fun onEvent(event: E) - abstract fun initState(): S + abstract fun initState(): S - private val _state = MutableStateFlow(this.initState()) + private val _state = MutableStateFlow(this.initState()) - private val mutex = Mutex() + private val mutex = Mutex() - protected fun updateState(map: (S) -> S) = _state.update(map) + protected fun updateState(map: (S) -> S) = _state.update(map) - private val presenterScope: CoroutineScope = - CoroutineScope( - SupervisorJob() + - dispatcherProvider.main() + - CoroutineExceptionHandler { _, exception -> - logE("Coroutine threw $exception: \n${exception.stackTraceToString()}") - } - ) - - val state: StateFlow = - _state.stateIn( - presenterScope, - SharingStarted.WhileSubscribed(5000), - this.initState(), - ) - - protected fun launch( - context: CoroutineContext = EmptyCoroutineContext, - start: CoroutineStart = CoroutineStart.DEFAULT, - block: suspend CoroutineScope.() -> Unit - ): Job = presenterScope.launch(context, start, block) - - val currentState: S - get() = _state.value - - val viewEvents - get() = _events.receiveAsFlow() - - private val _events = - Channel( - capacity = Int.MAX_VALUE, - onBufferOverflow = BufferOverflow.SUSPEND, - onUndeliveredElement = { logE("Missed view event $it") }, - ) - - protected fun sideEffect(event: SideEffect) { - launch { _events.send(event) } - } - - companion object { - val presenters = mutableMapOf>() - - inline fun getPresenter(key: String, factory: () -> T): T { - return (presenters[key] ?: factory()) as T - } - - fun removeBinding(key: String) { - presenters.remove(key)?.onCleared() + private val presenterScope: CoroutineScope = + CoroutineScope( + SupervisorJob() + + dispatcherProvider.main() + + CoroutineExceptionHandler { _, exception -> + logE("Coroutine threw $exception: \n${exception.stackTraceToString()}") } + ) + + val state: StateFlow = + _state.stateIn( + presenterScope, + SharingStarted.WhileSubscribed(5000), + this.initState(), + ) + + protected fun launch( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit + ): Job = presenterScope.launch(context, start, block) + + val currentState: S + get() = _state.value + + val viewEvents + get() = _events.receiveAsFlow() + + private val _events = + Channel( + capacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.SUSPEND, + onUndeliveredElement = { logE("Missed view event $it") }, + ) + + protected fun sideEffect(event: SideEffect) { + launch { _events.send(event) } + } + + companion object { + val presenters = mutableMapOf>() + + inline fun getPresenter(key: String, factory: () -> T): T { + return (presenters[key] ?: factory()) as T } - fun bind(screen: PresenterScreen) { - if (!presenters.containsKey(screen.key)) { - presenters[screen.key] = this - } + fun removeBinding(key: String) { + presenters.remove(key)?.onCleared() } + } - fun onCleared() { - presenterScope.cancel() + fun bind(screen: PresenterScreen) { + if (!presenters.containsKey(screen.key)) { + presenters[screen.key] = this } + } + + fun onCleared() { + presenterScope.cancel() + } }