@@ -0,0 +1,176 @@
1+package com.parseable.android.ui.screens.about
2+
3+import android.content.Intent
4+import android.net.Uri
5+import androidx.compose.foundation.layout.*
6+import androidx.compose.foundation.rememberScrollState
7+import androidx.compose.foundation.verticalScroll
8+import androidx.compose.material.icons.Icons
9+import androidx.compose.material.icons.automirrored.filled.ArrowBack
10+import androidx.compose.material.icons.filled.*
11+import androidx.compose.material3.*
12+import androidx.compose.runtime.Composable
13+import androidx.compose.ui.Alignment
14+import androidx.compose.ui.Modifier
15+import androidx.compose.ui.platform.LocalContext
16+import androidx.compose.ui.text.font.FontWeight
17+import androidx.compose.ui.unit.dp
18+import com.parseable.android.BuildConfig
19+
20+private const val GITHUB_REPO_URL = "https://github.com/parseablehq/parseable-android"
21+private const val PARSEABLE_WEBSITE_URL = "https://www.parseable.com"
22+
23+@OptIn(ExperimentalMaterial3Api::class)
24+@Composable
25+fun AboutScreen(
26+ onBack: () -> Unit,
27+) {
28+ val context = LocalContext.current
29+
30+ Scaffold(
31+ topBar = {
32+ TopAppBar(
33+ title = { Text("About") },
34+ navigationIcon = {
35+ IconButton(onClick = onBack) {
36+ Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
37+ }
38+ },
39+ )
40+ },
41+ ) { padding ->
42+ Column(
43+ modifier = Modifier
44+ .fillMaxSize()
45+ .padding(padding)
46+ .verticalScroll(rememberScrollState())
47+ .padding(16.dp),
48+ verticalArrangement = Arrangement.spacedBy(16.dp),
49+ ) {
50+ // App header
51+ Card(
52+ modifier = Modifier.fillMaxWidth(),
53+ elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
54+ ) {
55+ Column(
56+ modifier = Modifier
57+ .fillMaxWidth()
58+ .padding(24.dp),
59+ horizontalAlignment = Alignment.CenterHorizontally,
60+ ) {
61+ Icon(
62+ Icons.Filled.Terminal,
63+ contentDescription = null,
64+ modifier = Modifier.size(48.dp),
65+ tint = MaterialTheme.colorScheme.primary,
66+ )
67+ Spacer(modifier = Modifier.height(12.dp))
68+ Text(
69+ text = "Parseable",
70+ style = MaterialTheme.typography.headlineSmall,
71+ fontWeight = FontWeight.Bold,
72+ )
73+ Text(
74+ text = "Android Client",
75+ style = MaterialTheme.typography.titleMedium,
76+ color = MaterialTheme.colorScheme.onSurfaceVariant,
77+ )
78+ Spacer(modifier = Modifier.height(8.dp))
79+ Text(
80+ text = "Version ${BuildConfig.VERSION_NAME}",
81+ style = MaterialTheme.typography.bodyMedium,
82+ color = MaterialTheme.colorScheme.onSurfaceVariant,
83+ )
84+ }
85+ }
86+
87+ // Description
88+ Card(
89+ modifier = Modifier.fillMaxWidth(),
90+ elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
91+ ) {
92+ Column(modifier = Modifier.padding(16.dp)) {
93+ Row(verticalAlignment = Alignment.CenterVertically) {
94+ Icon(
95+ Icons.Filled.Info,
96+ contentDescription = null,
97+ tint = MaterialTheme.colorScheme.primary,
98+ )
99+ Spacer(modifier = Modifier.width(8.dp))
100+ Text(
101+ text = "About",
102+ style = MaterialTheme.typography.titleMedium,
103+ fontWeight = FontWeight.Bold,
104+ )
105+ }
106+ Spacer(modifier = Modifier.height(12.dp))
107+ Text(
108+ text = "Parseable is an open-source log analytics platform. " +
109+ "This app connects to a Parseable server instance and lets you " +
110+ "browse, search, filter, and live-tail log data.",
111+ style = MaterialTheme.typography.bodyMedium,
112+ )
113+ }
114+ }
115+
116+ // Links
117+ Card(
118+ modifier = Modifier.fillMaxWidth(),
119+ elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
120+ ) {
121+ Column(modifier = Modifier.padding(16.dp)) {
122+ Row(verticalAlignment = Alignment.CenterVertically) {
123+ Icon(
124+ Icons.Filled.Link,
125+ contentDescription = null,
126+ tint = MaterialTheme.colorScheme.primary,
127+ )
128+ Spacer(modifier = Modifier.width(8.dp))
129+ Text(
130+ text = "Links",
131+ style = MaterialTheme.typography.titleMedium,
132+ fontWeight = FontWeight.Bold,
133+ )
134+ }
135+ Spacer(modifier = Modifier.height(12.dp))
136+
137+ OutlinedButton(
138+ onClick = {
139+ context.startActivity(
140+ Intent(Intent.ACTION_VIEW, Uri.parse(GITHUB_REPO_URL))
141+ )
142+ },
143+ modifier = Modifier.fillMaxWidth(),
144+ ) {
145+ Icon(
146+ Icons.Filled.Code,
147+ contentDescription = null,
148+ modifier = Modifier.size(18.dp),
149+ )
150+ Spacer(modifier = Modifier.width(8.dp))
151+ Text("GitHub Repository")
152+ }
153+
154+ Spacer(modifier = Modifier.height(8.dp))
155+
156+ OutlinedButton(
157+ onClick = {
158+ context.startActivity(
159+ Intent(Intent.ACTION_VIEW, Uri.parse(PARSEABLE_WEBSITE_URL))
160+ )
161+ },
162+ modifier = Modifier.fillMaxWidth(),
163+ ) {
164+ Icon(
165+ Icons.Filled.Language,
166+ contentDescription = null,
167+ modifier = Modifier.size(18.dp),
168+ )
169+ Spacer(modifier = Modifier.width(8.dp))
170+ Text("Parseable Website")
171+ }
172+ }
173+ }
174+ }
175+ }
176+}