OXYGENHUB
◆ v0.1.4 oxygenhub-android / app / src / main / java / io / oxygenhub / android / MainActivity.kt
3.6 KiB · last changed The widget's foot: a white mark and title, counts of unread, reviews and assigned issues that open their screens, and the phone's runner job; Assigned to you on the dashboard (closes #31) 3 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
aa627197 Andy McCall ↶ 22
import io.oxygenhub.android.widget.WidgetTaps
b610bc6e Andy McCall ↶ 23
import kotlinx.coroutines.launch
57c08243 Andy McCall ↶ 24
import uniffi.rust_core.oxygenGreeting
25
26
class MainActivity : ComponentActivity() {
ff65ea45 Andy McCall ↶ 27
    /** A proposal a notification asked to open (#20), until it is shown. */
aa627197 Andy McCall ↶ 28
    /** A screen to open, as a notification or the widget asks: a route of the app's navigation. */
29
    private val opening = mutableStateOf<Any?>(null)
ff65ea45 Andy McCall ↶ 30
57c08243 Andy McCall ↶ 31
    override fun onCreate(savedInstanceState: Bundle?) {
32
        super.onCreate(savedInstanceState)
aa627197 Andy McCall ↶ 33
        if (savedInstanceState == null) opening.value = routeIn(intent)
57c08243 Andy McCall ↶ 34
        enableEdgeToEdge()
144cbf7b Andy McCall ↶ 35
        val container = (application as OxygenHubApp).container
36
        val sessions = container.sessions
57c08243 Andy McCall ↶ 37
        setContent {
38
            OxygenHubTheme {
144cbf7b Andy McCall ↶ 39
                val session by sessions.session.collectAsStateWithLifecycle()
40
                val signedIn = session
41
                val api = signedIn?.let { sessions.api() }
42
                if (signedIn == null || api == null) {
43
                    SignInScreen(
44
                        rememberViewModel { SignInViewModel(sessions, container::deviceAuth, container.clientName, DEFAULT_HUB) },
45
                    )
57c08243 Andy McCall ↶ 46
                } else {
144cbf7b Andy McCall ↶ 47
                    // A new session starts the signed-in app afresh: nothing of the last account's is kept.
48
                    key(signedIn) {
49
                        SignedInApp(
50
                            session = signedIn,
51
                            api = api,
52
                            nativeCore = { oxygenGreeting(signedIn.username) },
53
                            onSignOut = { sessions.signOut() },
ff65ea45 Andy McCall ↶ 54
                            open = opening.value,
55
                            onOpened = { opening.value = null },
144cbf7b Andy McCall ↶ 56
                        )
57
                    }
57c08243 Andy McCall ↶ 58
                }
59
            }
60
        }
b610bc6e Andy McCall ↶ 61
    }
62
63
    /** The widget (#28) shows what the app knows now, whenever the app comes to the front. */
64
    override fun onResume() {
65
        super.onResume()
66
        lifecycleScope.launch { runCatching { HubWidget().updateAll(this@MainActivity) } }
ff65ea45 Andy McCall ↶ 67
    }
68
69
    override fun onNewIntent(intent: Intent) {
70
        super.onNewIntent(intent)
aa627197 Andy McCall ↶ 71
        routeIn(intent)?.let { opening.value = it }
ff65ea45 Andy McCall ↶ 72
    }
73
aa627197 Andy McCall ↶ 74
    /** A land alert's proposal, or the screen a tap on the widget's counts names (#31). */
75
    private fun routeIn(intent: Intent?): Any? = proposalIn(intent) ?: WidgetTaps.route(intent)
76
ff65ea45 Andy McCall ↶ 77
    private fun proposalIn(intent: Intent?): ProposalRoute? {
78
        val repository = intent?.getStringExtra(LandAlerts.EXTRA_REPOSITORY) ?: return null
79
        val number = intent.getLongExtra(LandAlerts.EXTRA_NUMBER, 0)
80
        if ('/' !in repository || number <= 0) return null
81
        return ProposalRoute(repository.substringBefore('/'), repository.substringAfter('/'), number)
57c08243 Andy McCall ↶ 82
    }
83
}