Skip to content

Commit 1375a46

Browse files
committed
feat: add export as amnezia or wg
1 parent f52efd9 commit 1375a46

File tree

4 files changed

+81
-9
lines changed

4 files changed

+81
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.zaneschepke.wireguardautotunnel.domain.enums
2+
3+
enum class ConfigType {
4+
AMNEZIA,
5+
WG,
6+
}

app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt

+58-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import androidx.compose.foundation.focusable
55
import androidx.compose.foundation.interaction.MutableInteractionSource
66
import androidx.compose.foundation.layout.Arrangement
77
import androidx.compose.foundation.layout.Column
8-
import androidx.compose.foundation.layout.ExperimentalLayoutApi
8+
import androidx.compose.foundation.layout.Row
99
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.foundation.layout.fillMaxWidth
1011
import androidx.compose.foundation.layout.imePadding
1112
import androidx.compose.foundation.layout.padding
1213
import androidx.compose.foundation.layout.systemBarsPadding
@@ -15,6 +16,7 @@ import androidx.compose.foundation.verticalScroll
1516
import androidx.compose.material.icons.Icons
1617
import androidx.compose.material.icons.automirrored.outlined.ViewQuilt
1718
import androidx.compose.material.icons.filled.AppShortcut
19+
import androidx.compose.material.icons.filled.FolderZip
1820
import androidx.compose.material.icons.outlined.Bolt
1921
import androidx.compose.material.icons.outlined.Code
2022
import androidx.compose.material.icons.outlined.FolderZip
@@ -23,7 +25,11 @@ import androidx.compose.material.icons.outlined.Pin
2325
import androidx.compose.material.icons.outlined.Restore
2426
import androidx.compose.material.icons.outlined.VpnKeyOff
2527
import androidx.compose.material.icons.outlined.VpnLock
28+
import androidx.compose.material3.ExperimentalMaterial3Api
29+
import androidx.compose.material3.HorizontalDivider
30+
import androidx.compose.material3.Icon
2631
import androidx.compose.material3.MaterialTheme
32+
import androidx.compose.material3.ModalBottomSheet
2733
import androidx.compose.material3.Text
2834
import androidx.compose.runtime.Composable
2935
import androidx.compose.runtime.getValue
@@ -38,6 +44,7 @@ import androidx.compose.ui.res.stringResource
3844
import androidx.compose.ui.unit.dp
3945
import androidx.hilt.navigation.compose.hiltViewModel
4046
import com.zaneschepke.wireguardautotunnel.R
47+
import com.zaneschepke.wireguardautotunnel.domain.enums.ConfigType
4148
import com.zaneschepke.wireguardautotunnel.ui.state.AppUiState
4249
import com.zaneschepke.wireguardautotunnel.viewmodel.AppViewModel
4350
import com.zaneschepke.wireguardautotunnel.ui.Route
@@ -56,7 +63,7 @@ import com.zaneschepke.wireguardautotunnel.util.extensions.showToast
5663
import com.zaneschepke.wireguardautotunnel.viewmodel.SettingsViewModel
5764
import xyz.teamgravity.pin_lock_compose.PinManager
5865

