Skip to content
Open
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
79 changes: 29 additions & 50 deletions app/src/main/java/org/torproject/android/OrbotActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.WindowInsetsController
import androidx.activity.addCallback

import androidx.activity.addCallback
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
Expand All @@ -23,28 +23,29 @@ import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.navigation.NavController
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController

import com.google.android.material.bottomnavigation.BottomNavigationView
import com.scottyab.rootbeer.RootBeer

import org.torproject.android.service.util.sendIntentToService
import org.torproject.android.ui.core.BaseActivity
import org.torproject.android.service.OrbotConstants
import org.torproject.android.service.util.NavigationTarget
import org.torproject.android.ui.kindness.SnowflakeProxyService
import org.torproject.android.service.util.Prefs
import org.torproject.android.service.util.navigateTo
import org.torproject.android.service.util.showToast
import org.torproject.android.ui.connect.ConnectFragment
import org.torproject.android.ui.more.LogBottomSheet
import org.torproject.android.ui.connect.ConnectViewModel
import org.torproject.android.ui.connect.RequestPostNotificationPermission
import org.torproject.android.ui.core.DeviceAuthenticationPrompt
import org.torproject.android.ui.kindness.KindnessFragment
import org.torproject.android.ui.more.MoreFragment
import java.util.Locale

class OrbotActivity : BaseActivity() {

private lateinit var bottomNavigationView: BottomNavigationView
private lateinit var logBottomSheet: LogBottomSheet

var portSocks: Int = -1
Expand All @@ -59,6 +60,12 @@ class OrbotActivity : BaseActivity() {

private val connectViewModel: ConnectViewModel by viewModels()

private val tabDestinations = mapOf(
R.id.connectFragment to ConnectFragment::class,
R.id.kindnessFragment to KindnessFragment::class,
R.id.moreFragment to MoreFragment::class
)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
Expand Down Expand Up @@ -103,20 +110,15 @@ class OrbotActivity : BaseActivity() {
lastSelectedItemId = savedInstanceState.getInt(KEY_SELECTED_TAB, R.id.connectFragment)
previousReceivedTorStatus = savedInstanceState.getString(KEY_TOR_STATUS)

val navController = findNavController(R.id.nav_fragment)
val currentDest = navController.currentDestination?.id

if (currentDest != lastSelectedItemId) {
navController.navigate(lastSelectedItemId)
}
bottomNavigationView.selectedItemId = lastSelectedItemId

findViewById<BottomNavigationView>(R.id.bottom_navigation).selectedItemId =
lastSelectedItemId
switchToTab(lastSelectedItemId, true)
}

private fun createOrbot() {
setContentView(R.layout.activity_orbot)
rootLayout = findViewById(R.id.rootLayout)

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.nav_fragment)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
Expand All @@ -125,44 +127,12 @@ class OrbotActivity : BaseActivity() {

logBottomSheet = LogBottomSheet()

val navController: NavController = findNavController(R.id.nav_fragment)
val bottomNavigationView: BottomNavigationView = findViewById(R.id.bottom_navigation)
bottomNavigationView.setupWithNavController(navController)

bottomNavigationView = findViewById(R.id.bottom_navigation)
bottomNavigationView.selectedItemId = lastSelectedItemId

val navOptionsLeftToRight = NavOptions.Builder().setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left).setPopEnterAnim(R.anim.slide_in_right)
.setPopExitAnim(R.anim.slide_out_left).build()

val navOptionsRightToLeft = NavOptions.Builder().setEnterAnim(R.anim.slide_in_left)
.setExitAnim(R.anim.slide_out_right).setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right).build()

bottomNavigationView.setOnItemSelectedListener { item ->
if (item.itemId == lastSelectedItemId) {
return@setOnItemSelectedListener true
}

val navOptions = if (item.itemId > lastSelectedItemId) {
navOptionsLeftToRight
} else {
navOptionsRightToLeft
}

when (item.itemId) {
R.id.connectFragment -> navController.navigate(
R.id.connectFragment, null, navOptions
)

R.id.kindnessFragment -> navController.navigate(
R.id.kindnessFragment, null, navOptions
)

R.id.moreFragment -> navController.navigate(R.id.moreFragment, null, navOptions)
}

lastSelectedItemId = item.itemId
val forward = item.itemId > lastSelectedItemId
switchToTab(item.itemId, forward)
true
}

Expand Down Expand Up @@ -196,6 +166,16 @@ class OrbotActivity : BaseActivity() {
}
}

