Skip to content

Commit 4fd6376

Browse files
committed
feat: WebDAV toggle and plus license handling
1 parent 0c6fc27 commit 4fd6376

8 files changed

Lines changed: 81 additions & 1 deletion

File tree

app/src/main/java/com/sameerasw/airsync/data/local/DataStoreManager.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class DataStoreManager(private val context: Context) {
9292
private val PITCH_BLACK_THEME = booleanPreferencesKey("pitch_black_theme")
9393
private val SENTRY_REPORTING_ENABLED = booleanPreferencesKey("sentry_reporting_enabled")
9494
private val QUICK_SHARE_ENABLED = booleanPreferencesKey("quick_share_enabled")
95+
private val FILE_ACCESS_ENABLED = booleanPreferencesKey("file_access_enabled")
9596

9697
// Widget preferences
9798
private val WIDGET_TRANSPARENCY = androidx.datastore.preferences.core.floatPreferencesKey("widget_transparency")
@@ -346,6 +347,18 @@ class DataStoreManager(private val context: Context) {
346347
}
347348
}
348349

350+
suspend fun setFileAccessEnabled(enabled: Boolean) {
351+
context.dataStore.edit { preferences ->
352+
preferences[FILE_ACCESS_ENABLED] = enabled
353+
}
354+
}
355+
356+
fun isFileAccessEnabled(): Flow<Boolean> {
357+
return context.dataStore.data.map { preferences ->
358+
preferences[FILE_ACCESS_ENABLED] != false // Default to enabled
359+
}
360+
}
361+
349362
suspend fun setDefaultTab(tab: String) {
350363
context.dataStore.edit { prefs ->
351364
prefs[DEFAULT_TAB] = tab

app/src/main/java/com/sameerasw/airsync/data/repository/AirSyncRepositoryImpl.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,4 +295,12 @@ class AirSyncRepositoryImpl(
295295
override fun isQuickShareEnabled(): Flow<Boolean> {
296296
return dataStoreManager.isQuickShareEnabled()
297297
}
298+
299+
override suspend fun setFileAccessEnabled(enabled: Boolean) {
300+
dataStoreManager.setFileAccessEnabled(enabled)
301+
}
302+
303+
override fun isFileAccessEnabled(): Flow<Boolean> {
304+
return dataStoreManager.isFileAccessEnabled()
305+
}
298306
}

app/src/main/java/com/sameerasw/airsync/domain/model/UiState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,6 @@ data class UiState(
5050
val isOnboardingCompleted: Boolean = true,
5151
val widgetTransparency: Float = 1f,
5252
val isQuickShareEnabled: Boolean = false,
53+
val isFileAccessEnabled: Boolean = true,
5354
val bleConnectionState: com.sameerasw.airsync.data.ble.BleGattServer.BleConnectionState = com.sameerasw.airsync.data.ble.BleGattServer.BleConnectionState.DISCONNECTED
5455
)

app/src/main/java/com/sameerasw/airsync/domain/repository/AirSyncRepository.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,8 @@ interface AirSyncRepository {
132132
// Quick Share (receiving)
133133
suspend fun setQuickShareEnabled(enabled: Boolean)
134134
fun isQuickShareEnabled(): Flow<Boolean>
135+
136+
// File Access (WebDAV Server)
137+
suspend fun setFileAccessEnabled(enabled: Boolean)
138+
fun isFileAccessEnabled(): Flow<Boolean>
135139
}

app/src/main/java/com/sameerasw/airsync/presentation/ui/components/SettingsView.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.runtime.Composable
3838
import androidx.compose.ui.Alignment
3939
import androidx.compose.ui.Modifier
4040
import androidx.compose.ui.platform.LocalHapticFeedback
41+
import androidx.compose.ui.res.stringResource
4142
import androidx.compose.ui.unit.dp
4243
import com.sameerasw.airsync.R
4344
import com.sameerasw.airsync.domain.model.DeviceInfo
@@ -242,6 +243,16 @@ fun SettingsView(
242243
viewModel.setQuickShareEnabled(context, enabled)
243244
}
244245
)
246+
247+
IconToggleItem(
248+
title = stringResource(R.string.label_file_access),
249+
description = stringResource(R.string.subtitle_file_access),
250+
iconRes = R.drawable.rounded_folder_managed_24,
251+
isChecked = uiState.isFileAccessEnabled,
252+
onCheckedChange = { enabled: Boolean ->
253+
viewModel.setFileAccessEnabled(context, enabled)
254+
}
255+
)
245256
}
246257
}
247258

