diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e7d51bf..22dbf1f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -51,6 +51,7 @@ android { dependencies { val composeBom = platform("androidx.compose:compose-bom:2024.10.01") implementation(composeBom) + implementation("androidx.core:core-ktx:1.13.1") implementation("androidx.compose.ui:ui") implementation("androidx.compose.material3:material3") implementation("androidx.activity:activity-compose:1.9.3") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b901d03..f6f2585 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,16 @@ android:name=".TimerService" android:exported="false" android:foregroundServiceType="mediaPlayback" /> + + + + diff --git a/app/src/main/assets/reading/jhanas-guide.pdf b/app/src/main/assets/reading/jhanas-guide.pdf new file mode 100644 index 0000000..243462f Binary files /dev/null and b/app/src/main/assets/reading/jhanas-guide.pdf differ diff --git a/app/src/main/assets/reading/retreat-instructions.pdf b/app/src/main/assets/reading/retreat-instructions.pdf new file mode 100644 index 0000000..363c3f0 Binary files /dev/null and b/app/src/main/assets/reading/retreat-instructions.pdf differ diff --git a/app/src/main/java/com/marcus/meditationtimer/MainActivity.kt b/app/src/main/java/com/marcus/meditationtimer/MainActivity.kt index ebeec7e..8d60245 100644 --- a/app/src/main/java/com/marcus/meditationtimer/MainActivity.kt +++ b/app/src/main/java/com/marcus/meditationtimer/MainActivity.kt @@ -1,10 +1,14 @@ package com.marcus.meditationtimer import android.Manifest +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.os.Bundle +import android.widget.Toast +import androidx.core.content.FileProvider +import java.io.File import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts @@ -136,6 +140,7 @@ private fun App() { ) { Tab(selected = tab == 0, onClick = { tab = 0 }, text = { Text("Timer") }) Tab(selected = tab == 1, onClick = { tab = 1 }, text = { Text("History") }) + Tab(selected = tab == 2, onClick = { tab = 2 }, text = { Text("Reading") }) } when (tab) { 0 -> TimerTab() @@ -143,6 +148,7 @@ private fun App() { onEditSession = { ratingFor = it }, onOpenToken = { showTokenDialog = true }, ) + 2 -> ReadingTab() } } @@ -430,6 +436,67 @@ private fun SessionRow(s: Session, onClick: () -> Unit) { } } +// -------------------------------------------------------------- Reading tab + +private data class Doc(val title: String, val subtitle: String, val asset: String) + +private val DOCS = listOf( + Doc("Pragmatic Jhanas Guide", "v4.3", "jhanas-guide.pdf"), + Doc("Retreat Instructions", "v6.0.3 ยท Day 1 & 2", "retreat-instructions.pdf"), +) + +@Composable +private fun ReadingTab() { + val context = LocalContext.current + Column( + Modifier + .fillMaxSize() + .padding(20.dp) + ) { + DOCS.forEach { doc -> + Column( + Modifier + .fillMaxWidth() + .clickable { openPdf(context, doc) } + .background(Color.White.copy(alpha = 0.05f), RoundedCornerShape(12.dp)) + .padding(20.dp) + ) { + Text(doc.title, color = Color.White.copy(alpha = 0.9f), fontSize = 16.sp) + Spacer(Modifier.height(4.dp)) + Text(doc.subtitle, color = Dim, fontSize = 12.sp) + } + Spacer(Modifier.height(12.dp)) + } + Text( + "Opens in the system PDF viewer.", + color = Dim, + fontSize = 11.sp, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +private fun openPdf(context: Context, doc: Doc) { + try { + val dir = File(context.cacheDir, "reading").apply { mkdirs() } + val outFile = File(dir, doc.asset) + if (!outFile.exists() || outFile.length() == 0L) { + context.assets.open("reading/${doc.asset}").use { input -> + outFile.outputStream().use { input.copyTo(it) } + } + } + val uri = FileProvider.getUriForFile(context, "${context.packageName}.files", outFile) + context.startActivity( + Intent(Intent.ACTION_VIEW) + .setDataAndType(uri, "application/pdf") + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + ) + } catch (e: Exception) { + Toast.makeText(context, "Could not open PDF: ${e.message}", Toast.LENGTH_SHORT).show() + } +} + // ----------------------------------------------------------------- Dialogs @Composable diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..e6b4e2a --- /dev/null +++ b/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,4 @@ + + + +