Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/android-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ jobs:
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ job.status }}
content: "<@${{ secrets.DISCORD_NOTIFY_USER_ID }}> チェック終わったみたい ${{ secrets.DISCORD_NOTIFY_SUFFIX }}"
1 change: 1 addition & 0 deletions AndroidApp/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".App"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.nya_n.notificationnotifier

import android.app.Application
import android.net.ConnectivityManager
import me.nya_n.notificationnotifier.data.repository.AppRepository
import me.nya_n.notificationnotifier.data.repository.BackupRepository
import me.nya_n.notificationnotifier.data.repository.UserSettingsRepository
Expand All @@ -23,6 +24,7 @@ import me.nya_n.notificationnotifier.domain.usecase.NotifyUseCase
import me.nya_n.notificationnotifier.domain.usecase.PackageVisibilityGrantedUseCase
import me.nya_n.notificationnotifier.domain.usecase.SaveAddressUseCase
import me.nya_n.notificationnotifier.domain.usecase.SaveFilterConditionUseCase
import me.nya_n.notificationnotifier.domain.usecase.SaveWifiOnlyNotificationSettingUseCase
import me.nya_n.notificationnotifier.domain.usecase.ToggleIgnoreSummaryUseCase
import me.nya_n.notificationnotifier.domain.usecase.impl.AddTargetAppUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.CheckPackageVisibilityUseCaseImpl
Expand All @@ -37,6 +39,7 @@ import me.nya_n.notificationnotifier.domain.usecase.impl.NotifyUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.PackageVisibilityGrantedUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.SaveAddressUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.SaveFilterConditionUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.SaveWifiOnlyNotificationSettingUseCaseImpl
import me.nya_n.notificationnotifier.domain.usecase.impl.ToggleIgnoreSummaryUseCaseImpl
import me.nya_n.notificationnotifier.model.AppConfig
import me.nya_n.notificationnotifier.ui.screen.app.AppViewModel
Expand All @@ -60,6 +63,8 @@ class App : Application() {
}

