mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 19:36:37 +02:00
Adds privacy presets for Tor Settings
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.tor
|
||||
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
@@ -41,6 +42,27 @@ class TorDialogViewModel : ViewModel() {
|
||||
val nip05VerificationsViaTor = mutableStateOf(false)
|
||||
val nip96UploadsViaTor = mutableStateOf(false)
|
||||
|
||||
val preset =
|
||||
derivedStateOf {
|
||||
whichPreset(
|
||||
TorSettings(
|
||||
torType = TorType.INTERNAL,
|
||||
externalSocksPort = -1,
|
||||
onionRelaysViaTor = onionRelaysViaTor.value,
|
||||
dmRelaysViaTor = dmRelaysViaTor.value,
|
||||
newRelaysViaTor = newRelaysViaTor.value,
|
||||
trustedRelaysViaTor = trustedRelaysViaTor.value,
|
||||
urlPreviewsViaTor = urlPreviewsViaTor.value,
|
||||
profilePicsViaTor = profilePicsViaTor.value,
|
||||
imagesViaTor = imagesViaTor.value,
|
||||
videosViaTor = videosViaTor.value,
|
||||
moneyOperationsViaTor = moneyOperationsViaTor.value,
|
||||
nip05VerificationsViaTor = nip05VerificationsViaTor.value,
|
||||
nip96UploadsViaTor = nip96UploadsViaTor.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun reset(torSettings: TorSettings) {
|
||||
torType.value = torSettings.torType
|
||||
socksPortStr.value = torSettings.externalSocksPort.toString()
|
||||
@@ -73,4 +95,28 @@ class TorDialogViewModel : ViewModel() {
|
||||
nip05VerificationsViaTor = nip05VerificationsViaTor.value,
|
||||
nip96UploadsViaTor = nip96UploadsViaTor.value,
|
||||
)
|
||||
|
||||
fun setPreset(preset: TorPresetType) {
|
||||
when (preset) {
|
||||
TorPresetType.DEFAULT -> resetOnlyFlags(torDefaultPreset)
|
||||
TorPresetType.ONLY_WHEN_NEEDED -> resetOnlyFlags(torOnlyWhenNeededPreset)
|
||||
TorPresetType.SMALL_PAYLOADS -> resetOnlyFlags(torSmallPayloadsPreset)
|
||||
TorPresetType.FULL_PRIVACY -> resetOnlyFlags(torFullyPrivate)
|
||||
TorPresetType.CUSTOM -> { }
|
||||
}
|
||||
}
|
||||
|
||||
fun resetOnlyFlags(torSettings: TorSettings) {
|
||||
onionRelaysViaTor.value = torSettings.onionRelaysViaTor
|
||||
dmRelaysViaTor.value = torSettings.dmRelaysViaTor
|
||||
newRelaysViaTor.value = torSettings.newRelaysViaTor
|
||||
trustedRelaysViaTor.value = torSettings.trustedRelaysViaTor
|
||||
urlPreviewsViaTor.value = torSettings.urlPreviewsViaTor
|
||||
profilePicsViaTor.value = torSettings.profilePicsViaTor
|
||||
imagesViaTor.value = torSettings.imagesViaTor
|
||||
videosViaTor.value = torSettings.videosViaTor
|
||||
moneyOperationsViaTor.value = torSettings.moneyOperationsViaTor
|
||||
nip05VerificationsViaTor.value = torSettings.nip05VerificationsViaTor
|
||||
nip96UploadsViaTor.value = torSettings.nip96UploadsViaTor
|
||||
}
|
||||
}
|
||||
|
@@ -56,3 +56,107 @@ fun parseTorType(code: Int?): TorType =
|
||||
TorType.INTERNAL
|
||||
}
|
||||
}
|
||||
|
||||
enum class TorPresetType(
|
||||
val screenCode: Int,
|
||||
val resourceId: Int,
|
||||
val explainerId: Int,
|
||||
) {
|
||||
ONLY_WHEN_NEEDED(0, R.string.tor_when_needed, R.string.tor_when_needed_explainer),
|
||||
DEFAULT(1, R.string.tor_default, R.string.tor_default_explainer),
|
||||
SMALL_PAYLOADS(2, R.string.tor_small_payloads, R.string.tor_small_payloads_explainer),
|
||||
FULL_PRIVACY(3, R.string.tor_full_privacy, R.string.tor_full_privacy_explainer),
|
||||
CUSTOM(4, R.string.tor_custom, R.string.tor_custom_explainer),
|
||||
}
|
||||
|
||||
fun parseTorPresetType(code: Int?): TorPresetType =
|
||||
when (code) {
|
||||
TorPresetType.ONLY_WHEN_NEEDED.screenCode -> TorPresetType.ONLY_WHEN_NEEDED
|
||||
TorPresetType.DEFAULT.screenCode -> TorPresetType.DEFAULT
|
||||
TorPresetType.SMALL_PAYLOADS.screenCode -> TorPresetType.SMALL_PAYLOADS
|
||||
TorPresetType.FULL_PRIVACY.screenCode -> TorPresetType.FULL_PRIVACY
|
||||
else -> {
|
||||
TorPresetType.CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
fun isPreset(
|
||||
torSettings: TorSettings,
|
||||
preset: TorSettings,
|
||||
): Boolean =
|
||||
torSettings.onionRelaysViaTor == preset.onionRelaysViaTor &&
|
||||
torSettings.dmRelaysViaTor == preset.dmRelaysViaTor &&
|
||||
torSettings.newRelaysViaTor == preset.newRelaysViaTor &&
|
||||
torSettings.trustedRelaysViaTor == preset.trustedRelaysViaTor &&
|
||||
torSettings.urlPreviewsViaTor == preset.urlPreviewsViaTor &&
|
||||
// torSettings.profilePicsViaTor == preset.profilePicsViaTor &&
|
||||
torSettings.imagesViaTor == preset.imagesViaTor &&
|
||||
torSettings.videosViaTor == preset.videosViaTor &&
|
||||
torSettings.moneyOperationsViaTor == preset.moneyOperationsViaTor &&
|
||||
torSettings.nip05VerificationsViaTor == preset.nip05VerificationsViaTor &&
|
||||
torSettings.nip96UploadsViaTor == preset.nip96UploadsViaTor
|
||||
|
||||
fun whichPreset(torSettings: TorSettings): TorPresetType {
|
||||
if (isPreset(torSettings, torOnlyWhenNeededPreset)) return TorPresetType.ONLY_WHEN_NEEDED
|
||||
if (isPreset(torSettings, torDefaultPreset)) return TorPresetType.DEFAULT
|
||||
if (isPreset(torSettings, torSmallPayloadsPreset)) return TorPresetType.SMALL_PAYLOADS
|
||||
if (isPreset(torSettings, torFullyPrivate)) return TorPresetType.FULL_PRIVACY
|
||||
return TorPresetType.CUSTOM
|
||||
}
|
||||
|
||||
val torOnlyWhenNeededPreset =
|
||||
TorSettings(
|
||||
onionRelaysViaTor = true,
|
||||
dmRelaysViaTor = false,
|
||||
newRelaysViaTor = false,
|
||||
trustedRelaysViaTor = false,
|
||||
urlPreviewsViaTor = false,
|
||||
profilePicsViaTor = false,
|
||||
imagesViaTor = false,
|
||||
videosViaTor = false,
|
||||
moneyOperationsViaTor = false,
|
||||
nip05VerificationsViaTor = false,
|
||||
nip96UploadsViaTor = false,
|
||||
)
|
||||
val torDefaultPreset =
|
||||
TorSettings(
|
||||
onionRelaysViaTor = true,
|
||||
dmRelaysViaTor = true,
|
||||
newRelaysViaTor = true,
|
||||
trustedRelaysViaTor = false,
|
||||
urlPreviewsViaTor = false,
|
||||
profilePicsViaTor = false,
|
||||
imagesViaTor = false,
|
||||
videosViaTor = false,
|
||||
moneyOperationsViaTor = false,
|
||||
nip05VerificationsViaTor = false,
|
||||
nip96UploadsViaTor = false,
|
||||
)
|
||||
val torSmallPayloadsPreset =
|
||||
TorSettings(
|
||||
onionRelaysViaTor = true,
|
||||
dmRelaysViaTor = true,
|
||||
newRelaysViaTor = true,
|
||||
trustedRelaysViaTor = true,
|
||||
urlPreviewsViaTor = true,
|
||||
profilePicsViaTor = true,
|
||||
imagesViaTor = false,
|
||||
videosViaTor = false,
|
||||
moneyOperationsViaTor = true,
|
||||
nip05VerificationsViaTor = true,
|
||||
nip96UploadsViaTor = false,
|
||||
)
|
||||
val torFullyPrivate =
|
||||
TorSettings(
|
||||
onionRelaysViaTor = true,
|
||||
dmRelaysViaTor = true,
|
||||
newRelaysViaTor = true,
|
||||
trustedRelaysViaTor = true,
|
||||
urlPreviewsViaTor = true,
|
||||
profilePicsViaTor = true,
|
||||
imagesViaTor = true,
|
||||
videosViaTor = true,
|
||||
moneyOperationsViaTor = true,
|
||||
nip05VerificationsViaTor = true,
|
||||
nip96UploadsViaTor = true,
|
||||
)
|
||||
|
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.actions.SaveButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size15dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
@@ -93,7 +93,7 @@ fun TorDialogContentsPreview() {
|
||||
onClose = {},
|
||||
onPost = { },
|
||||
onError = {},
|
||||
torSettings = TorSettings(),
|
||||
torSettings = TorSettings(torType = TorType.EXTERNAL),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,22 @@ fun TorDialogContents(
|
||||
onClose: () -> Unit,
|
||||
onPost: (torSettings: TorSettings) -> Unit,
|
||||
onError: (String) -> Unit,
|
||||
) {
|
||||
val dialogViewModel = viewModel<TorDialogViewModel>()
|
||||
|
||||
LaunchedEffect(dialogViewModel, torSettings) {
|
||||
dialogViewModel.reset(torSettings)
|
||||
}
|
||||
|
||||
TorDialogContents(dialogViewModel, onClose, onPost, onError)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TorDialogContents(
|
||||
dialogViewModel: TorDialogViewModel,
|
||||
onClose: () -> Unit,
|
||||
onPost: (torSettings: TorSettings) -> Unit,
|
||||
onError: (String) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier =
|
||||
@@ -113,12 +129,6 @@ fun TorDialogContents(
|
||||
rememberScrollState(),
|
||||
).padding(10.dp),
|
||||
) {
|
||||
val dialogViewModel = viewModel<TorDialogViewModel>()
|
||||
|
||||
LaunchedEffect(dialogViewModel, torSettings) {
|
||||
dialogViewModel.reset(torSettings)
|
||||
}
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@@ -142,8 +152,8 @@ fun TorDialogContents(
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 10.dp, horizontal = 5.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(Size15dp),
|
||||
modifier = Modifier.padding(horizontal = 5.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(Size10dp),
|
||||
) {
|
||||
SettingsRow(
|
||||
R.string.use_internal_tor,
|
||||
@@ -182,75 +192,99 @@ fun TorDialogContents(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_onion_address,
|
||||
R.string.tor_use_onion_address_explainer,
|
||||
dialogViewModel.onionRelaysViaTor,
|
||||
)
|
||||
AnimatedVisibility(
|
||||
visible = dialogViewModel.torType.value != TorType.OFF,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 5.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(Size10dp),
|
||||
) {
|
||||
SettingsRow(
|
||||
R.string.tor_preset,
|
||||
R.string.tor_preset_explainer,
|
||||
persistentListOf(
|
||||
TitleExplainer(stringRes(TorPresetType.ONLY_WHEN_NEEDED.resourceId), stringRes(TorPresetType.ONLY_WHEN_NEEDED.explainerId)),
|
||||
TitleExplainer(stringRes(TorPresetType.DEFAULT.resourceId), stringRes(TorPresetType.DEFAULT.explainerId)),
|
||||
TitleExplainer(stringRes(TorPresetType.SMALL_PAYLOADS.resourceId), stringRes(TorPresetType.SMALL_PAYLOADS.explainerId)),
|
||||
TitleExplainer(stringRes(TorPresetType.FULL_PRIVACY.resourceId), stringRes(TorPresetType.FULL_PRIVACY.explainerId)),
|
||||
TitleExplainer(stringRes(TorPresetType.CUSTOM.resourceId), stringRes(TorPresetType.CUSTOM.explainerId)),
|
||||
),
|
||||
dialogViewModel.preset.value.screenCode,
|
||||
) {
|
||||
dialogViewModel.setPreset(parseTorPresetType(it))
|
||||
}
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_dm_relays,
|
||||
R.string.tor_use_dm_relays_explainer,
|
||||
dialogViewModel.dmRelaysViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_onion_address,
|
||||
R.string.tor_use_onion_address_explainer,
|
||||
dialogViewModel.onionRelaysViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_new_relays,
|
||||
R.string.tor_use_new_relays_explainer,
|
||||
dialogViewModel.newRelaysViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_dm_relays,
|
||||
R.string.tor_use_dm_relays_explainer,
|
||||
dialogViewModel.dmRelaysViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_trusted_relays,
|
||||
R.string.tor_use_trusted_relays_explainer,
|
||||
dialogViewModel.trustedRelaysViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_new_relays,
|
||||
R.string.tor_use_new_relays_explainer,
|
||||
dialogViewModel.newRelaysViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_money_operations,
|
||||
R.string.tor_use_money_operations_explainer,
|
||||
dialogViewModel.moneyOperationsViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_trusted_relays,
|
||||
R.string.tor_use_trusted_relays_explainer,
|
||||
dialogViewModel.trustedRelaysViaTor,
|
||||
)
|
||||
|
||||
/**
|
||||
* Too hard to separate Coil into regular images and profile pics
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_profile_pictures,
|
||||
R.string.tor_use_profile_pictures_explainer,
|
||||
dialogViewModel.profilePicsViaTor,
|
||||
)
|
||||
*/
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_money_operations,
|
||||
R.string.tor_use_money_operations_explainer,
|
||||
dialogViewModel.moneyOperationsViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_nip05_verification,
|
||||
R.string.tor_use_nip05_verification_explainer,
|
||||
dialogViewModel.nip05VerificationsViaTor,
|
||||
)
|
||||
/**
|
||||
* Too hard to separate Coil into regular images and profile pics
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_profile_pictures,
|
||||
R.string.tor_use_profile_pictures_explainer,
|
||||
dialogViewModel.profilePicsViaTor,
|
||||
)
|
||||
*/
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_url_previews,
|
||||
R.string.tor_use_url_previews_explainer,
|
||||
dialogViewModel.urlPreviewsViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_nip05_verification,
|
||||
R.string.tor_use_nip05_verification_explainer,
|
||||
dialogViewModel.nip05VerificationsViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_images,
|
||||
R.string.tor_use_images_explainer,
|
||||
dialogViewModel.imagesViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_url_previews,
|
||||
R.string.tor_use_url_previews_explainer,
|
||||
dialogViewModel.urlPreviewsViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_videos,
|
||||
R.string.tor_use_videos_explainer,
|
||||
dialogViewModel.videosViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_images,
|
||||
R.string.tor_use_images_explainer,
|
||||
dialogViewModel.imagesViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_nip96_uploads,
|
||||
R.string.tor_use_nip96_uploads_explainer,
|
||||
dialogViewModel.nip96UploadsViaTor,
|
||||
)
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_videos,
|
||||
R.string.tor_use_videos_explainer,
|
||||
dialogViewModel.videosViaTor,
|
||||
)
|
||||
|
||||
SwitchSettingsRow(
|
||||
R.string.tor_use_nip96_uploads,
|
||||
R.string.tor_use_nip96_uploads_explainer,
|
||||
dialogViewModel.nip96UploadsViaTor,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -433,6 +433,9 @@
|
||||
<string name="use_internal_tor">Active Tor Engine</string>
|
||||
<string name="use_internal_tor_explainer">Use the internal version or Orbot</string>
|
||||
|
||||
<string name="tor_preset">Tor/Privacy Presets</string>
|
||||
<string name="tor_preset_explainer">Quickly modify all settings below</string>
|
||||
|
||||
<string name="tor_use_onion_address">Onion Url/Relays</string>
|
||||
<string name="tor_use_onion_address_explainer">Use Tor for any .onion url</string>
|
||||
|
||||
@@ -470,6 +473,18 @@
|
||||
<string name="tor_external">Orbot</string>
|
||||
<string name="tor_off">Off</string>
|
||||
|
||||
<string name="tor_when_needed">Basic</string>
|
||||
<string name="tor_default">Default</string>
|
||||
<string name="tor_small_payloads">All but Media</string>
|
||||
<string name="tor_full_privacy">Full Privacy</string>
|
||||
<string name="tor_custom">Custom</string>
|
||||
|
||||
<string name="tor_when_needed_explainer">Use Tor when it\'s required by the server</string>
|
||||
<string name="tor_default_explainer">Hide your IP from random relays</string>
|
||||
<string name="tor_small_payloads_explainer">Hide your IP from everything, but images and videos</string>
|
||||
<string name="tor_full_privacy_explainer">Hide your IP in all connections</string>
|
||||
<string name="tor_custom_explainer">Make your own</string>
|
||||
|
||||
<string name="invalid_port_number">Invalid port number</string>
|
||||
<string name="use_orbot">Use Orbot</string>
|
||||
<string name="disconnect_from_your_orbot_setup">Disconnect Tor/Orbot</string>
|
||||
|
Reference in New Issue
Block a user