Dan Ballard pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android

Commits:

2 changed files:

Changes:

  • fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsComposeFragment.kt
    ... ... @@ -23,13 +23,19 @@ import androidx.compose.material.Icon
    23 23
     import androidx.compose.material.Scaffold
    
    24 24
     import androidx.compose.material.Text
    
    25 25
     import androidx.compose.runtime.Composable
    
    26
    +import androidx.compose.runtime.DisposableEffect
    
    27
    +import androidx.compose.runtime.LaunchedEffect
    
    26 28
     import androidx.compose.runtime.Stable
    
    29
    +import androidx.compose.runtime.mutableStateOf
    
    30
    +import androidx.compose.runtime.remember
    
    27 31
     import androidx.compose.ui.Modifier
    
    28 32
     import androidx.compose.ui.platform.ComposeView
    
    33
    +import androidx.compose.ui.platform.LocalLifecycleOwner
    
    29 34
     import androidx.compose.ui.res.painterResource
    
    30 35
     import androidx.compose.ui.unit.dp
    
    31 36
     import androidx.fragment.app.Fragment
    
    32 37
     import androidx.fragment.app.viewModels
    
    38
    +import androidx.lifecycle.Observer
    
    33 39
     import mozilla.components.ui.colors.PhotonColors
    
    34 40
     import org.mozilla.fenix.R
    
    35 41
     
    
    ... ... @@ -53,17 +59,37 @@ class TorLogsComposeFragment : Fragment() {
    53 59
     
    
    54 60
         @Composable
    
    55 61
         private fun TorLogs(paddingValues: PaddingValues) {
    
    62
    +        val torLogsState = remember { mutableStateOf<List<TorLog>>(emptyList()) }
    
    63
    +        val lifecycleOwner = LocalLifecycleOwner.current
    
    64
    +        val scrollState = rememberScrollState()
    
    65
    +
    
    66
    +        DisposableEffect(viewModel.torLogs(), lifecycleOwner) {
    
    67
    +            val observer = Observer<List<TorLog>> { logs ->
    
    68
    +                torLogsState.value = logs
    
    69
    +            }
    
    70
    +            viewModel.torLogs().observe(lifecycleOwner, observer)
    
    71
    +            onDispose {
    
    72
    +                viewModel.torLogs().removeObserver(observer)
    
    73
    +            }
    
    74
    +        }
    
    75
    +
    
    76
    +        val torLogs = torLogsState.value
    
    77
    +
    
    78
    +        LaunchedEffect(torLogs) {
    
    79
    +            scrollState.animateScrollTo(scrollState.maxValue)
    
    80
    +        }
    
    81
    +
    
    56 82
             SelectionContainer {
    
    57 83
                 Column(
    
    58 84
                     // Column instead of LazyColumn so that you can select all the logs, and not just one "screen" at a time
    
    59 85
                     // The logs won't be too big so loading them all instead of just whats visible shouldn't be a big deal
    
    60 86
                     modifier = Modifier
    
    61 87
                         .fillMaxSize()
    
    62
    -                    .verticalScroll(state = rememberScrollState(), reverseScrolling = true)
    
    88
    +                    .verticalScroll(scrollState)
    
    63 89
                         .padding(paddingValues)
    
    64 90
                         .background(PhotonColors.Ink50), // Standard background color
    
    65 91
                 ) {
    
    66
    -                for (log in viewModel.torLogs) {
    
    92
    +                for (log in torLogs) {
    
    67 93
                         LogRow(log = log)
    
    68 94
                     }
    
    69 95
                 }
    

  • fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsViewModel.kt
    ... ... @@ -12,6 +12,8 @@ import android.os.Build
    12 12
     import android.widget.Toast
    
    13 13
     import androidx.compose.runtime.Stable
    
    14 14
     import androidx.lifecycle.AndroidViewModel
    
    15
    +import androidx.lifecycle.LiveData
    
    16
    +import androidx.lifecycle.MutableLiveData
    
    15 17
     import org.mozilla.fenix.R
    
    16 18
     import org.mozilla.fenix.ext.components
    
    17 19
     import java.sql.Timestamp
    
    ... ... @@ -21,12 +23,18 @@ class TorLogsViewModel(application: Application) : AndroidViewModel(application)
    21 23
         private val clipboardManager =
    
    22 24
             application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    
    23 25
     
    
    24
    -    val torLogs: MutableList<TorLog> = mutableListOf(
    
    25
    -        TorLog(
    
    26
    -            "---------------" + application.getString(R.string.tor_initializing_log) + "---------------",
    
    27
    -        ),
    
    26
    +    private val _torLogs: MutableLiveData<List<TorLog>> = MutableLiveData(
    
    27
    +        mutableListOf(TorLog("---------------" + application.getString(R.string.tor_initializing_log) + "---------------")),
    
    28 28
         )
    
    29 29
     
    
    30
    +    fun torLogs(): LiveData<List<TorLog>> {
    
    31
    +        return _torLogs
    
    32
    +    }
    
    33
    +
    
    34
    +    private fun addLog(log: TorLog) {
    
    35
    +        _torLogs.value = _torLogs.value?.plus(log) ?: return
    
    36
    +    }
    
    37
    +
    
    30 38
         init {
    
    31 39
             setupClipboardListener()
    
    32 40
             torController.registerTorLogListener(this)
    
    ... ... @@ -34,14 +42,16 @@ class TorLogsViewModel(application: Application) : AndroidViewModel(application)
    34 42
                 .filter { !(it.second!!.startsWith("Circuit") && it.first == "ON") }
    
    35 43
                 // Keep synchronized with format in onTorStatusUpdate
    
    36 44
                 .flatMap { listOf(TorLog("[${it.first}] ${it.second}")) }
    
    37
    -        torLogs.addAll(currentEntries)
    
    45
    +        for (log in currentEntries) {
    
    46
    +            addLog(log)
    
    47
    +        }
    
    38 48
         }
    
    39 49
     
    
    40 50
         override fun onLog(type: String?, message: String?) {
    
    41 51
             if (message == null || type == null) return
    
    42 52
             if (type == "ON" && type.startsWith("Circuit")) return
    
    43 53
     
    
    44
    -        torLogs.add(TorLog("[$type] $message"))
    
    54
    +        addLog(TorLog("[$type] $message"))
    
    45 55
         }
    
    46 56
     
    
    47 57
         override fun onCleared() {
    
    ... ... @@ -74,7 +84,8 @@ class TorLogsViewModel(application: Application) : AndroidViewModel(application)
    74 84
     
    
    75 85
         private fun getAllTorLogs(): String {
    
    76 86
             var ret = ""
    
    77
    -        for (log in torLogs) {
    
    87
    +        for (log in torLogs().value
    
    88
    +            ?: return getApplication<Application>().getString(R.string.default_error_msg)) {
    
    78 89
                 ret += log.text + '\n'
    
    79 90
             }
    
    80 91
             return ret