private val modules = module {
single { applicationContext.getSystemService(ConnectivityManager::class.java) }

// BuildConfigのデータ共有用
single {
AppConfig(
Expand Down Expand Up @@ -91,7 +96,7 @@ class App : Application() {
viewModel { SelectionViewModel(get(), get()) }
viewModel { params -> DetailViewModel(get(), get(), get(), get(), params.get()) }
viewModel { TargetViewModel(get()) }
viewModel { SettingsViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { SettingsViewModel(get(), get(), get(), get(), get(), get(), get()) }

// UseCase
factory<AddTargetAppUseCase> { AddTargetAppUseCaseImpl(get()) }
Expand All @@ -102,13 +107,18 @@ class App : Application() {
factory<LoadAppUseCase> { LoadAppUseCaseImpl(get(), get()) }
factory<LoadFilterConditionUseCase> { LoadFilterConditionUseCaseImpl(get()) }
factory<NotifyTargetAppNotificationUseCase> {
NotifyTargetAppNotificationUseCaseImpl(get(), get())
NotifyTargetAppNotificationUseCaseImpl(get(), get(), get(), get())
}
factory<NotifyUseCase> { NotifyUseCaseImpl(get()) }
factory<PackageVisibilityGrantedUseCase> { PackageVisibilityGrantedUseCaseImpl(get()) }
factory<CheckPackageVisibilityUseCase> { CheckPackageVisibilityUseCaseImpl(get()) }
factory<SaveAddressUseCase> { SaveAddressUseCaseImpl(get()) }
factory<SaveFilterConditionUseCase> { SaveFilterConditionUseCaseImpl(get()) }
factory<ToggleIgnoreSummaryUseCase> { ToggleIgnoreSummaryUseCaseImpl(get()) }
factory<SaveWifiOnlyNotificationSettingUseCase> {
SaveWifiOnlyNotificationSettingUseCaseImpl(
get()
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@ import me.nya_n.notificationnotifier.model.UserSettings
class UserSettingsDataStore(
pref: SharedPreferences
) : KeyValueDataStore(pref) {
companion object {
const val DATA_STORE_NAME = "settings"
const val KEY_HOST = "host"
const val DEFAULT_HOST = ""
const val KEY_PORT = "port"
const val DEFAULT_PORT = -1
const val KEY_IS_PACKAGE_VISIBILITY_GRANTED = "isPackageVisibilityGranted"
const val DEFAULT_IS_PACKAGE_VISIBILITY_GRANTED = false
const val KEY_IS_WIFI_ONLY_NOTIFICATION_ENABLED = "isWifiOnlyNotificationEnabled"
const val DEFAULT_IS_WIFI_ONLY_NOTIFICATION_ENABLED = false
}

fun get(): UserSettings {
return UserSettings(
get(KEY_HOST, DEFAULT_HOST),
get(KEY_PORT, DEFAULT_PORT),
get(KEY_IS_PACKAGE_VISIBILITY_GRANTED, DEFAULT_IS_PACKAGE_VISIBILITY_GRANTED)
get(KEY_IS_PACKAGE_VISIBILITY_GRANTED, DEFAULT_IS_PACKAGE_VISIBILITY_GRANTED),
get(KEY_IS_WIFI_ONLY_NOTIFICATION_ENABLED, DEFAULT_IS_WIFI_ONLY_NOTIFICATION_ENABLED)
)
}

fun save(settings: UserSettings) {
put(KEY_HOST, settings.host)
put(KEY_PORT, settings.port)
put(KEY_IS_PACKAGE_VISIBILITY_GRANTED, settings.isPackageVisibilityGranted)
}

companion object {
const val DATA_STORE_NAME = "settings"
const val KEY_HOST = "host"
const val DEFAULT_HOST = ""
const val KEY_PORT = "port"
const val DEFAULT_PORT = -1
const val KEY_IS_PACKAGE_VISIBILITY_GRANTED = "isPackageVisibilityGranted"
const val DEFAULT_IS_PACKAGE_VISIBILITY_GRANTED = false
put(KEY_IS_WIFI_ONLY_NOTIFICATION_ENABLED, settings.isWifiOnlyNotificationEnabled)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.nya_n.notificationnotifier.domain.usecase

interface SaveWifiOnlyNotificationSettingUseCase {
operator fun invoke(isWifiOnlyNotificationEnabled: Boolean): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
package me.nya_n.notificationnotifier.domain.usecase.impl

import android.Manifest
import android.app.Notification
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import androidx.annotation.RequiresPermission
import me.nya_n.notificationnotifier.data.repository.AppRepository
import me.nya_n.notificationnotifier.data.repository.UserSettingsRepository
import me.nya_n.notificationnotifier.domain.usecase.NotifyTargetAppNotificationUseCase
import me.nya_n.notificationnotifier.domain.usecase.NotifyUseCase

class NotifyTargetAppNotificationUseCaseImpl(
private val connectionManager: ConnectivityManager,
private val appRepository: AppRepository,
private val userSettingsRepository: UserSettingsRepository,
private val notifyUseCase: NotifyUseCase,
) : NotifyTargetAppNotificationUseCase {
@get:RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
private val isConnectedToWifi: Boolean
get() {
val network = connectionManager.activeNetwork ?: return false
val capabilities = connectionManager.getNetworkCapabilities(network) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
}

override suspend operator fun invoke(
packageName: String,
title: String,
message: String,
flags: Int
): Result<Unit> {
return runCatching {
val settings = userSettingsRepository.getUserSettings()
if (settings.isWifiOnlyNotificationEnabled && !isConnectedToWifi) {
return Result.success(Unit)
}

val targets = appRepository.getTargetAppList()
if (!targets.any { t -> t.packageName == packageName }) {
return Result.success(Unit)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package me.nya_n.notificationnotifier.domain.usecase.impl

import me.nya_n.notificationnotifier.data.repository.UserSettingsRepository
import me.nya_n.notificationnotifier.domain.usecase.SaveWifiOnlyNotificationSettingUseCase

class SaveWifiOnlyNotificationSettingUseCaseImpl(
private val userSettingsRepository: UserSettingsRepository
) : SaveWifiOnlyNotificationSettingUseCase {
override fun invoke(isWifiOnlyNotificationEnabled: Boolean): Result<Unit> {
return runCatching {
val settings = userSettingsRepository.getUserSettings()
userSettingsRepository.saveUserSettings(
settings.copy(
isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled
)
)
return Result.success(Unit)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class UseCaseTest {

@Test
fun `インストール済みアプリの取得_許可あり`() {
every { userSettingsRepository.getUserSettings() } returns UserSettings("", 0, true)
every { userSettingsRepository.getUserSettings() } returns UserSettings("", 0, true, false)
every { appRepository.loadInstalledAppList() } returns listOf(InstalledApp("", ""))

val ret = loadAppUseCase.loadInstalledAppList()
Expand All @@ -61,7 +61,7 @@ class UseCaseTest {

@Test
fun `インストール済みアプリの取得_許可なし`() {
every { userSettingsRepository.getUserSettings() } returns UserSettings("", 0, false)
every { userSettingsRepository.getUserSettings() } returns UserSettings("", 0, false, false)
every { appRepository.loadInstalledAppList() } throws PermissionDeniedException()

val ret = loadAppUseCase.loadInstalledAppList()
Expand All @@ -76,7 +76,8 @@ class UseCaseTest {
every { userSettingsRepository.getUserSettings() } returns UserSettings(
"192.168.10.18",
8484,
true
true,
false
)
Comment on lines 76 to 81
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find all UserSettings constructor usages to identify which need updating
rg -n "UserSettings\s*\(" --type kotlin -B 1 -A 5

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 20933


UserSettingsRepositoryTest.kt の44行目を4パラメータコンストラクタに更新してください

UserSettingsRepositoryTest.kt の46行目でUserSettingsの3パラメータコンストラクタが使用されています。新しい4パラメータシグネチャに対応するため、isWifiOnlyNotificationEnabledパラメータを追加する必要があります。

該当コード
        val data = UserSettings("192.168.10.18", 8484, false)

修正例:

        val data = UserSettings("192.168.10.18", 8484, false, false)
🤖 Prompt for AI Agents
In `@AndroidApp/domain/src/test/java/me/nya_n/notificationnotifier/UseCaseTest.kt`
around lines 76 - 81, Test uses the old 3-parameter UserSettings constructor;
update the UserSettings constructor call in UserSettingsRepositoryTest to pass
the new fourth boolean parameter (isWifiOnlyNotificationEnabled) so the
instantiation matches the new 4-parameter signature of the UserSettings class
(update the val data = UserSettings(...) call to include the additional boolean,
e.g., set it to false).

every { userSettingsRepository.saveUserSettings(any()) } just Runs

Expand Down Expand Up @@ -115,7 +116,8 @@ class UseCaseTest {
every { userSettingsRepository.getUserSettings() } returns UserSettings(
"192.168.10.18",
8484,
true
true,
false
)

runTest(testDispatcher) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ data class UserSettings(
val host: String,
val port: Int,
/**
* @see <a href="https://support.google.com/googleplay/android-developer/answer/10158779?hl=ja">https://support.google.com/googleplay/android-developer/answer/10158779</a>
* @see <a href="https://support.google.com/googleplay/android-developer/answer/10158779?hl=ja">パッケージ(アプリ)の広範な一覧取得(QUERY_ALL_PACKAGES)権限の使用</a>
*/
@SerializedName("is_package_visibility_granted")
val isPackageVisibilityGranted: Boolean
val isPackageVisibilityGranted: Boolean,
@SerializedName("is_wifi_only_notification_enabled")
val isWifiOnlyNotificationEnabled: Boolean
Comment on lines +13 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find Backup.kt and examine its structure
find . -name "Backup.kt" -o -name "backup.kt" | head -20

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 159


🏁 Script executed:

# List files in the model directory to understand structure
git ls-files | grep -E "(Backup|UserSettings|backup)" | head -30

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 939


🏁 Script executed:

# Search for UserSettings usage in backup context
rg -n "UserSettings" --type kotlin | grep -E "(Backup|backup)" | head -30

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 370


🏁 Script executed:

# Look for Gson configuration and deserialization logic
rg -n "Gson|fromJson|deserialize" --type kotlin | head -40

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 1216


🏁 Script executed:

# Check for any default value assignments in UserSettings
rg -n "UserSettings" -A 30 --type kotlin | grep -E "(class UserSettings|=|default)" | head -40

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 6710


🏁 Script executed:

# Read Backup.kt to see its structure
cat -n AndroidApp/model/src/main/kotlin/me/nya_n/notificationnotifier/model/Backup.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 445


🏁 Script executed:

# Read UserSettings.kt to see all fields and current defaults
cat -n AndroidApp/model/src/main/kotlin/me/nya_n/notificationnotifier/model/UserSettings.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 713


🏁 Script executed:

# Read ImportDataUseCaseImpl to see deserialization and error handling
cat -n AndroidApp/domain/src/main/kotlin/me/nya_n/notificationnotifier/domain/usecase/impl/ImportDataUseCaseImpl.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 1713


🏁 Script executed:

# Search for Gson configuration, custom TypeAdapter, or JsonDeserializer
rg -n "TypeAdapter|JsonDeserializer|GsonBuilder|setFieldNamingStrategy" --type kotlin

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 61


🏁 Script executed:

# Check for Gson version in build.gradle files
find . -name "build.gradle*" -type f | xargs grep -l "gson"

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 151


🏁 Script executed:

# Search for test cases related to backup import
rg -n "ImportDataUseCase|import.*json|backup" --type kotlin | grep -i "test"

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 1075


🏁 Script executed:

# Check if there's a Gson configuration or dependency setup
git ls-files | grep -i "gson\|gradle" | head -20

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 642


🏁 Script executed:

# Check Gson version and dependencies
cat -n AndroidApp/gradle/libs.versions.toml | grep -i gson

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 226


🏁 Script executed:

# Check domain build.gradle.kts for Gson config
cat -n AndroidApp/domain/build.gradle.kts | head -50

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 1420


🏁 Script executed:

# Check UseCaseTest.kt to see if there are backward compatibility tests
cat -n AndroidApp/domain/src/androidTest/java/me/nya_n/notificationnotifier/UseCaseTest.kt | head -150

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 7950


🏁 Script executed:

# Search for any test data or old backup JSON files
find . -name "*.json" -type f | head -20

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 294


🏁 Script executed:

# Verify Gson behavior - search for any error handling or migration logic
rg -n "JsonSyntaxException|catch|try" AndroidApp/domain/src/main/kotlin/me/nya_n/notificationnotifier/domain/usecase/impl/ImportDataUseCaseImpl.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 61


🏁 Script executed:

# Check if there's any version migration or schema update logic
rg -n "version|migration|upgrade" --type kotlin | grep -i "backup\|import\|restore" | head -20

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 510


🏁 Script executed:

# Verify field initialization behavior in UserSettings
cat -n AndroidApp/model/src/main/kotlin/me/nya_n/notificationnotifier/model/UserSettings.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 713


古いバックアップファイルの復元に失敗する可能性

新しく追加されたnon-nullableのisWifiOnlyNotificationEnabledフィールドにはデフォルト値が設定されていません。Gsonはデフォルト値のないnon-nullableフィールドが欠落している場合、デシリアライズ時にJsonSyntaxExceptionをスローします。そのため、このフィールドを含まない古いバックアップをリストアする際に失敗します。

推奨される修正

デフォルト値を追加してください:

     `@SerializedName`("is_wifi_only_notification_enabled")
-    val isWifiOnlyNotificationEnabled: Boolean
+    val isWifiOnlyNotificationEnabled: Boolean = false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@SerializedName("is_wifi_only_notification_enabled")
val isWifiOnlyNotificationEnabled: Boolean
`@SerializedName`("is_wifi_only_notification_enabled")
val isWifiOnlyNotificationEnabled: Boolean = false
🤖 Prompt for AI Agents
In
`@AndroidApp/model/src/main/kotlin/me/nya_n/notificationnotifier/model/UserSettings.kt`
around lines 13 - 14, The non-nullable field isWifiOnlyNotificationEnabled in
UserSettings lacks a default, causing Gson to throw on deserializing older
backups; update the property declaration (isWifiOnlyNotificationEnabled) to
provide a sensible default value (e.g., false) so missing JSON keys do not cause
JsonSyntaxException during restore and ensure the class deserializes
successfully when the field is absent.

)
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -23,6 +24,7 @@ import androidx.compose.material.icons.outlined.CloudDownload
import androidx.compose.material.icons.outlined.CloudUpload
import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.Devices
import androidx.compose.material3.Checkbox
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.SnackbarHostState
Expand Down Expand Up @@ -115,6 +117,8 @@ fun SettingsScreen(
versionName = uiState.appConfig.versionString,
onValueChange = { viewModel.updateAddress(it) },
onNotifyTest = { viewModel.notifyTest() },
isWifiOnlyNotificationEnabled = uiState.isWifiOnlyNotificationEnabled,
onWifiOnlySettingChanged = { viewModel.updateWifiOnlySetting(it) },
onExportData = { viewModel.event(UiEvent.ExportData()) },
onImportData = { viewModel.event(UiEvent.ImportData()) },
onLicense = { navController.navigate(Screen.License.route) },
Expand All @@ -130,6 +134,8 @@ fun SettingsContent(
versionName: String,
onValueChange: (String) -> Unit,
onNotifyTest: () -> Unit,
isWifiOnlyNotificationEnabled: Boolean,
onWifiOnlySettingChanged: (Boolean) -> Unit,
onExportData: () -> Unit,
onImportData: () -> Unit,
onLicense: () -> Unit,
Expand All @@ -147,7 +153,9 @@ fun SettingsContent(
NotifySettings(
address = address,
onValueChange = onValueChange,
onNotifyTest = onNotifyTest
onNotifyTest = onNotifyTest,
isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled,
onWifiOnlySettingChanged = onWifiOnlySettingChanged
)
OtherSettings(
onExportData = onExportData,
Expand Down Expand Up @@ -176,7 +184,9 @@ fun SettingsContent(
private fun NotifySettings(
address: String,
onValueChange: (String) -> Unit,
onNotifyTest: () -> Unit
onNotifyTest: () -> Unit,
isWifiOnlyNotificationEnabled: Boolean,
onWifiOnlySettingChanged: (Boolean) -> Unit
) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
Expand Down Expand Up @@ -216,6 +226,15 @@ private fun NotifySettings(
text = stringResource(id = R.string.notify_test),
onClick = onNotifyTest
)
Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = isWifiOnlyNotificationEnabled,
onCheckedChange = onWifiOnlySettingChanged
)
Text("Wi-Fi接続時のみ転送する。")
}
}

/** その他の項目
Expand Down Expand Up @@ -293,6 +312,8 @@ private fun SettingsPreview() {
versionName = "1.0",
onValueChange = { },
onNotifyTest = { },
isWifiOnlyNotificationEnabled = true,
onWifiOnlySettingChanged = { },
onExportData = { },
onImportData = { },
onLicense = { },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import me.nya_n.notificationnotifier.domain.usecase.ImportDataUseCase
import me.nya_n.notificationnotifier.domain.usecase.LoadAddressUseCase
import me.nya_n.notificationnotifier.domain.usecase.NotifyUseCase
import me.nya_n.notificationnotifier.domain.usecase.SaveAddressUseCase
import me.nya_n.notificationnotifier.domain.usecase.SaveWifiOnlyNotificationSettingUseCase
import me.nya_n.notificationnotifier.model.AppConfig
import me.nya_n.notificationnotifier.model.Message
import me.nya_n.notificationnotifier.ui.R
Expand All @@ -22,6 +23,7 @@ class SettingsViewModel(
loadAddressUseCase: LoadAddressUseCase,
private val saveAddressUseCase: SaveAddressUseCase,
private val notifyUseCase: NotifyUseCase,
private val saveWifiOnlyNotificationSettingUseCase: SaveWifiOnlyNotificationSettingUseCase,
private val exportDataUseCase: ExportDataUseCase,
private val importDataUseCase: ImportDataUseCase
) : BaseViewModel<UiEvent>() {
Expand Down Expand Up @@ -59,6 +61,11 @@ class SettingsViewModel(
}
}

fun updateWifiOnlySetting(isWifiOnlyNotificationEnabled: Boolean) {
saveWifiOnlyNotificationSettingUseCase(isWifiOnlyNotificationEnabled)
_uiState.update { it.copy(isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled) }
}
Comment on lines +64 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "SettingsViewModel.kt" | head -20

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 180


🏁 Script executed:

cat -n ./AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/settings/SettingsViewModel.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 4573


🏁 Script executed:

find . -type f -name "SaveWifiOnlyNotificationSettingUseCase.kt" | head -5

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 201


🏁 Script executed:

cat -n ./AndroidApp/domain/src/main/kotlin/me/nya_n/notificationnotifier/domain/usecase/SaveWifiOnlyNotificationSettingUseCase.kt

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 298


🏁 Script executed:

# Check if there are any other similar use cases that return Result
rg "SaveWifiOnlyNotificationSettingUseCase" -A 5 -B 5

Repository: ptkNktq/AndroidNotificationNotifier

Length of output: 11200


保存失敗時のUI整合性を担保してください

Resultを無視してUI状態を更新しています。保存失敗時に表示と永続値がズレます。成功時のみ更新するか、失敗時の扱いを入れるべきです。同ファイル内のnotifyTest()exportData()importData()メソッドなど、他の同様のメソッドと同じく.isSuccessをチェックして条件付きで状態更新することを推奨します。

♻️ 修正案
     fun updateWifiOnlySetting(isWifiOnlyNotificationEnabled: Boolean) {
-        saveWifiOnlyNotificationSettingUseCase(isWifiOnlyNotificationEnabled)
-        _uiState.update { it.copy(isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled) }
+        val result = saveWifiOnlyNotificationSettingUseCase(isWifiOnlyNotificationEnabled)
+        if (result.isSuccess) {
+            _uiState.update { it.copy(isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled) }
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun updateWifiOnlySetting(isWifiOnlyNotificationEnabled: Boolean) {
saveWifiOnlyNotificationSettingUseCase(isWifiOnlyNotificationEnabled)
_uiState.update { it.copy(isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled) }
}
fun updateWifiOnlySetting(isWifiOnlyNotificationEnabled: Boolean) {
val result = saveWifiOnlyNotificationSettingUseCase(isWifiOnlyNotificationEnabled)
if (result.isSuccess) {
_uiState.update { it.copy(isWifiOnlyNotificationEnabled = isWifiOnlyNotificationEnabled) }
}
}
🤖 Prompt for AI Agents
In
`@AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/settings/SettingsViewModel.kt`
around lines 64 - 67, The updateWifiOnlySetting function currently ignores the
Result from saveWifiOnlyNotificationSettingUseCase and updates _uiState
unconditionally; change it to call saveWifiOnlyNotificationSettingUseCase and
check the returned Result (e.g., result.isSuccess) and only update
_uiState.copy(isWifiOnlyNotificationEnabled = ...) on success, and handle
failure by setting an error/failed state or leaving the UI unchanged (mirror the
pattern used in notifyTest(), exportData(), importData()); reference the
saveWifiOnlyNotificationSettingUseCase invocation and the _uiState.update call
when making the change.


/** バックアップのために外部ストレージにデータを保存 */
fun exportData(uri: Uri?) {
if (uri == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ import me.nya_n.notificationnotifier.model.Message
data class UiState(
val appConfig: AppConfig,
val address: String = "",
val message: Message? = null
val message: Message? = null,
val isWifiOnlyNotificationEnabled: Boolean = false
)
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ Google Playからインストールしてください。
###### 権限の説明
- インターネット接続
- 指定したアドレスに通知データを送信するために必要です。
- ネットワーク状態の取得
- Wi-Fiに接続しているか確認するために必要です。
- インストール済みアプリの取得
- 通知対象のアプリを選択するための必要です
- 通知対象のアプリを選択するために必要です
- 通知へのアクセス
- PCに通知する内容を知るために、通知へアクセスする必要があります。

Expand Down