-
Notifications
You must be signed in to change notification settings - Fork 0
Chore/#126 link #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Chore/#126 link #143
Changes from all commits
1a97d79
bb8fbf3
cae9a16
ef003df
cda40a1
1917332
b160d51
0c1d6cc
522b105
cd65a08
516e0eb
ed304fb
4b6f8d4
eac6b65
9a82420
c36b349
b34cf5a
03b924b
3a38cf7
82d3384
d01469e
d33e92f
ddde533
7ccb07d
6aa03ba
c57bb3d
e9faa7c
6f5513f
7f70dea
71f5c0d
f2fe87f
ceaa443
92cf18d
155ec68
523e337
b8f42c3
c7bb7b6
9f7a772
97dc501
ae715ef
58a76d0
f83aa5e
4177d52
1f14c4f
14c80b2
6956155
a3e4141
72b7beb
3656030
488e453
badd798
15a9dcd
3422028
45b03a5
71c41df
f3e834b
6bc7736
02cc312
0c9138c
33e3734
d86b3ac
4cf3e1b
742bb1e
26cc654
1422b6a
0b32e8c
dd8fb76
f3d00c4
ac2984f
eb9a021
406cb78
0b5645c
8962f7e
7878663
63218e4
e9c8c57
bf47a4d
e953b32
4bf61d9
3d1dc87
b2f49ed
11811bb
91512d1
5ade90b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,17 @@ | ||
| <<<<<<<< HEAD:app/src/androidTest/java/com/linku/link/ExampleInstrumentedTest.kt | ||
| package com.linku.link | ||
| ======== | ||
| package com.linku | ||
| >>>>>>>> fd1304faab6b86e04c17e31a0786ce151290d292:app/src/androidTest/java/com/linku/ExampleInstrumentedTest.kt | ||
|
|
||
| import androidx.test.platform.app.InstrumentationRegistry | ||
| import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
|
|
||
| import org.junit.Test | ||
| import org.junit.runner.RunWith | ||
|
|
||
| import org.junit.Assert.* | ||
|
|
||
| /** | ||
| * Instrumented test, which will execute on an Android device. | ||
| * | ||
| * See [testing documentation](http://d.android.com/tools/testing). | ||
| */ | ||
| @RunWith(AndroidJUnit4::class) | ||
| class ExampleInstrumentedTest { | ||
|
|
||
| @Test | ||
| fun useAppContext() { | ||
| // Context of the app under test. | ||
| val appContext = InstrumentationRegistry.getInstrumentation().targetContext | ||
| <<<<<<<< HEAD:app/src/androidTest/java/com/linku/link/ExampleInstrumentedTest.kt | ||
| assertEquals("com.linku.link", appContext.packageName) | ||
| ======== | ||
| assertEquals("com.linku", appContext.packageName) | ||
| >>>>>>>> fd1304faab6b86e04c17e31a0786ce151290d292:app/src/androidTest/java/com/linku/ExampleInstrumentedTest.kt | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,94 @@ | ||
| package com.linku | ||
|
|
||
| import android.app.NotificationManager | ||
| import android.app.PendingIntent | ||
| import android.util.Log | ||
| import androidx.core.app.NotificationCompat | ||
| import com.google.firebase.messaging.FirebaseMessagingService | ||
| import com.google.firebase.messaging.RemoteMessage | ||
| import com.linku.core.di.ApplicationScope | ||
| import com.linku.core.repository.AlarmRepository | ||
| import com.linku.data.preference.NotificationPreference | ||
| import dagger.hilt.android.AndroidEntryPoint | ||
| import kotlinx.coroutines.CoroutineScope | ||
| import kotlinx.coroutines.launch | ||
| import javax.inject.Inject | ||
|
|
||
|
|
||
| @AndroidEntryPoint | ||
| class LinkUFireBaseMessageService : FirebaseMessagingService() { | ||
|
|
||
| // FirebaseMessagingService๋ ์์ฑ์ ์ฃผ์ ์ด ๋ถ๊ฐ. ๋ฐ๋ผ์ ํ๋ ์ฃผ์ ์ฌ์ฉ | ||
| @Inject | ||
| lateinit var alarmRepository: AlarmRepository | ||
| @Inject | ||
| lateinit var notificationPreference: NotificationPreference | ||
|
|
||
| @Inject | ||
| @ApplicationScope | ||
| lateinit var externalScope: CoroutineScope | ||
|
|
||
| //FireBase์์ ์ ํ ํฐ์ด ๋ฐ๊ธ๋์์ ๋ ํธ์ถ๋๋ ์ฝ๋ฐฑ | ||
| override fun onNewToken(token: String) { | ||
| super.onNewToken(token) | ||
| // TODO: ์๋ฒ์ FCM ํ ํฐ ์ ์ก | ||
| if (BuildConfig.DEBUG) { | ||
| Log.d("FCM Token", token) | ||
| } | ||
|
|
||
| notificationPreference.setFcmToken(token) | ||
|
|
||
| externalScope.launch { | ||
| alarmRepository.registerFCMToken(token) | ||
| } | ||
| } | ||
|
|
||
| // FireBase๋ก๋ถํฐ ๋ฉ์ธ์ง๋ฅผ ๋ฐ์์ ๋ ํธ์ถ๋๋ ์ฝ๋ฐฑ | ||
| override fun onMessageReceived(message: RemoteMessage) { | ||
| super.onMessageReceived(message) | ||
| // TODO: ํธ์ ์๋ฆผ ์ฒ๋ฆฌ | ||
|
|
||
| // ํธ์์๋ฆผ ํ์ฑํ ์๋์ด์์ผ๋ฉด ์ข ๋ฃ | ||
| if (!notificationPreference.isMasterNotificationEnabled()) return | ||
|
|
||
| // FCM ๋ฉ์์ง ํ์ ์ ๋ฐ๋ผ title/body ์ถ์ถ | ||
| // Notification Message: message.notification์์ ์ถ์ถ | ||
| // Data Message: message.data์์ ์ถ์ถ | ||
| // ๋ ๋ค ์์ผ๋ฉด ์ฒ๋ฆฌ ๋ถํ์๋ก ํ๋จํ์ฌ ์ข ๋ฃ | ||
| val title = message.notification?.title ?: message.data["title"] ?: return | ||
| val body = message.notification?.body ?: message.data["message"] ?: return | ||
| val targetId = message.data["targetId"] ?: "null" | ||
|
|
||
| Log.d("FCM", """ | ||
| FCM ์์ | ||
| title: $title | ||
| body: $body | ||
| targetId: $targetId | ||
| """.trimIndent() | ||
| ) | ||
|
|
||
| // ์ผ๋จ์ ์กํฐ๋นํฐ๋ก์ ์ด๋์ฒ๋ฆฌ๋ง ๊ตฌํ. ์ถํ ์์ ์์ | ||
| val pendingIntent = PendingIntent.getActivity( | ||
| this, | ||
| 0, | ||
| packageManager.getLaunchIntentForPackage(packageName), | ||
| PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT | ||
| ) | ||
|
|
||
| // ์๋ฆผ ์ ์ | ||
| val notification = NotificationCompat.Builder(this, CHANNEL_ID) | ||
| .setSmallIcon(R.drawable.ic_logo) | ||
| .setContentTitle(title) | ||
| .setContentText(body) | ||
| .setPriority(NotificationCompat.PRIORITY_DEFAULT) | ||
| .setAutoCancel(true) | ||
| .setContentIntent(pendingIntent) | ||
| .build() | ||
|
|
||
| // ์๋ฆผ ์ถ๋ ฅ | ||
| getSystemService(NotificationManager::class.java) | ||
| .notify(System.currentTimeMillis().toInt(), notification) | ||
| } | ||
|
|
||
| } | ||
| companion object { | ||
| const val CHANNEL_ID = "default_channel" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,8 @@ import com.linku.file.FileViewModel | |
| import com.linku.file.viewmodel.folder.state.FolderStateViewModel | ||
| import com.linku.home.HomeApp | ||
| import com.linku.home.HomeViewModel | ||
| import com.linku.home.screen.SaveLinkResultScreen | ||
| import com.linku.home.component.LinkCategoryOption | ||
| import com.linku.home.screen.LinkDetailScreen | ||
| import com.linku.home.screen.SaveLinkScreen | ||
| import com.linku.linku_android.curation.curationGraph | ||
| import com.linku.login.navigation.LoginApp | ||
|
|
@@ -159,10 +160,9 @@ fun MainApp( | |
| // ๊ถํ ์์ฒญ ๋ฐ์ณ | ||
| val notificationPermissionLauncher = rememberLauncherForActivityResult( | ||
| ActivityResultContracts.RequestPermission() | ||
| ) { isGranted -> // ์์คํ ๊ถํ ์์ฒญ ๊ฒฐ๊ณผ๋ฅผ ๋ก์ปฌ์ ์ ์ฅ | ||
| ) { isGranted -> | ||
| viewModel.setNotificationEnabled(isGranted) | ||
| Log.d("MainApp", "์๋ฆผ ๊ถํ ์์ฒญ ๊ฒฐ๊ณผ: $isGranted") | ||
| Log.d("MainApp", "์์คํ ๊ถํ ์ํ: ${ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED}") | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -173,6 +173,8 @@ fun MainApp( | |
| // Android 13 ์ด์์์๋ POST_NOTIFICATIONS ๋ฐํ์ ๊ถํ์ด ํ์ํ๋ฏ๋ก ์กฐ๊ฑด๋ถ ์์ฒญ | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||
| notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) | ||
| } else { | ||
| viewModel.setNotificationEnabled(true) | ||
| } | ||
| requestNotificationPermission = false // ํ ๋ฒ๋ง ์์ฒญํ๋๋ก ์ฒ๋ฆฌ | ||
| } | ||
|
|
@@ -359,7 +361,7 @@ fun MainApp( | |
| HomeApp( | ||
| viewModel = homeViewModel, | ||
| nickname = nickname.orEmpty().ifBlank { "๋งํ" }, | ||
| onNavigateToMyPage = { // TODO: ์ถํ ์๋ฆผ ์ค์ ํ์ด์ง๋ก ์ด๋ | ||
| onNavigateToMyPage = { | ||
| navigator.navigate(NavigationRoute.MyPage.route) { | ||
| popUpTo(navigator.graph.findStartDestination().id) { | ||
| saveState = true | ||
|
|
@@ -369,6 +371,13 @@ fun MainApp( | |
| restoreState = true | ||
| } | ||
| }, | ||
| onNavigateToSaveLink = { url -> | ||
| homeViewModel.setUrl(url) | ||
| navigator.navigate("savelink") | ||
| }, | ||
| onNavigateToLinkDetail = { linkuId -> | ||
| navigator.navigate("savelinkresult/$linkuId") | ||
| }, | ||
| onShowNavBar = { showNavBar = it } | ||
| ) | ||
| } | ||
|
|
@@ -453,18 +462,29 @@ fun MainApp( | |
| SaveLinkScreen( | ||
| image = vm.image, | ||
| url = vm.url, | ||
| title = vm.title, | ||
| memo = vm.memo, | ||
| selectedEmotionId = vm.selectedEmotionId, | ||
| selectedSituationId = vm.selectedSituationId, | ||
| jobId = vm.jobId ?: 3L, | ||
| onPickImage = { imagePicker.launch("image/*") }, | ||
| onUrlChange = vm::setUrl, | ||
| onTitleChange = vm::setTitle, | ||
| onMemoChange = vm::setMemo, | ||
| onEmotionSelect = vm::selectEmotion, | ||
| onSituationSelect = vm::selectSituation, | ||
| onSaveClick = { | ||
| // ์ ์ฅ ๋ฒํผ ๋ก๊ทธ + API ํธ์ถ | ||
| Log.d("SaveLink", "try save -> url=${vm.url}, memo=${vm.memo}, emotionId=${vm.selectedEmotionId}, image=${vm.image?.name}") | ||
| Log.d( | ||
| "SaveLink", | ||
| "try save -> url=${vm.url}, memo=${vm.memo}, emotionId=${vm.selectedEmotionId}, situationId=${vm.selectedSituationId}, image=${vm.image?.name}" | ||
| ) | ||
|
|
||
| vm.saveLink( | ||
| onSucceed = { saved -> | ||
| Log.d("SaveLink", "success -> id=${saved.linkuId}, title=${saved.title}, domain=${saved.domain}") | ||
| Log.d( | ||
| "SaveLink", | ||
| "success -> id=${saved.linkuId}, title=${saved.title}, domain=${saved.domain}" | ||
| ) | ||
| vm.loadLinkDetail(saved.linkuId) | ||
| vm.resetForm() | ||
| navigator.navigate("savelinkresult/${saved.linkuId}") | ||
|
|
@@ -496,48 +516,115 @@ fun MainApp( | |
| vm.loadCategoryColors() | ||
| } | ||
|
|
||
| fun emotionNameOf(id: Long?): String { | ||
| return when (id) { | ||
| 1L -> "์ฆ๊ฑฐ์" | ||
| 2L -> "ํ์จ" | ||
| 3L -> "์ค๋ " | ||
| 4L -> "์ฌํ" | ||
| 5L -> "์ง์ฆ" | ||
| 6L -> "๋ถ๋ ธ" | ||
| else -> "๊ฐ์ " | ||
| } | ||
| } | ||
|
|
||
| // TODO: ์นดํ ๊ณ ๋ฆฌ API ์ฐ๋ ํ categoryId ๊ธฐ์ค ์ค์ ์นดํ ๊ณ ๋ฆฌ๋ช /์์ ๋งคํ์ผ๋ก ๊ต์ฒด | ||
| val CATEGORY_MAP = linkedMapOf( | ||
| 1L to "์ดํ", | ||
| 2L to "๋ด์ค", | ||
| 3L to "๊ณต๋ถ๋ฒ", | ||
| 4L to "ITยท๊ฐ๋ฐ", | ||
| 5L to "์๊ธฐ๊ณ๋ฐ", | ||
| 6L to "์ทจ์ ยท์ด์ง", | ||
| 7L to "๋น์ฆ๋์ค ์ธ์ฌ์ดํธ", | ||
| 8L to "์์ฐ์ฑยทํด", | ||
| 9L to "๋ผ์ดํ์คํ์ผ", | ||
| 10L to "์ฌ๋ฆฌยท์๊ธฐ์ดํด", | ||
| 11L to "์์ธ์ดยท์นผ๋ผ", | ||
| 12L to "ํธ๋ ๋", | ||
| 13L to "๋์์ธยท์์ ", | ||
| 14L to "์์ยท๋ฎค์ง", | ||
| 15L to "๋ง์งยท์ฌํ", | ||
| 16L to "๊ธฐํ" | ||
| ) | ||
|
Comment on lines
+519
to
+549
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] ์ด๋ ๊ฒ ๋งคํํจ์๊ฐ MainApp์ ์์ผ๋ฉด ๋ชจ๋์ฑ์ ์๋ฐฐ๋๋ค๊ณ ์๊ฐํฉ๋๋ค! ์ด๊ฑด ์์ ์ ์ ์ผ๋ก ์ ํด์ง ๋งคํ ๊ตฌํ์ด๋ ์ฌ๊ธฐ์ ์ด ๋ถ๋ถ์ ์ญ์ ํ๊ณ , ์ด๋ฏธ ์ ๋ง๋ค์ด์ง CategoryType, EmotionType์ด ์์ผ๋ ๋ฐ์์์ ์ธ ์ ์๊ฒ ์์ ํ๋ฉด ๋ ๊ฒ ๊ฐ์์ ๐ emotionNameOf, CATEGORY_MAP, categoryNameOf, categoryIdOf ์ญ์ ํ๊ณ , val categoryType = CategoryType.fromId(linkDetail?.categoryId)
val emotionType = EmotionType.fromId(linkDetail?.emotionId)ํ๋ค๋ฉด ๋ ์ข์ ๋ฐฉํฅ์ผ ๊ฒ ๊ฐ์ต๋๋ค:) ์ถ๊ฐ์ ์ผ๋ก
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์นดํ ๊ณ ๋ฆฌ๋ API ์ฐ๋์ผ๋ก ๊ตฌํํ ์์ ์ด๋ผ ์ง๊ธ์ ์ผ๋จ ์ ๋ ๊ฒ ๊ตฌํํด๋จ์์ด์ใ ใ ์ถํ์ ํ์ฅ๋์ด design ๋ชจ๋์ ์นดํ ๊ณ ๋ฆฌ ๊ด๋ จ๋ ํ์ผ ์ฌ๋ ค์ฃผ์๋ฉด ๊ทธ ๋ API ์ฐ๋ํ๋ฉด์ ์์ ํ๊ฒ ์ต๋๋ค |
||
|
|
||
| fun categoryNameOf(id: Long?): String { | ||
| return CATEGORY_MAP[id] ?: "์นดํ ๊ณ ๋ฆฌ" | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| fun categoryIdOf(name: String): Long? { | ||
| return CATEGORY_MAP.entries | ||
| .firstOrNull { it.value == name } | ||
| ?.key | ||
| } | ||
|
|
||
| fun keywordToTags(keyword: String?): List<String> { | ||
| return keyword | ||
| .orEmpty() | ||
| .split(",", " ", "#") | ||
| .map { it.trim() } | ||
| .filter { it.isNotBlank() } | ||
| .take(4) | ||
| } | ||
|
|
||
| // ์งํ๋ฅ /์์ ๋งต ์์ง | ||
| val aiProgress = vm.aiProgress.collectAsState().value | ||
| val categoryColorMap = vm.categoryColorMap.collectAsState().value | ||
|
|
||
| val categoryOptions = categoryColorMap.mapNotNull { (name, style) -> | ||
| val id = categoryIdOf(name) ?: return@mapNotNull null | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] ์ฌ๊ธฐ์ ์๋ฒ์์ ๋ด๋ ค์ค string ๋ฐ์ดํฐ๋ฅผ ๋ค์ LongId๋ก ์ญ๋งคํํ๋๊ฑฐ ๋ง๋์? ์ ์๋๋ฉด categoryColorMap์ String ํค๊ฐ ์๋๋ผ CategoryType ํค๋ก ๋ฐ๊พธ๋ ๋ฐฉํฅ์ ์ด๋ค๊ฐ์? private val _categoryColorMap = MutableStateFlow<Map<CategoryType, CategoryColorStyle>>(emptyMap())์ด๋ ๊ฒ ํ๋ทฐ๋ชจ๋ธ์์ ์์ String name์ ํ ๋ฒ ๋ณํํ๋ฉด.... ๋ญ ์ญ ๋งคํํ ํ์๋ ์์ง ์์๊น ์ถ์๋ฐ ๊ทธ๋ฌ๋ฉด ์ฌ๊ธฐ์๋ val categoryOptions = categoryColorMap.map { (type, style) ->
LinkCategoryOption(
id = type.id,
name = type.tagName,
color = style.color4
)
}์ด๋ ๊ฒ ํ๋ฉด ๋ ๊ฒ ๊ฐ๊ธฐ๋ ํ๊ณ ..? ์ ์๋๋ฉด ์์ LinkCategoryOption์ด Long id๋ฅผ ๋ฐ๋ก ๋ค ํ์ ์์ด CategoryType์ ์ง์ ๋๋ ๋ฐฉ์๋ ์์ ๊ฒ ๊ฐ์๋ฐ ์งํ์ด๊ฐ ๊ฐ๋ฐํ ํํธ์ด๋ ํ ๋ฒ ๋ณด๊ณ ํ๋จํด์ฃผ์ธ์:) |
||
|
|
||
| LinkCategoryOption( | ||
| id = id, | ||
| name = name, | ||
| color = style.color4 | ||
| ) | ||
| } | ||
|
Comment on lines
+519
to
+582
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ด๋ฆ๋ง์ผ๋ก๋ ์ ๋ํฌํ ๋ฐ์ดํฐ๋ค์ Long ํ์ id๊ฐ ๋ค์ด๊ฐ๋ ๊ฑด ๋ถ์๋ถ์ํ๋ค์..
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ด๋์ผ๋ก ๋ฐ๊ฟ๋ณผ๊ฒ์ |
||
|
|
||
| // ์ธ๋ถ ๋ธ๋ผ์ฐ์ ์ด๊ธฐ | ||
| fun openUrl(url: String) { | ||
| runCatching { | ||
| val fixed = if (url.startsWith("http")) url else "https://$url" | ||
| val fixed = if ( | ||
| url.startsWith("http://") || url.startsWith("https://") | ||
| ) { | ||
| url | ||
| } else { | ||
| "https://$url" | ||
| } | ||
|
|
||
| val intent = Intent( | ||
| Intent.ACTION_VIEW, | ||
| fixed.toUri() | ||
| ) | ||
|
|
||
| context.startActivity(intent) | ||
| }.onFailure { | ||
| Toast.makeText(context, "๋งํฌ๋ฅผ ์ด ์ ์์ด์.", Toast.LENGTH_SHORT).show() | ||
| } | ||
| } | ||
|
|
||
| SaveLinkResultScreen( | ||
| link = vm.linkDetail, | ||
| aiArticle = vm.aiArticleDetail, | ||
| isLoading = vm.isLoadingLinkDetail || vm.isLoadingAiArticle, | ||
| isAiLoading = vm.isLoadingAiArticle, | ||
| onBack = { navigator.popBackStack() }, | ||
| onOpenLink = { url -> openUrl(url) }, | ||
| categoryColorMap = categoryColorMap, | ||
| onSubmitEdit = { title, memo, categoryId, emotionId -> | ||
| vm.updateLink( | ||
| title = title, | ||
| memo = memo, | ||
| categoryId = categoryId, | ||
| emotionId = emotionId, | ||
| onSucceed = { Toast.makeText(context, "์์ ์๋ฃ", Toast.LENGTH_SHORT).show() }, | ||
| onFailed = { e -> | ||
| Log.e("SaveLinkResult", "์์ ์คํจ", e) | ||
| Toast.makeText(context, e.message ?: "์์ ์ ์คํจํ์ต๋๋ค.", Toast.LENGTH_SHORT).show() | ||
| } | ||
| ) | ||
| }, | ||
| onRequestAiSummary = { vm.loadAiArticle(linkuId) }, | ||
| aiProgress = aiProgress, | ||
| onCancelAi = { vm.cancelAiArticleJob() } | ||
| val linkDetail = vm.linkDetail | ||
| val aiArticle = vm.aiArticleDetail | ||
|
|
||
| val displayKeyword = aiArticle?.keyword?.trim().orEmpty() | ||
| .ifEmpty { linkDetail?.keyword.orEmpty() } | ||
|
|
||
| val displaySummary = aiArticle?.summary?.trim().orEmpty() | ||
| .ifEmpty { linkDetail?.summary.orEmpty() } | ||
|
|
||
| LinkDetailScreen( | ||
| linkTitle = linkDetail?.title.orEmpty(), | ||
| category = categoryNameOf(linkDetail?.categoryId), | ||
| emotion = emotionNameOf(linkDetail?.emotionId), | ||
| situationId = null, // TODO: ์์ธ API์ situationId ์๊ธฐ๋ฉด linkDetail?.situationId๋ก ๋ณ๊ฒฝ | ||
| linkUrl = linkDetail?.linku.orEmpty(), | ||
| memo = linkDetail?.memo.orEmpty(), | ||
| tags = keywordToTags(displayKeyword), | ||
| aiSummary = displaySummary, | ||
| categoryOptions = categoryOptions, | ||
| onBack = { | ||
| navigator.popBackStack() | ||
| } | ||
| ) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๐ฉบ Stability & Availability | ๐ Major
๐งฉ Analysis chain
๐ Web query:
Android PendingIntent.getActivity intent parameter nullable NonNull๐ก Result:
In the Android API, the intent parameter of the PendingIntent.getActivity method is marked as
@NonNull[1][2]. While some older documentation or specific framework versions might occasionally display ambiguous nullability annotations in generated documentation [3][4], the official source code for PendingIntent.getActivity explicitly defines the intent parameter as@NonNull[1][2]. Attempting to pass a null Intent to this method will typically result in a NullPointerException, as the system requires a valid Intent to define the activity that the PendingIntent should launch [5].Citations:
getLaunchIntentForPackage์ nullable ๋ฐํ๊ฐ์ดPendingIntent.getActivity์ ์ ๋ฌ๋์ด NPE ์ํ์ด ์์ต๋๋ค.packageManager.getLaunchIntentForPackage(packageName)์ ๋ฐ์ฒ ํ๋์ ์ฐพ์ง ๋ชปํ๋ฉดnull์ ๋ฐํํ ์ ์์ผ๋,PendingIntent.getActivity์ intent ํ๋ผ๋ฏธํฐ๋@NonNull์ผ๋ก ์ ์ธ๋์ด ์์ด null ์ ๋ฌ ์ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.์ ์ ์์
๐ Committable suggestion
๐ค Prompt for AI Agents