From cc74acdc62c6738b2cb2751a043ae009bd4fbf1a Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:22:42 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chroe:=20gitignore=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 애드몹 ID를 안전히 하기 위한 파일 --- app/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/.gitignore b/app/.gitignore index 42afabf..342694e 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,2 @@ -/build \ No newline at end of file +/build +*-secret.xml \ No newline at end of file From 971b837ab6f643912ce2a577d18e4a2cef4fdc5f Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:23:42 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EA=B5=AC=EA=B8=80=20=EC=95=A0?= =?UTF-8?q?=EB=93=9C=EB=AA=B9=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 필요한 의존성을 추가 manifest에 설정 추가 --- app/build.gradle.kts | 3 +++ app/src/main/AndroidManifest.xml | 4 ++++ .../presentation/ui/activity/MainActivity.kt | 14 +++++++++++++- gradle/libs.versions.toml | 2 ++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bcc8a7a..e6f14f2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -160,4 +160,7 @@ dependencies { kspTest(libs.hilt.android.compiler) androidTestImplementation(libs.hilt.android.testing) kspAndroidTest(libs.hilt.android.compiler) + + // 구글 광고 + implementation(libs.play.services.ads) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5428f7d..3145652 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,10 @@ android:theme="@style/Theme.NotiManager" android:enableOnBackInvokedCallback="true" tools:targetApi="35"> + + Date: Mon, 10 Mar 2025 16:25:33 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EA=B4=91=EA=B3=A0=20=EB=A1=9C?= =?UTF-8?q?=EB=8D=94=20=EB=B0=8F=20=EB=B7=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit native ads 및 배너 광고를 위한 뷰 추가 native의 경우 UI 개선 필요 --- .../presentation/ui/ads/AdLoader.kt | 22 +++++++++++ .../notimanager/presentation/ui/ads/AdSize.kt | 24 ++++++++++++ .../presentation/ui/ads/NativeAdView.kt | 39 +++++++++++++++++++ .../presentation/ui/ads/NotiNativeAds.kt | 24 ++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 app/src/main/java/com/example/notimanager/presentation/ui/ads/AdLoader.kt create mode 100644 app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt create mode 100644 app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt create mode 100644 app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdLoader.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdLoader.kt new file mode 100644 index 0000000..f9a5278 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdLoader.kt @@ -0,0 +1,22 @@ +package com.example.notimanager.presentation.ui.ads + +import android.content.Context +import com.google.android.gms.ads.AdListener +import com.google.android.gms.ads.AdLoader +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.ads.nativead.NativeAd +import com.google.android.gms.ads.nativead.NativeAdOptions + +fun createNativeAdLoader(context: Context, onAdLoaded: (NativeAd) -> Unit, onAdFailedToLoad: (LoadAdError) -> Unit): AdLoader { + return AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110") + .forNativeAd { ad: NativeAd -> + onAdLoaded(ad) // 광고가 로드되었을 때 호출 + } + .withAdListener(object : AdListener() { + override fun onAdFailedToLoad(adError: LoadAdError) { + onAdFailedToLoad(adError) // 광고 로드 실패 시 호출 + } + }) + .withNativeAdOptions(NativeAdOptions.Builder().build()) + .build() +} diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt new file mode 100644 index 0000000..75009b3 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt @@ -0,0 +1,24 @@ +package com.example.notimanager.presentation.ui.ads + +import android.app.Activity +import android.content.Context +import android.os.Build +import android.view.WindowMetrics +import com.google.android.gms.ads.AdSize + +object AdsUtil{ + // Get the ad size with screen width. + fun getAdSize(context: Context): AdSize { + val displayMetrics = context.resources.displayMetrics + val adWidthPixels = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val windowMetrics: WindowMetrics = (context as? Activity)?.windowManager!!.currentWindowMetrics + windowMetrics.bounds.width() + } else { + displayMetrics.widthPixels + } + val density = displayMetrics.density + val adWidth = (adWidthPixels / density).toInt() + return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt new file mode 100644 index 0000000..33b7290 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NativeAdView.kt @@ -0,0 +1,39 @@ +package com.example.notimanager.presentation.ui.ads + +import android.view.View +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.viewinterop.AndroidView +import com.google.android.gms.ads.nativead.NativeAd +import com.google.android.gms.ads.nativead.NativeAdView + +@Composable +fun NotiNativeAdView( + ad: NativeAd, + adContent: @Composable (ad: NativeAd, contentView: View) -> Unit, +) { + val contentViewId by remember { mutableIntStateOf(View.generateViewId()) } + val adViewId by remember { mutableIntStateOf(View.generateViewId()) } + AndroidView( + factory = { context -> + val contentView = ComposeView(context).apply { + id = contentViewId + } + NativeAdView(context).apply { + id = adViewId + addView(contentView) + } + }, + update = { view -> + val adView = view.findViewById(adViewId) + val contentView = view.findViewById(contentViewId) + + adView.setNativeAd(ad) + adView.callToActionView = contentView + contentView.setContent { adContent(ad, contentView) } + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt new file mode 100644 index 0000000..2cb192f --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt @@ -0,0 +1,24 @@ +package com.example.notimanager.presentation.ui.ads + +import android.util.Log +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import com.google.android.gms.ads.nativead.NativeAd + +@Composable +fun NotiNativeAds(nativeAd: NativeAd) { + NotiNativeAdView(ad = nativeAd) { ad, view -> + //Style it whatever you want + Log.i("ad 정보", ad.toString()) + Log.i("ad 정보", ad.headline.toString()) + Column { + ad.headline?.let { Text(text = it) } + TextButton( + content = { ad.callToAction?.let { Text(text = it) } }, + onClick = { view.performClick() }, + ) + } + } +} \ No newline at end of file From 2a85019237d6124162e894a0f10f2dda0225f036 Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Tue, 11 Mar 2025 18:07:23 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EB=84=A4=EC=9D=B4=ED=8B=B0?= =?UTF-8?q?=EB=B8=8C=20ads=20=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 당장 활용할 생각은 없지만, 추후 재사용을 위한 커밋 --- .../presentation/ui/ads/NotiNativeAds.kt | 51 +++++++++++++++++-- app/src/main/res/drawable/ad_badge.xml | 15 ++++++ 2 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/ad_badge.xml diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt index 2cb192f..1a409cc 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/NotiNativeAds.kt @@ -1,20 +1,61 @@ package com.example.notimanager.presentation.ui.ads import android.util.Log +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Badge +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.example.notimanager.R +import com.example.notimanager.common.objects.DateFormatter.toBitmap +import com.example.notimanager.presentation.ui.component.common.AppIconView import com.google.android.gms.ads.nativead.NativeAd @Composable fun NotiNativeAds(nativeAd: NativeAd) { NotiNativeAdView(ad = nativeAd) { ad, view -> - //Style it whatever you want - Log.i("ad 정보", ad.toString()) - Log.i("ad 정보", ad.headline.toString()) - Column { - ad.headline?.let { Text(text = it) } + Row( + modifier = Modifier.padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ){ + AppIconView(ad.icon?.drawable?.toBitmap()) + Column { + // 광고 뱃지와 함께 광고 제목 + Row(){ + Image( + painter = painterResource(id = R.drawable.ad_badge), + contentDescription = "ad badge", + modifier = Modifier.size(16.dp) + ) + ad.headline?.let { + Text( + text = it, + style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold), + ) + } + } + ad.body?.let { + Text( + text = it, + style = MaterialTheme.typography.bodySmall, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } TextButton( content = { ad.callToAction?.let { Text(text = it) } }, onClick = { view.performClick() }, diff --git a/app/src/main/res/drawable/ad_badge.xml b/app/src/main/res/drawable/ad_badge.xml new file mode 100644 index 0000000..9cd3608 --- /dev/null +++ b/app/src/main/res/drawable/ad_badge.xml @@ -0,0 +1,15 @@ + + + + + From 4e43a7e5f76dda5f4f409079849a930fa6d45c94 Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Tue, 11 Mar 2025 18:08:46 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=EC=BB=A8=ED=85=90=EC=B8=A0?= =?UTF-8?q?=EA=B0=80=20=EC=9E=88=EB=8A=94=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=20=EA=B4=91=EA=B3=A0=20=EB=B0=B0=EB=84=88=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 광고 규정 준수를 위해 컨텐츠가 있는 페이지에만 광고 추가. 그리고 시간 형식 페이지에서 광고 삭제. --- .../notimanager/presentation/ui/ads/AdSize.kt | 16 +++- .../ui/component/DateFormatterView.kt | 1 - .../component/list/NotificationAppListView.kt | 88 ++++++++++------- .../ui/component/list/NotificationListView.kt | 40 ++++++-- .../list/NotificationTitleListView.kt | 94 ++++++++++++------- 5 files changed, 160 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt index 75009b3..8c9b6ab 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/ads/AdSize.kt @@ -4,11 +4,14 @@ import android.app.Activity import android.content.Context import android.os.Build import android.view.WindowMetrics +import com.example.notimanager.R +import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.AdView object AdsUtil{ // Get the ad size with screen width. - fun getAdSize(context: Context): AdSize { + private fun getAdSize(context: Context): AdSize { val displayMetrics = context.resources.displayMetrics val adWidthPixels = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { @@ -21,4 +24,15 @@ object AdsUtil{ val adWidth = (adWidthPixels / density).toInt() return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth) } + + fun getAdView(context: Context): AdView{ + val unitId = context.getString(R.string.admob_banner_id) + val adView = AdView(context) + adView.adUnitId = unitId + adView.setAdSize(getAdSize(context)) + + val adRequest = AdRequest.Builder().build() + adView.loadAd(adRequest) + return adView + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt index 031551d..223e103 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/DateFormatterView.kt @@ -113,6 +113,5 @@ fun DateFormatterView( Text(apply) } } - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt index fa049f6..472c5a2 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt @@ -1,6 +1,11 @@ package com.example.notimanager.presentation.ui.component.list +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.HorizontalDivider @@ -10,13 +15,19 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView import androidx.navigation.NavController import com.example.notimanager.presentation.stateholder.state.NotificationAppPriorityState import com.example.notimanager.presentation.stateholder.state.NotificationAppState import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel +import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView import com.example.notimanager.presentation.ui.component.item.NotificationAppItemView @Composable @@ -30,6 +41,10 @@ fun NotificationAppListView( var currentNotiPriority by remember { mutableStateOf(priorityState.notificationAppList) } var currentNoti by remember { mutableStateOf(notificationAppState.notificationAppList) } + // 광고 + val context = LocalContext.current + val adView = getAdView(context) + LaunchedEffect(priorityState.notificationAppList) { if (!priorityState.isLoading) { currentNotiPriority = priorityState.notificationAppList @@ -42,41 +57,48 @@ fun NotificationAppListView( } } - LazyColumn( - Modifier.fillMaxSize() - ) { - items(currentNotiPriority) { notification -> - NotificationAppItemView( - notification = notification, - onClick = { - navController - .navigate( - "titleScreen/${notification.appName}" - ) - }, - viewModel = viewModel, - priorityViewModel = priorityViewModel - ) - } - if (currentNotiPriority.isNotEmpty()){ - item { - HorizontalDivider() + Box(modifier = Modifier.fillMaxSize()) { + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(bottom = 56.dp) // AndroidView의 높이만큼 패딩 추가 + ) { + items(currentNotiPriority) { notification -> + NotificationAppItemView( + notification = notification, + onClick = { + navController.navigate("titleScreen/${notification.appName}") + }, + viewModel = viewModel, + priorityViewModel = priorityViewModel + ) + } + if (currentNotiPriority.isNotEmpty()) { + item { + HorizontalDivider() + } } - } - - items(currentNoti) { notification -> - NotificationAppItemView( - notification = notification, - onClick = { - navController - .navigate( - "titleScreen/${notification.appName}" - ) - }, - viewModel = viewModel, - priorityViewModel = priorityViewModel - ) + items(currentNoti) { notification -> + NotificationAppItemView( + notification = notification, + onClick = { + navController.navigate("titleScreen/${notification.appName}") + }, + viewModel = viewModel, + priorityViewModel = priorityViewModel + ) + } } + + AndroidView( + factory = { adView }, + update = {}, + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .height(56.dp) + ) } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt index 39b5a31..b130aef 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt @@ -1,6 +1,10 @@ package com.example.notimanager.presentation.ui.component.list +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable @@ -9,9 +13,13 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView import com.example.notimanager.presentation.stateholder.state.NotificationState +import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView import com.example.notimanager.presentation.ui.component.item.NotificationItemView @@ -24,6 +32,8 @@ fun NotificationListView( val context = LocalContext.current var currentNoti by remember { mutableStateOf(notificationState.notificationList) } + val adView = getAdView(context) + LaunchedEffect(notificationState.notificationList) { if (!notificationState.isLoading) { currentNoti = notificationState.notificationList @@ -33,15 +43,27 @@ fun NotificationListView( } } - LazyColumn( - modifier = Modifier.fillMaxSize() - ) { - items(currentNoti) { notification -> - NotificationItemView (notification = notification, onClick = { - if (notification.intent?.action != null) - context.startActivity(notification.intent) }, - onDelete = onDelete - ) + Box(modifier = Modifier.fillMaxSize()) { + LazyColumn( + modifier = Modifier.fillMaxSize().padding(bottom = 56.dp) + ) { + items(currentNoti) { notification -> + NotificationItemView (notification = notification, onClick = { + if (notification.intent?.action != null) + context.startActivity(notification.intent) }, + onDelete = onDelete + ) + } + } + + AndroidView( + factory = { adView }, + update = {}, + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .height(56.dp) + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt index 54a3e29..eaf7074 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt @@ -1,6 +1,10 @@ package com.example.notimanager.presentation.ui.component.list +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.HorizontalDivider @@ -11,13 +15,18 @@ import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView import androidx.navigation.NavController import com.example.notimanager.common.objects.Encoder.getEncodedString import com.example.notimanager.presentation.stateholder.state.NotificationTitlePriorityState import com.example.notimanager.presentation.stateholder.state.NotificationTitleState import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel +import com.example.notimanager.presentation.ui.ads.AdsUtil.getAdView import com.example.notimanager.presentation.ui.component.item.NotificationTitleItemView @Composable @@ -35,6 +44,9 @@ fun NotificationTitleListView( var currentNotiPriority by remember { mutableStateOf(priorityState.notificationTitleList) } var currentNoti by remember { mutableStateOf(notificationTitleState.notificationTitleList) } + val context = LocalContext.current + val adView = getAdView(context) + LaunchedEffect(priorityState.notificationTitleList) { if (!priorityState.isLoading) { currentNotiPriority = priorityState.notificationTitleList @@ -47,44 +59,56 @@ fun NotificationTitleListView( } } - LazyColumn( - modifier = Modifier.fillMaxSize() - ) { - items(currentNotiPriority) { notification -> - NotificationTitleItemView(notification = notification, onClick = { - if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False") - else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True") - }, viewModel = viewModel, priorityViewModel = priorityViewModel) - } - - if (currentNotiPriority.isNotEmpty()){ - item { - HorizontalDivider() + Box(){ + LazyColumn( + modifier = Modifier.fillMaxSize().padding(bottom = 56.dp) + ) { + items(currentNotiPriority) { notification -> + NotificationTitleItemView(notification = notification, onClick = { + if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False") + else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True") + }, viewModel = viewModel, priorityViewModel = priorityViewModel) } - } - items(currentNoti) { notification -> - NotificationTitleItemView(notification = notification, onClick = { - if (notification.subText == "") { - viewModel.updateAsRead(notification.title) - navController.navigate( - "notificationScreen/${viewModel.getAppName()}/${ - getEncodedString( - notification.title - ) - }/False" - ) + if (currentNotiPriority.isNotEmpty()){ + item { + HorizontalDivider() } - else { - viewModel.updateAsSubText(notification.subText) - navController.navigate( - "notificationScreen/${viewModel.getAppName()}/${ - getEncodedString( - notification.subText - ) - }/True" - ) - }}, viewModel = viewModel, priorityViewModel = priorityViewModel) + } + + items(currentNoti) { notification -> + NotificationTitleItemView(notification = notification, onClick = { + if (notification.subText == "") { + viewModel.updateAsRead(notification.title) + navController.navigate( + "notificationScreen/${viewModel.getAppName()}/${ + getEncodedString( + notification.title + ) + }/False" + ) + } + else { + viewModel.updateAsSubText(notification.subText) + navController.navigate( + "notificationScreen/${viewModel.getAppName()}/${ + getEncodedString( + notification.subText + ) + }/True" + ) + }}, viewModel = viewModel, priorityViewModel = priorityViewModel) + } } + + AndroidView( + factory = { adView }, + update = {}, + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .height(56.dp) + ) } + } \ No newline at end of file From 87b7a7ee5dfb56afe421e6f3b2b05308017e5972 Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Tue, 11 Mar 2025 18:08:56 +0900 Subject: [PATCH 6/8] =?UTF-8?q?build:=20gradle=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EA=B7=B8=EB=A0=88=EC=9D=B4=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6ce2bff..1f52c41 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.8.2" +agp = "8.9.0" byteBuddy = "1.17.1" byteBuddyAgent = "1.17.1" coilCompose = "3.1.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d922a38..fffb202 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Feb 18 09:46:15 KST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From b9db05b7378a14ee7bbbfe5c914f0dd1853028f3 Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Tue, 11 Mar 2025 22:10:46 +0900 Subject: [PATCH 7/8] =?UTF-8?q?ci:=20manifest=EC=9D=98=20secret=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/testBranch.yml | 2 ++ app/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testBranch.yml b/.github/workflows/testBranch.yml index 86eb842..07be595 100644 --- a/.github/workflows/testBranch.yml +++ b/.github/workflows/testBranch.yml @@ -31,6 +31,8 @@ jobs: uses: android-actions/setup-android@v3 - name: Generate kover coverage report + env: + ADMOB_APP_ID: ${{ secrets.ADMOB_APP_ID }} run: | chmod +x ./gradlew ./gradlew koverXmlReport diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e6f14f2..cbe21a0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,8 +18,8 @@ android { targetSdk = 35 versionCode = 1 versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + resValue("string", "admob_app_id", System.getenv("ADMOB_APP_ID") ?: "") } buildTypes { From 90d16e49c037091b9ee6d989bf40c48c45fb995e Mon Sep 17 00:00:00 2001 From: Richter3766 <97567615+Richter3766@users.noreply.github.com> Date: Wed, 12 Mar 2025 10:08:53 +0900 Subject: [PATCH 8/8] =?UTF-8?q?build:=20secret=20string=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=20=EB=B3=80=EC=88=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/testBranch.yml | 1 + app/.gitignore | 2 +- app/build.gradle.kts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testBranch.yml b/.github/workflows/testBranch.yml index 07be595..e2aac81 100644 --- a/.github/workflows/testBranch.yml +++ b/.github/workflows/testBranch.yml @@ -33,6 +33,7 @@ jobs: - name: Generate kover coverage report env: ADMOB_APP_ID: ${{ secrets.ADMOB_APP_ID }} + ADMOB_BANNER_ID: ${{ secrets.ADMOB_BANNER_ID }} run: | chmod +x ./gradlew ./gradlew koverXmlReport diff --git a/app/.gitignore b/app/.gitignore index 342694e..626c8a5 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1,2 +1,2 @@ /build -*-secret.xml \ No newline at end of file +.env \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cbe21a0..c2fee4c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,6 +20,7 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" resValue("string", "admob_app_id", System.getenv("ADMOB_APP_ID") ?: "") + resValue("string", "admob_banner_id", System.getenv("ADMOB_BANNER_ID") ?: "") } buildTypes {