private fun switchToTab(itemId: Int, isForward: Boolean) {
val target = tabDestinations[itemId] ?: return
navigateTo(
target = NavigationTarget.FragmentTarget(target),
animateTransition = true,
isForward = isForward
)
lastSelectedItemId = itemId
}

private fun requestNotificationPermission() {
// automatically granted on Android 12 and lower
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
Expand Down Expand Up @@ -249,7 +229,6 @@ class OrbotActivity : BaseActivity() {
sendIntentToService(OrbotConstants.CMD_ACTIVE)
if (Prefs.beSnowflakeProxy())
SnowflakeProxyService.startSnowflakeProxyForegroundService(this)

}

override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.torproject.android.service.util

import android.content.Intent

import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity

import org.torproject.android.R

import kotlin.reflect.KClass

sealed class NavigationTarget {
data class FragmentTarget(val fragmentClass: KClass<out Fragment>) : NavigationTarget()
data class ActivityTarget(val activityClass: KClass<out ComponentActivity>) : NavigationTarget()
}

fun FragmentActivity.navigateTo(
target: NavigationTarget,
addToBackStack: Boolean = true,
animateTransition: Boolean = false,
isForward: Boolean = true,
finishCurrent: Boolean = false,
containerId: Int = R.id.nav_fragment
) {
when (target) {
is NavigationTarget.FragmentTarget -> {
val fragment = target.fragmentClass.java.getDeclaredConstructor().newInstance()
val tx = supportFragmentManager.beginTransaction()

if (animateTransition) {
val animIn = if (isForward) R.anim.slide_in_right else R.anim.slide_in_left
val animOut = if (isForward) R.anim.slide_out_left else R.anim.slide_out_right
val popIn = if (isForward) R.anim.slide_in_left else R.anim.slide_in_right
val popOut = if (isForward) R.anim.slide_out_right else R.anim.slide_out_left

tx.setCustomAnimations(animIn, animOut, popIn, popOut)
}

tx.replace(containerId, fragment, target.fragmentClass.simpleName)

if (addToBackStack) {
tx.addToBackStack(target.fragmentClass.simpleName)
}

tx.commit()
}

is NavigationTarget.ActivityTarget -> {
val intent = Intent(this, target.activityClass.java)
startActivity(intent)
if (finishCurrent) finish()
}
}
}

fun Fragment.navigateTo(
target: NavigationTarget,
addToBackStack: Boolean = true,
animateTransition: Boolean = false,
isForward: Boolean = true,
finishCurrent: Boolean = false,
containerId: Int = R.id.nav_fragment
) {
requireActivity().navigateTo(
target = target,
addToBackStack = addToBackStack,
animateTransition = animateTransition,
isForward = isForward,
finishCurrent = finishCurrent,
containerId = containerId
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.widget.Toolbar
import org.torproject.android.R
import org.torproject.android.service.util.NavigationTarget
import org.torproject.android.service.util.navigateTo
import org.torproject.android.ui.core.BaseActivity

class SettingsActivity : BaseActivity() {
Expand All @@ -12,18 +14,18 @@ class SettingsActivity : BaseActivity() {
setTitle(R.string.menu_settings)
setContentView(R.layout.activity_settings)

var toolbar = findViewById<Toolbar>(R.id.toolbar);
setSupportActionBar(toolbar);
var sab = getSupportActionBar();
if (sab != null) sab.setDisplayHomeAsUpEnabled(true);
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)

supportFragmentManager
.beginTransaction()
.replace(R.id.settings_container, SettingsPreferenceFragment())
.commit()
navigateTo(
target = NavigationTarget.FragmentTarget(SettingsPreferenceFragment::class),
addToBackStack = false,
animateTransition = true,
containerId = R.id.settings_container
)
}


override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
if (supportFragmentManager.backStackEntryCount > 0)
Expand Down
8 changes: 2 additions & 6 deletions app/src/main/res/layout/activity_orbot.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,14 @@
android:background="@drawable/bg_gradient"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<fragment
<FrameLayout
android:id="@+id/nav_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/floating_bottom_nav"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_bias="0"
app:navGraph="@navigation/nav_graph" />
app:layout_constraintStart_toStartOf="parent" />

<include
android:id="@+id/floating_bottom_nav"
Expand Down
23 changes: 0 additions & 23 deletions app/src/main/res/navigation/nav_graph.xml

This file was deleted.