OXYGENHUB
◆ v0.1.1 oxygenhub-android / app / src / main / java / io / oxygenhub / android / MainActivity.kt
3.3 KiB · last changed A home screen widget: latest runs, unread, reviews waiting (closes #28) 7 days ago source blame history raw
57c08243 Andy McCall ↶ 1
package io.oxygenhub.android
2
ff65ea45 Andy McCall ↶ 3
import android.content.Intent
57c08243 Andy McCall ↶ 4
import android.os.Bundle
5
import androidx.activity.ComponentActivity
6
import androidx.activity.compose.setContent
7
import androidx.activity.enableEdgeToEdge
144cbf7b Andy McCall ↶ 8
import androidx.compose.runtime.getValue
9
import androidx.compose.runtime.key
ff65ea45 Andy McCall ↶ 10
import androidx.compose.runtime.mutableStateOf
b610bc6e Andy McCall ↶ 11
import androidx.glance.appwidget.updateAll
12
import androidx.lifecycle.compose.collectAsStateWithLifecycle
13
import androidx.lifecycle.lifecycleScope
ff65ea45 Andy McCall ↶ 14
import io.oxygenhub.android.alerts.LandAlerts
15
import io.oxygenhub.android.ui.nav.ProposalRoute
144cbf7b Andy McCall ↶ 16
import io.oxygenhub.android.ui.nav.SignedInApp
17
import io.oxygenhub.android.ui.nav.rememberViewModel
18
import io.oxygenhub.android.ui.signin.SignInScreen
19
import io.oxygenhub.android.ui.signin.SignInViewModel
57c08243 Andy McCall ↶ 20
import io.oxygenhub.android.ui.theme.OxygenHubTheme
b610bc6e Andy McCall ↶ 21
import io.oxygenhub.android.widget.HubWidget
22
import kotlinx.coroutines.launch
57c08243 Andy McCall ↶ 23
import uniffi.rust_core.oxygenGreeting
24
25
class MainActivity : ComponentActivity() {
ff65ea45 Andy McCall ↶ 26
    /** A proposal a notification asked to open (#20), until it is shown. */
27
    private val opening = mutableStateOf<ProposalRoute?>(null)
28
57c08243 Andy McCall ↶ 29
    override fun onCreate(savedInstanceState: Bundle?) {
30
        super.onCreate(savedInstanceState)
ff65ea45 Andy McCall ↶ 31
        if (savedInstanceState == null) opening.value = proposalIn(intent)
57c08243 Andy McCall ↶ 32
        enableEdgeToEdge()
144cbf7b Andy McCall ↶ 33
        val container = (application as OxygenHubApp).container
34
        val sessions = container.sessions
57c08243 Andy McCall ↶ 35
        setContent {
36
            OxygenHubTheme {
144cbf7b Andy McCall ↶ 37
                val session by sessions.session.collectAsStateWithLifecycle()
38
                val signedIn = session
39
                val api = signedIn?.let { sessions.api() }
40
                if (signedIn == null || api == null) {
41
                    SignInScreen(
42
                        rememberViewModel { SignInViewModel(sessions, container::deviceAuth, container.clientName, DEFAULT_HUB) },
43
                    )
57c08243 Andy McCall ↶ 44
                } else {
144cbf7b Andy McCall ↶ 45
                    // A new session starts the signed-in app afresh: nothing of the last account's is kept.
46
                    key(signedIn) {
47
                        SignedInApp(
48
                            session = signedIn,
49
                            api = api,
50
                            nativeCore = { oxygenGreeting(signedIn.username) },
51
                            onSignOut = { sessions.signOut() },
ff65ea45 Andy McCall ↶ 52
                            open = opening.value,
53
                            onOpened = { opening.value = null },
144cbf7b Andy McCall ↶ 54
                        )
55
                    }
57c08243 Andy McCall ↶ 56
                }
57
            }
58
        }
b610bc6e Andy McCall ↶ 59
    }
60
61
    /** The widget (#28) shows what the app knows now, whenever the app comes to the front. */
62
    override fun onResume() {
63
        super.onResume()
64
        lifecycleScope.launch { runCatching { HubWidget().updateAll(this@MainActivity) } }
ff65ea45 Andy McCall ↶ 65
    }
66
67
    override fun onNewIntent(intent: Intent) {
68
        super.onNewIntent(intent)
69
        proposalIn(intent)?.let { opening.value = it }
70
    }
71
72
    private fun proposalIn(intent: Intent?): ProposalRoute? {
73
        val repository = intent?.getStringExtra(LandAlerts.EXTRA_REPOSITORY) ?: return null
74
        val number = intent.getLongExtra(LandAlerts.EXTRA_NUMBER, 0)
75
        if ('/' !in repository || number <= 0) return null
76
        return ProposalRoute(repository.substringBefore('/'), repository.substringAfter('/'), number)
57c08243 Andy McCall ↶ 77
    }
78
}