diff --git a/android/Omnivore/app/build.gradle b/android/Omnivore/app/build.gradle
index a8c001e18..c20cfc63f 100644
--- a/android/Omnivore/app/build.gradle
+++ b/android/Omnivore/app/build.gradle
@@ -17,8 +17,8 @@ android {
applicationId "app.omnivore.omnivore"
minSdk 26
targetSdk 33
- versionCode 60
- versionName "0.0.60"
+ versionCode 61
+ versionName "0.0.61"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@@ -148,6 +148,8 @@ dependencies {
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
kapt "androidx.room:room-compiler:$room_version"
+
+ implementation 'com.github.jeziellago:compose-markdown:0.3.3'
}
apollo {
diff --git a/android/Omnivore/app/src/main/AndroidManifest.xml b/android/Omnivore/app/src/main/AndroidManifest.xml
index 3983989ed..a721ffdc7 100644
--- a/android/Omnivore/app/src/main/AndroidManifest.xml
+++ b/android/Omnivore/app/src/main/AndroidManifest.xml
@@ -57,5 +57,10 @@
android:exported="true"
android:theme="@style/Theme.Omnivore"/>
+
+
diff --git a/android/Omnivore/app/src/main/assets/test.pdf b/android/Omnivore/app/src/main/assets/test.pdf
deleted file mode 100644
index 2887e5b76..000000000
Binary files a/android/Omnivore/app/src/main/assets/test.pdf and /dev/null differ
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt
index 6608a30f6..01b4b9a6f 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt
@@ -7,4 +7,5 @@ sealed class Routes(val route: String) {
object Documentation: Routes("Documentation")
object PrivacyPolicy: Routes("PrivacyPolicy")
object TermsAndConditions: Routes("TermsAndConditions")
+ object Notebook: Routes("Notebook")
}
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt
index 38cd552d6..68f4b40f5 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt
@@ -162,6 +162,24 @@ interface SavedItemDao {
)
fun getLibraryLiveDataSortedByRecentlyPublished(archiveFilter: Int): LiveData>
+ @Transaction
+ @Query(
+ "SELECT ${SavedItemQueryConstants.libraryColumns} " +
+ "FROM SavedItem " +
+ "LEFT OUTER JOIN SavedItemAndSavedItemLabelCrossRef on SavedItem.savedItemId = SavedItemAndSavedItemLabelCrossRef.savedItemId " +
+ "LEFT OUTER JOIN SavedItemAndHighlightCrossRef on SavedItem.savedItemId = SavedItemAndHighlightCrossRef.savedItemId " +
+
+ "LEFT OUTER JOIN SavedItemLabel on SavedItemLabel.savedItemLabelId = SavedItemAndSavedItemLabelCrossRef.savedItemLabelId " +
+ "LEFT OUTER JOIN Highlight on highlight.highlightId = SavedItemAndHighlightCrossRef.highlightId " +
+
+ "WHERE SavedItem.savedItemId = :savedItemId " +
+ "AND SavedItem.serverSyncStatus != 2 " +
+ "AND Highlight.serverSyncStatus != 2 " +
+
+ "GROUP BY SavedItem.savedItemId "
+ )
+ fun getLibraryItemById(savedItemId: String): LiveData
+
@Transaction
@Query(
"SELECT ${SavedItemQueryConstants.libraryColumns} " +
@@ -173,7 +191,7 @@ interface SavedItemDao {
"LEFT OUTER JOIN Highlight on highlight.highlightId = SavedItemAndHighlightCrossRef.highlightId " +
"WHERE SavedItem.serverSyncStatus != 2 " +
- "AND SavedItem.isArchived != :archiveFilter " +
+ "AND SavedItem.isArchived IN (:allowedArchiveStates) " +
"AND SavedItem.contentReader IN (:allowedContentReaders) " +
"AND CASE WHEN :hasRequiredLabels THEN SavedItemLabel.name in (:requiredLabels) ELSE 1 END " +
"AND CASE WHEN :hasExcludedLabels THEN SavedItemLabel.name is NULL OR SavedItemLabel.name not in (:excludedLabels) ELSE 1 END " +
@@ -187,11 +205,11 @@ interface SavedItemDao {
"CASE WHEN :sortKey = 'recentlyRead' THEN SavedItem.readAt END DESC,\n" +
"CASE WHEN :sortKey = 'recentlyPublished' THEN SavedItem.publishDate END DESC"
)
- fun _filteredLibraryData(archiveFilter: Int, sortKey: String, hasRequiredLabels: Int, hasExcludedLabels: Int, requiredLabels: List, excludedLabels: List, allowedContentReaders: List): LiveData>
+ fun _filteredLibraryData(allowedArchiveStates: List, sortKey: String, hasRequiredLabels: Int, hasExcludedLabels: Int, requiredLabels: List, excludedLabels: List, allowedContentReaders: List): LiveData>
- fun filteredLibraryData(archiveFilter: Int, sortKey: String, requiredLabels: List, excludedLabels: List, allowedContentReaders: List): LiveData> {
+ fun filteredLibraryData(allowedArchiveStates: List, sortKey: String, requiredLabels: List, excludedLabels: List, allowedContentReaders: List): LiveData> {
return _filteredLibraryData(
- archiveFilter = archiveFilter,
+ allowedArchiveStates = allowedArchiveStates,
sortKey = sortKey,
hasRequiredLabels = requiredLabels.size,
hasExcludedLabels = excludedLabels.size,
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt
index cc4bb85ed..577526da6 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt
@@ -36,7 +36,7 @@ class LibraryViewModel @Inject constructor(
// Live Data
private var itemsLiveDataInternal = dataService.db.savedItemDao().filteredLibraryData(
- archiveFilter = 1,
+ allowedArchiveStates = listOf(0),
sortKey = "newest",
requiredLabels = listOf(),
excludedLabels = listOf(),
@@ -65,28 +65,6 @@ class LibraryViewModel @Inject constructor(
}
}
-// runBlocking {
-// datastoreRepo.getString(DatastoreKeys.lastUsedSavedItemFilter)?.let { str ->
-// try {
-// val filter = SavedItemFilter.values().first { it.rawValue == str }
-// appliedFilterLiveData.postValue(filter)
-// } catch (e: Exception) {
-// Log.d("error", "invalid filter value stored in datastore repo: $e")
-// }
-//
-// datastoreRepo.getString(DatastoreKeys.lastUsedSavedItemSortFilter)?.let { str ->
-// try {
-// val filter = SavedItemSortFilter.values().first { it.rawValue == str }
-// appliedSortFilterLiveData.postValue(filter)
-// } catch (e: Exception) {
-// Log.d("error", "invalid sort filter value stored in datastore repo: $e")
-// }
-//
-// handleFilterChanges()
-// }
-// }
-// }
-
viewModelScope.launch {
handleFilterChanges()
for (slug in contentRequestChannel) {
@@ -196,9 +174,10 @@ class LibraryViewModel @Inject constructor(
else -> "newest"
}
- val archiveFilter = when (appliedFilterLiveData.value) {
- SavedItemFilter.ARCHIVED -> 0
- else -> 1
+ val allowedArchiveStates = when (appliedFilterLiveData.value) {
+ SavedItemFilter.ALL -> listOf(0, 1)
+ SavedItemFilter.ARCHIVED -> listOf(1)
+ else -> listOf(0)
}
val allowedContentReaders = when(appliedFilterLiveData.value) {
@@ -221,7 +200,7 @@ class LibraryViewModel @Inject constructor(
}
val newData = dataService.db.savedItemDao().filteredLibraryData(
- archiveFilter = archiveFilter,
+ allowedArchiveStates = allowedArchiveStates,
sortKey = sortKey,
requiredLabels = requiredLabels,
excludedLabels = excludeLabels,
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt
new file mode 100644
index 000000000..cb7834c6c
--- /dev/null
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt
@@ -0,0 +1,403 @@
+package app.omnivore.omnivore.ui.notebook
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
+import androidx.activity.compose.setContent
+import androidx.activity.viewModels
+import androidx.compose.foundation.*
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.*
+import androidx.compose.material3.*
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Text
+import androidx.compose.runtime.*
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.drawWithCache
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import app.omnivore.omnivore.MainActivity
+import app.omnivore.omnivore.R
+import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights
+import app.omnivore.omnivore.ui.library.*
+import app.omnivore.omnivore.ui.theme.OmnivoreTheme
+import com.google.accompanist.systemuicontroller.rememberSystemUiController
+import dagger.hilt.android.AndroidEntryPoint
+import dev.jeziellago.compose.markdowntext.MarkdownText
+import kotlinx.coroutines.launch
+
+
+@AndroidEntryPoint
+class NotebookActivity: ComponentActivity() {
+ val viewModel: NotebookViewModel by viewModels()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val savedItemId = intent.getStringExtra("SAVED_ITEM_ID")
+
+ setContent {
+ val systemUiController = rememberSystemUiController()
+ val useDarkIcons = !isSystemInDarkTheme()
+
+ DisposableEffect(systemUiController, useDarkIcons) {
+ systemUiController.setSystemBarsColor(
+ color = Color.Black,
+ darkIcons = false
+ )
+
+ onDispose {}
+ }
+
+ OmnivoreTheme {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ // .background(color = Color.Black)
+ ) {
+ savedItemId?.let {
+ NotebookView(
+ savedItemId = savedItemId,
+ viewModel = viewModel
+ )
+ }
+ }
+ }
+ }
+ }
+
+// // animate the view up when keyboard appears
+// WindowCompat.setDecorFitsSystemWindows(window, false)
+// val rootView = findViewById(android.R.id.content).rootView
+// ViewCompat.setOnApplyWindowInsetsListener(rootView) { _, insets ->
+// val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
+// rootView.setPadding(0, 0, 0, imeHeight)
+// insets
+// }
+// }
+
+ private fun startMainActivity() {
+ val intent = Intent(this, MainActivity::class.java)
+ this.startActivity(intent)
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
+@Composable
+fun NotebookView(savedItemId: String, viewModel: NotebookViewModel) {
+ val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
+ val savedItem = viewModel.getLibraryItemById(savedItemId).observeAsState()
+ val scrollState = rememberScrollState()
+ val modalBottomSheetState = rememberModalBottomSheetState(
+ ModalBottomSheetValue.Hidden,
+ )
+ val notes = savedItem.value?.highlights?.filter { it.type == "NOTE" } ?: listOf()
+ val highlights = savedItem.value?.highlights?.filter { it.type == "HIGHLIGHT" } ?: listOf()
+
+ ModalBottomSheetLayout(
+ modifier = Modifier.statusBarsPadding(),
+ sheetBackgroundColor = Color.Transparent,
+ sheetState = modalBottomSheetState,
+ sheetContent = {
+ EditNoteModal()
+ }
+ ) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text("Notebook") },
+ modifier = Modifier.statusBarsPadding(),
+ colors = TopAppBarDefaults.topAppBarColors(
+ containerColor = MaterialTheme.colorScheme.background
+ ),
+ navigationIcon = {
+ IconButton(onClick = {
+ onBackPressedDispatcher?.onBackPressed()
+ }) {
+ Icon(
+ imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack,
+ modifier = Modifier,
+ contentDescription = "Back"
+ )
+ }
+ },
+// actions = {
+// IconButton(onClick = {
+//
+// }) {
+// Icon(
+// imageVector = Icons.Default.MoreVert,
+// contentDescription = null
+// )
+// }
+// }
+ )
+ }
+ ) { paddingValues ->
+ Column(
+ modifier = Modifier
+ .padding(paddingValues)
+ .verticalScroll(scrollState)
+ .fillMaxSize()
+ ) {
+ savedItem.value?.let {
+ if (notes.isNotEmpty()) {
+ ArticleNotes(it)
+ }
+ HighlightsList(it)
+ }
+ Spacer(Modifier.weight(100f))
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
+@Composable
+fun EditNoteModal() {
+ val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
+ val annotation = remember { mutableStateOf("") }
+
+ BottomSheetUI() {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text("Note") },
+ modifier = Modifier.statusBarsPadding(),
+ colors = TopAppBarDefaults.topAppBarColors(
+ containerColor = MaterialTheme.colorScheme.background
+ ),
+ navigationIcon = {
+ IconButton(onClick = {
+ onBackPressedDispatcher?.onBackPressed()
+ }) {
+ Icon(
+ imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack,
+ modifier = Modifier,
+ contentDescription = "Back"
+ )
+ }
+ }
+ )
+ }
+ ) { paddingValues ->
+ TextField(
+ modifier = Modifier
+ .padding(paddingValues)
+ .fillMaxSize(),
+ value = annotation.value, onValueChange = { annotation.value = it }
+ )
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
+@Composable
+fun ArticleNotes(item: SavedItemWithLabelsAndHighlights) {
+ val notes = item.highlights?.filter { it.type == "NOTE" } ?: listOf()
+ val showDialog = remember { mutableStateOf(false) }
+ val modalBottomSheetState = rememberModalBottomSheetState(
+ ModalBottomSheetValue.Expanded,
+ )
+ val annotation = remember { mutableStateOf("") }
+
+ Column(modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 15.dp)
+ ) {
+ Text("Article Notes")
+ Divider(modifier = Modifier.padding(bottom= 15.dp))
+ notes.forEach { note ->
+ MarkdownText(
+ markdown = note.annotation ?: "",
+ fontSize = 14.sp,
+ style = TextStyle(lineHeight = 18.sp),
+ color = MaterialTheme.colorScheme.onPrimaryContainer,
+ )
+ }
+ if (notes.isEmpty()) {
+ Button(
+ onClick = {
+// viewModelScope.launch {
+// datastoreRepo.clearValue(DatastoreKeys.omnivorePendingUserToken)
+// }
+ },
+ modifier = Modifier
+ .padding(0.dp, end = 15.dp)
+ .fillMaxWidth(),
+ shape = androidx.compose.material.MaterialTheme.shapes.medium,
+ colors = ButtonDefaults.buttonColors(
+ contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ containerColor = MaterialTheme.colorScheme.surfaceVariant
+ )
+ ) {
+// Text(
+// text = "Add Notes...",
+// style = androidx.compose.material.MaterialTheme.typography.subtitle2,
+// modifier = Modifier
+// .padding(vertical = 2.dp, horizontal = 0.dp),
+// )
+ Spacer(Modifier.weight(1f))
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun HighlightsList(item: SavedItemWithLabelsAndHighlights) {
+ val highlights = item.highlights?.filter { it.type == "HIGHLIGHT" } ?: listOf()
+ val yellowColor = colorResource(R.color.cta_yellow)
+
+ val coroutineScope = rememberCoroutineScope()
+ val snackBarHostState = remember { SnackbarHostState() }
+ val clipboard: ClipboardManager? =
+ LocalContext.current.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
+
+ Column(modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 15.dp)
+ .padding(top = 40.dp, bottom = 100.dp)
+ ) {
+ Text("Highlights")
+ Divider(modifier = Modifier.padding(bottom= 10.dp))
+ highlights.forEach { highlight ->
+ var isMenuOpen by remember { mutableStateOf(false) }
+
+ Row(modifier = Modifier
+ .fillMaxWidth()
+ .align(Alignment.End)
+ .padding(0.dp)
+ ) {
+ Spacer(Modifier.weight(1f))
+ Box {
+ IconButton(onClick = { isMenuOpen = true }) {
+ Icon(
+ imageVector = Icons.Default.MoreVert,
+ contentDescription = null
+ )
+ }
+ if (isMenuOpen) {
+ DropdownMenu(
+ expanded = isMenuOpen,
+ onDismissRequest = { isMenuOpen = false }
+ ) {
+ DropdownMenuItem(
+ text = { Text("Copy") },
+ onClick = {
+ val clip = ClipData.newPlainText("highlight", highlight.quote)
+ clipboard?.let {
+ it
+ clipboard?.setPrimaryClip(clip)
+ } ?: run {
+ coroutineScope.launch {
+ snackBarHostState
+ .showSnackbar("Highlight copied")
+ }
+ }
+ isMenuOpen = false
+ }
+ )
+ }
+ }
+ }
+ }
+
+ highlight.quote?.let {
+ Row(modifier = Modifier
+ .padding(start = 2.dp, end = 15.dp)
+ .fillMaxWidth()
+ .drawWithCache {
+ onDrawWithContent {
+ // draw behind the content the vertical line on the left
+ drawLine(
+ color = yellowColor,
+ start = Offset.Zero,
+ end = Offset(0f, this.size.height),
+ strokeWidth = 10f
+ )
+
+ // draw the content
+ drawContent()
+ }
+ }) {
+
+ MarkdownText(
+ modifier = Modifier
+ .padding(start = 15.dp, end = 15.dp),
+ markdown = it,
+ fontSize = 14.sp,
+ color = MaterialTheme.colorScheme.onPrimaryContainer,
+ )
+ }
+ }
+ highlight.annotation?.let {
+ MarkdownText(
+ // modifier = Modifier.padding(paddingValues),
+ markdown = it,
+ fontSize = 14.sp,
+ color = MaterialTheme.colorScheme.onPrimaryContainer,
+ )
+ } ?: run {
+// Surface(
+// modifier = Modifier
+// .padding(0.dp, end = 15.dp, top = 15.dp, bottom = 30.dp)
+// .fillMaxWidth(),
+// shape = androidx.compose.material.MaterialTheme.shapes.medium,
+// color = MaterialTheme.colorScheme.surfaceVariant
+// ) {
+// Row {
+// Text(
+// text = "Add Notes...",
+// style = androidx.compose.material.MaterialTheme.typography.subtitle2,
+// modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp)
+// )
+// }
+// }
+ }
+ }
+ if (highlights.isEmpty()) {
+ Text(
+ text = "You have not added any highlights to this page.",
+ style = androidx.compose.material.MaterialTheme.typography.subtitle2,
+ modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp)
+ )
+ }
+ }
+}
+
+@Composable
+private fun BottomSheetUI(content: @Composable () -> Unit) {
+ Box(
+ modifier = Modifier
+ .wrapContentHeight()
+ .fillMaxWidth()
+ .clip(RoundedCornerShape(topEnd = 20.dp, topStart = 20.dp))
+ .background(Color.White)
+ .statusBarsPadding()
+ .padding(top = 20.dp)
+ ) {
+ content()
+ }
+}
+
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt
new file mode 100644
index 000000000..e1095d1ab
--- /dev/null
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt
@@ -0,0 +1,23 @@
+package app.omnivore.omnivore.ui.notebook
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.ViewModel
+import app.omnivore.omnivore.DatastoreRepository
+import app.omnivore.omnivore.dataService.DataService
+import app.omnivore.omnivore.networking.Networker
+import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights
+import app.omnivore.omnivore.ui.library.SavedItemViewModel
+import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
+
+@HiltViewModel
+class NotebookViewModel @Inject constructor(
+ private val networker: Networker,
+ private val dataService: DataService,
+ private val datastoreRepo: DatastoreRepository
+): ViewModel() {
+
+ fun getLibraryItemById(savedItemId: String): LiveData {
+ return dataService.db.savedItemDao().getLibraryItemById(savedItemId)
+ }
+}
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt
index 5230b381e..7d64466ce 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt
@@ -26,6 +26,7 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
@@ -33,8 +34,6 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.viewmodel.compose.viewModel
-import androidx.navigation.NavHostController
-import androidx.navigation.compose.rememberNavController
import app.omnivore.omnivore.MainActivity
import app.omnivore.omnivore.R
import app.omnivore.omnivore.ui.components.WebReaderLabelsSelectionSheet
@@ -44,6 +43,8 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import dagger.hilt.android.AndroidEntryPoint
import kotlin.math.roundToInt
import androidx.navigation.compose.rememberNavController
+import app.omnivore.omnivore.Routes
+import app.omnivore.omnivore.ui.notebook.NotebookActivity
@AndroidEntryPoint
@@ -55,7 +56,6 @@ class WebReaderLoadingContainerActivity: ComponentActivity() {
val requestID = intent.getStringExtra("SAVED_ITEM_REQUEST_ID")
val slug = intent.getStringExtra("SAVED_ITEM_SLUG")
-
setContent {
val systemUiController = rememberSystemUiController()
val useDarkIcons = !isSystemInDarkTheme()
@@ -122,6 +122,8 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o
webReaderViewModel.maxToolbarHeightPx = with(LocalDensity.current) { maxToolbarHeight.roundToPx().toFloat() }
webReaderViewModel.loadItem(slug = slug, requestID = requestID)
+ val context = LocalContext.current
+
val styledContent = webReaderParams?.let {
val webReaderContent = WebReaderContent(
preferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()),
@@ -171,6 +173,18 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o
)
}
}
+ webReaderParams?.let {
+ IconButton(onClick = {
+ val intent = Intent(context, NotebookActivity::class.java)
+ intent.putExtra("SAVED_ITEM_ID", it.item.savedItemId)
+ context.startActivity(intent)
+ }) {
+ Icon(
+ painter = painterResource(id = R.drawable.notebook),
+ contentDescription = null
+ )
+ }
+ }
IconButton(onClick = { showWebPreferencesDialog = true }) {
Icon(
painter = painterResource(id = R.drawable.format_letter_case),
diff --git a/android/Omnivore/app/src/main/res/drawable/notebook.xml b/android/Omnivore/app/src/main/res/drawable/notebook.xml
new file mode 100644
index 000000000..c39b20458
--- /dev/null
+++ b/android/Omnivore/app/src/main/res/drawable/notebook.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/android/Omnivore/app/src/main/res/values/colors.xml b/android/Omnivore/app/src/main/res/values/colors.xml
index d81888f7f..fdb6f43db 100644
--- a/android/Omnivore/app/src/main/res/values/colors.xml
+++ b/android/Omnivore/app/src/main/res/values/colors.xml
@@ -10,4 +10,8 @@
#EBEBEB
#E6E4BF
+ #F8D457
+
+
+
diff --git a/android/Omnivore/settings.gradle b/android/Omnivore/settings.gradle
index 8a45271fe..d3111f0f7 100644
--- a/android/Omnivore/settings.gradle
+++ b/android/Omnivore/settings.gradle
@@ -13,6 +13,7 @@ dependencyResolutionManagement {
maven {
url = uri("https://customers.pspdfkit.com/maven")
}
+ maven { url 'https://jitpack.io' }
}
}
rootProject.name = "Omnivore"