app/src/main/java/com/sameerasw/airsync/presentation/viewmodel/AirSyncViewModel.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ class AirSyncViewModel(
184184
}
185185
}
186186

187+
// Observe File Access preference
188+
viewModelScope.launch {
189+
repository.isFileAccessEnabled().collect { enabled ->
190+
_uiState.value = _uiState.value.copy(isFileAccessEnabled = enabled)
191+
}
192+
}
193+
187194
// Observe BLE connection status
188195
viewModelScope.launch {
189196
com.sameerasw.airsync.AirSyncApp.getBleConnectionManager()?.connectionState?.collect { state ->
@@ -691,6 +698,14 @@ class AirSyncViewModel(
691698
}
692699
}
693700

701+
fun setFileAccessEnabled(context: Context, enabled: Boolean) {
702+
_uiState.value = _uiState.value.copy(isFileAccessEnabled = enabled)
703+
viewModelScope.launch {
704+
repository.setFileAccessEnabled(enabled)
705+
ServiceManager.updateServiceState(context)
706+
}
707+
}
708+
694709
fun manualSyncAppIcons(context: Context) {
695710
_uiState.value = _uiState.value.copy(isIconSyncLoading = true, iconSyncMessage = "")
696711

app/src/main/java/com/sameerasw/airsync/service/AirSyncService.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ import kotlinx.coroutines.CoroutineScope
2828
import kotlinx.coroutines.Dispatchers
2929
import kotlinx.coroutines.Job
3030
import kotlinx.coroutines.cancel
31+
import kotlinx.coroutines.flow.combine
3132
import kotlinx.coroutines.flow.first
33+
import kotlinx.coroutines.launch
3234
import kotlinx.coroutines.runBlocking
3335

3436
/**
@@ -43,6 +45,7 @@ class AirSyncService : Service() {
4345
private var isScanning = false
4446

4547
private var webDavServer: WebDavServer? = null
48+
private var webDavJob: Job? = null
4649

4750
// Network state tracking
4851
private var networkCallback: ConnectivityManager.NetworkCallback? = null
@@ -119,6 +122,27 @@ class AirSyncService : Service() {
119122
webDavServer = null
120123
}
121124

125+
private fun monitorWebDavRequirements() {
126+
webDavJob?.cancel()
127+
webDavJob = scope.launch {
128+
val dataStoreManager = DataStoreManager.getInstance(applicationContext)
129+
combine(
130+
dataStoreManager.isFileAccessEnabled(),
131+
dataStoreManager.getLastConnectedDevice()
132+
) { isEnabled, device ->
133+
Log.d(TAG, "WebDAV flow evaluation: isEnabled=$isEnabled, isPlus=${device?.isPlus}")
134+
isEnabled && device?.isPlus == true
135+
}.collect { shouldStart ->
136+
Log.d(TAG, "WebDAV requirement state updated: shouldStart = $shouldStart")
137+
if (shouldStart) {
138+
startWebDavServer()
139+
} else {
140+
stopWebDavServer()
141+
}
142+
}
143+
}
144+
}
145+
122146
private fun handleAppForeground() {
123147
if (isScanning) {
124148
Log.d(TAG, "App in foreground, switching to ACTIVE discovery")
@@ -156,11 +180,13 @@ class AirSyncService : Service() {
156180
UDPDiscoveryManager.setDiscoveryMode(this, DiscoveryMode.PASSIVE)
157181

158182
WakeupService.startService(this)
159-
startWebDavServer()
183+
monitorWebDavRequirements()
160184
}
161185

162186
private fun stopSync() {
163187
Log.d(TAG, "Stopping AirSync foreground service")
188+
webDavJob?.cancel()
189+
webDavJob = null
164190
stopWebDavServer()
165191
ShortcutUtil.refreshShortcuts(this, false)
166192
UDPDiscoveryManager.stop(this)

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,6 @@
8989
<string name="setting_auto_reconnect_desc">Attempted when disconnected unexpectedly</string>
9090
<string name="setting_nearby_connection_title">Switch to Nearby</string>
9191
<string name="setting_nearby_connection_desc">Use Bluetooth LE if connection lost</string>
92+
<string name="label_file_access">File Access</string>
93+
<string name="subtitle_file_access">Mount storage in macOS Finder</string>
9294
</resources>

0 commit comments

Comments
 (0)