59-
@OptIn(ExperimentalLayoutApi::class)
66+
@OptIn(ExperimentalMaterial3Api::class)
6067
@Composable
6168
fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel(), appViewModel: AppViewModel, uiState: AppUiState) {
6269
val context = LocalContext.current
@@ -68,11 +75,13 @@ fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel(), appViewModel:
6875
val interactionSource = remember { MutableInteractionSource() }
6976
var showAuthPrompt by remember { mutableStateOf(false) }
7077

78+
var showExportSheet by remember { mutableStateOf(false) }
79+
7180
if (showAuthPrompt) {
7281
AuthorizationPrompt(
7382
onSuccess = {
7483
showAuthPrompt = false
75-
viewModel.exportAllConfigs(context)
84+
showExportSheet = true
7685
},
7786
onError = { _ ->
7887
showAuthPrompt = false
@@ -89,6 +98,52 @@ fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel(), appViewModel:
8998
)
9099
}
91100

101+
if (showExportSheet) {
102+
ModalBottomSheet(onDismissRequest = { showExportSheet = false }) {
103+
Row(
104+
modifier =
105+
Modifier
106+
.fillMaxWidth()
107+
.clickable {
108+
showExportSheet = false
109+
viewModel.exportAllConfigs(context, ConfigType.AMNEZIA)
110+
}
111+
.padding(10.dp),
112+
) {
113+
Icon(
114+
Icons.Filled.FolderZip,
115+
contentDescription = stringResource(id = R.string.export_amnezia),
116+
modifier = Modifier.padding(10.dp),
117+
)
118+
Text(
119+
stringResource(id = R.string.export_amnezia),
120+
modifier = Modifier.padding(10.dp),
121+
)
122+
}
123+
HorizontalDivider()
124+
Row(
125+
modifier =
126+
Modifier
127+
.fillMaxWidth()
128+
.clickable {
129+
showExportSheet = false
130+
viewModel.exportAllConfigs(context, ConfigType.WG)
131+
}
132+
.padding(10.dp),
133+
) {
134+
Icon(
135+
Icons.Filled.FolderZip,
136+
contentDescription = stringResource(id = R.string.export_wireguard),
137+
modifier = Modifier.padding(10.dp),
138+
)
139+
Text(
140+
stringResource(id = R.string.export_wireguard),
141+
modifier = Modifier.padding(10.dp),
142+
)
143+
}
144+
}
145+
}
146+
92147
Column(
93148
horizontalAlignment = Alignment.Start,
94149
verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.Top),

app/src/main/java/com/zaneschepke/wireguardautotunnel/viewmodel/SettingsViewModel.kt

+15-6
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import androidx.core.content.FileProvider
55
import androidx.lifecycle.ViewModel
66
import androidx.lifecycle.viewModelScope
77
import com.zaneschepke.wireguardautotunnel.R
8+
import com.zaneschepke.wireguardautotunnel.domain.enums.ConfigType
89
import com.zaneschepke.wireguardautotunnel.domain.repository.AppDataRepository
910
import com.zaneschepke.wireguardautotunnel.util.FileUtils
1011
import com.zaneschepke.wireguardautotunnel.util.extensions.launchShareFile
1112
import dagger.hilt.android.lifecycle.HiltViewModel
1213
import kotlinx.coroutines.launch
14+
import timber.log.Timber
1315
import java.time.Instant
1416
import javax.inject.Inject
1517

@@ -21,16 +23,23 @@ constructor(
2123
private val fileUtils: FileUtils,
2224
) : ViewModel() {
2325

24-
fun exportAllConfigs(context: Context) = viewModelScope.launch {
26+
fun exportAllConfigs(context: Context, configType: ConfigType) = viewModelScope.launch {
2527
runCatching {
26-
val shareFile = fileUtils.createNewShareFile("wg-export_${Instant.now().epochSecond}.zip")
2728
val tunnels = appDataRepository.tunnels.getAll()
28-
val wgFiles = fileUtils.createWgFiles(tunnels)
29-
val amFiles = fileUtils.createAmFiles(tunnels)
30-
val allFiles = wgFiles + amFiles
31-
fileUtils.zipAll(shareFile, allFiles)
29+
val (files, shareFileName) = when (configType) {
30+
ConfigType.AMNEZIA -> {
31+
Pair(fileUtils.createAmFiles(tunnels), "am-export_${Instant.now().epochSecond}.zip")
32+
}
33+
ConfigType.WG -> {
34+
Pair(fileUtils.createWgFiles(tunnels), "wg-export_${Instant.now().epochSecond}.zip")
35+
}
36+
}
37+
val shareFile = fileUtils.createNewShareFile(shareFileName)
38+
fileUtils.zipAll(shareFile, files)
3239
val uri = FileProvider.getUriForFile(context, context.getString(R.string.provider), shareFile)
3340
context.launchShareFile(uri)
41+
}.onFailure {
42+
Timber.e(it)
3443
}
3544
}
3645
}

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

+2
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,6 @@
213213
<string name="unauthorized">Failed to start tunnel, unauthorized.</string>
214214
<string name="tunne_start_failed_title">Tunnel failure</string>
215215
<string name="multiple">Multiple</string>
216+
<string name="export_amnezia">Export as Amnezia</string>
217+
<string name="export_wireguard">Export as WireGuard</string>
216218
</resources>

0 commit comments

Comments
 (0)