mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
android: resolve issues and warnings
Signed-off-by: Remy Chantenay <remy.chantenay@gmail.com>
This commit is contained in:
parent
78307b7149
commit
ac47aaaee6
47 changed files with 144 additions and 345 deletions
|
|
@ -22,7 +22,6 @@
|
|||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.Omnivore">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
@ -56,10 +55,5 @@
|
|||
android:exported="true"
|
||||
android:theme="@style/Theme.Omnivore"/>
|
||||
|
||||
<activity
|
||||
android:name=".ui.notebook.NotebookActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.Omnivore"/>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
package app.omnivore.omnivore
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import app.omnivore.omnivore.dataService.DataService
|
||||
import app.omnivore.omnivore.networking.Networker
|
||||
import app.omnivore.omnivore.persistence.AppDatabase
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package app.omnivore.omnivore.dataService
|
||||
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.HighlightType
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package app.omnivore.omnivore.dataService
|
||||
|
||||
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import java.security.SecureRandom
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
|
|
@ -32,13 +31,9 @@ object NanoId {
|
|||
*/
|
||||
@JvmOverloads
|
||||
fun generate(
|
||||
@NotNull
|
||||
size: Int = 21,
|
||||
@NotNull
|
||||
alphabet: String = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
@NotNull
|
||||
additionalBytesFactor: Double = 1.6,
|
||||
@NotNull
|
||||
random: Random = SecureRandom()
|
||||
): String {
|
||||
require(!(alphabet.isEmpty() || alphabet.length >= 256)) { "alphabet must contain between 1 and 255 symbols." }
|
||||
|
|
@ -64,7 +59,7 @@ object NanoId {
|
|||
* @return The generated optimized string.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun generateOptimized(@NotNull size: Int, @NotNull alphabet: String, @NotNull mask: Int, @NotNull step: Int, @NotNull random: Random = SecureRandom()): String {
|
||||
fun generateOptimized(size: Int, alphabet: String, mask: Int, step: Int, random: Random = SecureRandom()): String {
|
||||
val idBuilder = StringBuilder(size)
|
||||
val bytes = ByteArray(step)
|
||||
while (true) {
|
||||
|
|
@ -87,7 +82,7 @@ object NanoId {
|
|||
* @param alphabet The set of characters to use for generating the string.
|
||||
* @return The additional bytes factor, rounded to two decimal places.
|
||||
*/
|
||||
fun calculateAdditionalBytesFactor(@NotNull alphabet: String): Double {
|
||||
private fun calculateAdditionalBytesFactor(alphabet: String): Double {
|
||||
val mask = calculateMask(alphabet)
|
||||
return (1 + abs((mask - alphabet.length.toDouble()) / alphabet.length)).round(2)
|
||||
}
|
||||
|
|
@ -98,7 +93,7 @@ object NanoId {
|
|||
* @param alphabet The set of characters to use for generating the string.
|
||||
* @return The calculated mask value.
|
||||
*/
|
||||
fun calculateMask(@NotNull alphabet: String) = (2 shl (Integer.SIZE - 1 - Integer.numberOfLeadingZeros(alphabet.length - 1))) - 1
|
||||
private fun calculateMask(alphabet: String) = (2 shl (Integer.SIZE - 1 - Integer.numberOfLeadingZeros(alphabet.length - 1))) - 1
|
||||
|
||||
/**
|
||||
* Calculates the number of random bytes to generate in each iteration for a given size and alphabet.
|
||||
|
|
@ -109,7 +104,7 @@ object NanoId {
|
|||
* @return The number of random bytes to generate in each iteration.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun calculateStep(@NotNull size: Int, @NotNull alphabet: String, @NotNull additionalBytesFactor: Double = calculateAdditionalBytesFactor(alphabet)) =
|
||||
fun calculateStep(size: Int, alphabet: String, additionalBytesFactor: Double = calculateAdditionalBytesFactor(alphabet)) =
|
||||
ceil(additionalBytesFactor * calculateMask(alphabet) * size / alphabet.length).toInt()
|
||||
|
||||
@JvmSynthetic
|
||||
|
|
|
|||
|
|
@ -7,13 +7,7 @@ import app.omnivore.omnivore.networking.*
|
|||
import app.omnivore.omnivore.persistence.entities.Highlight
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import com.apollographql.apollo3.api.Optional.Companion.absent
|
||||
import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
suspend fun DataService.startSyncChannels() {
|
||||
for (savedItem in savedItemSyncChannel) {
|
||||
|
|
@ -112,7 +106,7 @@ private suspend fun DataService.syncHighlight(highlight: Highlight) {
|
|||
val isUpdatedOnServer = networker.updateHighlight(
|
||||
UpdateHighlightInput(
|
||||
annotation = Optional.presentIfNotNull(highlight.annotation),
|
||||
highlightId = highlight.highlightId ?: "",
|
||||
highlightId = highlight.highlightId,
|
||||
sharedAt = Optional.absent()
|
||||
)
|
||||
)
|
||||
|
|
@ -136,7 +130,7 @@ private suspend fun DataService.syncHighlight(highlight: Highlight) {
|
|||
id = highlight.highlightId,
|
||||
patch = Optional.presentIfNotNull(highlight.patch),
|
||||
quote = Optional.presentIfNotNull(highlight.quote),
|
||||
shortId = highlight.shortId ?: ""
|
||||
shortId = highlight.shortId
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package app.omnivore.omnivore.models
|
||||
|
||||
enum class ServerSyncStatus(
|
||||
val rawValue: Int,
|
||||
) {
|
||||
enum class ServerSyncStatus(val rawValue: Int) {
|
||||
IS_SYNCED(0),
|
||||
IS_SYNCING(1),
|
||||
NEEDS_DELETION(2),
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
package app.omnivore.omnivore.ui.auth
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ContentValues
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ fun UserProfileFields(
|
|||
|
||||
if (usernameValidationErrorMessage != null) {
|
||||
Text(
|
||||
text = usernameValidationErrorMessage!!,
|
||||
text = usernameValidationErrorMessage,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
textAlign = TextAlign.Center
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ fun EmailSignUpFields(
|
|||
|
||||
if (usernameValidationErrorMessage != null) {
|
||||
Text(
|
||||
text = usernameValidationErrorMessage!!,
|
||||
text = usernameValidationErrorMessage,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
textAlign = TextAlign.Center
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
|
|||
|
||||
@Composable
|
||||
fun LoadingButtonWithIcon(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String,
|
||||
loadingText: String,
|
||||
icon: Painter,
|
||||
|
|
@ -23,7 +24,6 @@ fun LoadingButtonWithIcon(
|
|||
borderColor: Color = Color.LightGray,
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
||||
progressIndicatorColor: Color = MaterialTheme.colorScheme.primary,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Surface(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
|||
import java.util.regex.Pattern
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
enum class RegistrationState {
|
||||
SocialLogin,
|
||||
EmailSignIn,
|
||||
|
|
@ -114,7 +113,7 @@ class LoginViewModel @Inject constructor(
|
|||
registrationStateLiveData.value = RegistrationState.EmailSignUp
|
||||
}
|
||||
|
||||
fun showSelfHostedSettings(pendingCreds: PendingEmailUserCreds? = null) {
|
||||
fun showSelfHostedSettings() {
|
||||
resetState()
|
||||
registrationStateLiveData.value = RegistrationState.SelfHosted
|
||||
}
|
||||
|
|
@ -329,11 +328,11 @@ class LoginViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun handleGoogleAuthTask(task: Task<GoogleSignInAccount>) {
|
||||
val result = task?.getResult(ApiException::class.java)
|
||||
val result = task.getResult(ApiException::class.java)
|
||||
val googleIdToken = result?.idToken ?: ""
|
||||
|
||||
// If token is missing then set the error message
|
||||
if (googleIdToken == null) {
|
||||
if (googleIdToken.isEmpty()) {
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_missing_auth_token_error_msg)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import app.omnivore.omnivore.R
|
|||
fun SelfHostedView(viewModel: LoginViewModel) {
|
||||
var apiServer by rememberSaveable { mutableStateOf("") }
|
||||
var webServer by rememberSaveable { mutableStateOf("") }
|
||||
var context = LocalContext.current
|
||||
val context = LocalContext.current
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
|
@ -6,15 +8,13 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.ui.components.HighlightColor
|
||||
import app.omnivore.omnivore.ui.components.HighlightColorPaletteMode
|
||||
|
||||
@Composable
|
||||
fun HighlightColorPalette(
|
||||
modifier: Modifier = Modifier,
|
||||
mode: HighlightColorPaletteMode = HighlightColorPaletteMode.Light,
|
||||
selectedColorName: String,
|
||||
onColorSelected: (color: HighlightColor) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
|
@ -14,17 +16,16 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.ui.components.HighlightColor
|
||||
|
||||
@Composable
|
||||
fun HighlightColorPaletteItem(
|
||||
modifier: Modifier = Modifier,
|
||||
color: HighlightColor,
|
||||
isSelected: Boolean,
|
||||
onClick: (color: HighlightColor) -> Unit,
|
||||
modifier: Modifier = Modifier.padding(6.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = modifier,
|
||||
modifier = modifier.padding(6.dp),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.selection.toggleable
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.ui.components.LabelChipColors
|
||||
|
||||
@Composable
|
||||
fun LabelChip(
|
||||
modifier: Modifier = Modifier,
|
||||
name: String,
|
||||
colors: LabelChipColors,
|
||||
modifier: Modifier = Modifier.padding(0.dp),
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier.padding(2.dp),
|
||||
|
|
|
|||
|
|
@ -2,43 +2,26 @@
|
|||
|
||||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import LabelChip
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.interaction.FocusInteraction
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.PressInteraction
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.ModalBottomSheetLayout
|
||||
import androidx.compose.material.ModalBottomSheetValue
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AddCircle
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.rememberModalBottomSheetState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.focus.onFocusEvent
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.boundsInWindow
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.*
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
|
|
@ -47,15 +30,9 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.ui.library.LibraryViewModel
|
||||
import com.dokar.chiptextfield.*
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import kotlinx.coroutines.delay
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
|
||||
|
||||
|
|
@ -307,7 +284,7 @@ fun LabelsSelectionSheetContent(
|
|||
if (isLibraryMode) {
|
||||
currentLabel?.let {
|
||||
LabelChipView(it)
|
||||
} ?: null
|
||||
}
|
||||
} else {
|
||||
LabelChipView(findOrCreateLabel(labelsViewModel = labelsViewModel, labels = labels, name = it.text))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.*
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
|
@ -19,11 +12,7 @@ import javax.inject.Inject
|
|||
|
||||
|
||||
@HiltViewModel
|
||||
class LabelsViewModel @Inject constructor(
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val dataService: DataService,
|
||||
private val networker: Networker
|
||||
): ViewModel() {
|
||||
class LabelsViewModel @Inject constructor(): ViewModel() {
|
||||
val labelNameMaxLength = 64
|
||||
|
||||
enum class Error {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import app.omnivore.omnivore.graphql.generated.type.UpdatePageInput
|
|||
import app.omnivore.omnivore.ui.ResourceProvider
|
||||
import com.apollographql.apollo3.ApolloClient
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import com.pspdfkit.internal.sa
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -25,10 +24,10 @@ import kotlinx.coroutines.withContext
|
|||
import javax.inject.Inject
|
||||
|
||||
enum class EditInfoState {
|
||||
DEFAULT(),
|
||||
UPDATING(),
|
||||
ERROR(),
|
||||
UPDATED()
|
||||
DEFAULT,
|
||||
UPDATING,
|
||||
ERROR,
|
||||
UPDATED
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
package app.omnivore.omnivore.ui.library
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import androidx.compose.material.icons.outlined.Info
|
|||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
|
|
@ -214,7 +213,6 @@ fun LibraryNavigationBar(
|
|||
|
||||
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SearchField(
|
||||
searchText: String,
|
||||
|
|
@ -244,7 +242,7 @@ fun SearchField(
|
|||
navController.popBackStack()
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack,
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = "Back"
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ import app.omnivore.omnivore.ui.save.SaveViewModel
|
|||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun LibraryView(
|
||||
libraryViewModel: LibraryViewModel,
|
||||
|
|
@ -56,9 +55,8 @@ fun LibraryView(
|
|||
val showEditInfoSheet: Boolean by libraryViewModel.showEditInfoSheetLiveData.observeAsState(false)
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(
|
||||
ModalBottomSheetValue.Hidden,
|
||||
confirmStateChange = { it != ModalBottomSheetValue.Hidden }
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden,
|
||||
confirmValueChange = { it != ModalBottomSheetValue.Hidden }
|
||||
)
|
||||
|
||||
if (showLabelsSelectionSheet || showAddLinkSheet || showEditInfoSheet) {
|
||||
|
|
|
|||
|
|
@ -1,29 +1,17 @@
|
|||
package app.omnivore.omnivore.ui.library
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.*
|
||||
import app.omnivore.omnivore.*
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.*
|
||||
import app.omnivore.omnivore.ui.ResourceProvider
|
||||
import app.omnivore.omnivore.ui.setSavedItemLabels
|
||||
import coil.util.CoilUtils.result
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
|
@ -71,9 +59,9 @@ class LibraryViewModel @Inject constructor(
|
|||
override val actionsMenuItemLiveData = MutableLiveData<SavedItemWithLabelsAndHighlights?>(null)
|
||||
|
||||
var isRefreshing by mutableStateOf(false)
|
||||
var hasLoadedInitialFilters = false
|
||||
private var hasLoadedInitialFilters = false
|
||||
|
||||
fun loadInitialFilterValues() {
|
||||
private fun loadInitialFilterValues() {
|
||||
if (hasLoadedInitialFilters) { return }
|
||||
hasLoadedInitialFilters = false
|
||||
|
||||
|
|
@ -101,10 +89,10 @@ class LibraryViewModel @Inject constructor(
|
|||
cursor = null
|
||||
librarySearchCursor = null
|
||||
isRefreshing = true
|
||||
load(true)
|
||||
load()
|
||||
}
|
||||
|
||||
fun getLastSyncTime(): Instant? = runBlocking {
|
||||
private fun getLastSyncTime(): Instant? = runBlocking {
|
||||
datastoreRepo.getString(DatastoreKeys.libraryLastSyncTimestamp)?.let {
|
||||
try {
|
||||
return@let Instant.parse(it)
|
||||
|
|
@ -127,7 +115,7 @@ class LibraryViewModel @Inject constructor(
|
|||
load()
|
||||
}
|
||||
|
||||
fun load(clearPreviousSearch: Boolean = false) {
|
||||
fun load() {
|
||||
loadInitialFilterValues()
|
||||
|
||||
viewModelScope.launch {
|
||||
|
|
@ -182,12 +170,13 @@ class LibraryViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun sortKey(appliedSortKey: String) {
|
||||
when(appliedSortKey) {
|
||||
// fun sortKey(appliedSortKey: String) {
|
||||
// when(appliedSortKey) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
fun handleFilterChanges() {
|
||||
private fun handleFilterChanges() {
|
||||
librarySearchCursor = null
|
||||
|
||||
if (appliedSortFilterLiveData.value != null && appliedFilterLiveData.value != null) {
|
||||
|
|
@ -216,7 +205,7 @@ class LibraryViewModel @Inject constructor(
|
|||
else -> (activeLabelsLiveData.value ?: listOf()).map { it.name }
|
||||
}
|
||||
|
||||
activeLabelsLiveData.value?.let {
|
||||
activeLabelsLiveData.value?.let { it ->
|
||||
requiredLabels = requiredLabels + it.map { it.name }
|
||||
}
|
||||
|
||||
|
|
@ -304,9 +293,6 @@ class LibraryViewModel @Inject constructor(
|
|||
currentItemLiveData.value = itemID
|
||||
showEditInfoSheetLiveData.value = true
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
actionsMenuItemLiveData.postValue(null)
|
||||
}
|
||||
|
|
@ -321,10 +307,10 @@ class LibraryViewModel @Inject constructor(
|
|||
labels = labels
|
||||
)
|
||||
|
||||
if (result) {
|
||||
snackbarMessage = resourceProvider.getString(R.string.library_view_model_snackbar_success)
|
||||
snackbarMessage = if (result) {
|
||||
resourceProvider.getString(R.string.library_view_model_snackbar_success)
|
||||
} else {
|
||||
snackbarMessage = resourceProvider.getString(R.string.library_view_model_snackbar_error)
|
||||
resourceProvider.getString(R.string.library_view_model_snackbar_error)
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ enum class SavedItemFilter(val displayText: String, val rawValue: String, val qu
|
|||
READ_LATER("Non-Feed Items", "nonFeed", "no:subscription"),
|
||||
FEEDS("Feeds", "feeds", "in:inbox label:RSS"),
|
||||
NEWSLETTERS("Newsletters", "newsletters", "in:inbox label:Newsletter"),
|
||||
RECOMMENDED("Recommended", "recommended", "recommendedBy:*"),
|
||||
// RECOMMENDED("Recommended", "recommended", "recommendedBy:*"),
|
||||
ALL("All", "all", "in:all"),
|
||||
ARCHIVED("Archived", "archived", "in:archive"),
|
||||
HAS_HIGHLIGHTS("Highlighted", "hasHighlights", "has:highlights"),
|
||||
// HAS_HIGHLIGHTS("Highlighted", "hasHighlights", "has:highlights"),
|
||||
FILES("Files", "files", "type:file"),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
|
|
@ -53,7 +52,7 @@ fun SearchView(
|
|||
viewModel.actionsMenuItemLiveData.postValue(null)
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack,
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
modifier = Modifier,
|
||||
contentDescription = "Back"
|
||||
)
|
||||
|
|
@ -134,7 +133,6 @@ fun SearchView(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun TypeaheadSearchViewContent(viewModel: SearchViewModel, modifier: Modifier) {
|
||||
val context = LocalContext.current
|
||||
|
|
@ -167,7 +165,6 @@ fun TypeaheadSearchViewContent(viewModel: SearchViewModel, modifier: Modifier) {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun SearchViewContent(viewModel: SearchViewModel, modifier: Modifier) {
|
||||
val context = LocalContext.current
|
||||
|
|
|
|||
|
|
@ -1,24 +1,16 @@
|
|||
package app.omnivore.omnivore.ui.library
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.omnivore.omnivore.*
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.*
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import java.time.Instant
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -71,7 +63,7 @@ class SearchViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun loadUsingSearchAPI() {
|
||||
private fun loadUsingSearchAPI() {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val result = dataService.librarySearch(cursor = librarySearchCursor, query = searchQueryString())
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights
|
||||
import app.omnivore.omnivore.ui.library.*
|
||||
import dev.jeziellago.compose.markdowntext.MarkdownText
|
||||
import kotlinx.coroutines.launch
|
||||
import app.omnivore.omnivore.persistence.entities.Highlight
|
||||
|
|
@ -71,7 +70,7 @@ fun notebookMD(notes: List<Highlight>, highlights: List<Highlight>): String {
|
|||
return result
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote: (note: Highlight?) -> Unit) {
|
||||
var isMenuOpen by remember {
|
||||
|
|
@ -109,7 +108,7 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
|||
}
|
||||
if (isMenuOpen) {
|
||||
DropdownMenu(
|
||||
expanded = isMenuOpen,
|
||||
expanded = true,
|
||||
onDismissRequest = { isMenuOpen = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
|
|
@ -117,7 +116,7 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
|||
onClick = {
|
||||
val clip = ClipData.newPlainText("notebook", notebookMD(notes, highlights))
|
||||
clipboard?.let {
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
} ?: run {
|
||||
coroutineScope.launch {
|
||||
snackBarHostState
|
||||
|
|
@ -141,20 +140,20 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
|||
.padding(top = paddingValues.calculateTopPadding())
|
||||
) {
|
||||
savedItem.value?.let {
|
||||
ArticleNotes(viewModel, it, onEditNote)
|
||||
ArticleNotes(it, onEditNote)
|
||||
HighlightsList(it, onEditNote)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditNoteModal(initialValue: String?, onDismiss: (save: Boolean, text: String?) -> Unit) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val annotation = rememberSaveable { mutableStateOf(initialValue ?: "") }
|
||||
|
||||
BottomSheetUI() {
|
||||
BottomSheetUI {
|
||||
MaterialTheme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
|
|
@ -202,10 +201,9 @@ fun EditNoteModal(initialValue: String?, onDismiss: (save: Boolean, text: String
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun ArticleNotes(viewModel: NotebookViewModel, item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Highlight?) -> Unit) {
|
||||
val notes = item.highlights?.filter { it.type == "NOTE" } ?: listOf()
|
||||
fun ArticleNotes(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Highlight?) -> Unit) {
|
||||
val notes = item.highlights.filter { it.type == "NOTE" }
|
||||
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -251,7 +249,7 @@ fun ArticleNotes(viewModel: NotebookViewModel, item: SavedItemWithLabelsAndHighl
|
|||
|
||||
@Composable
|
||||
fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Highlight?) -> Unit) {
|
||||
val highlights = item.highlights?.filter { it.type == "HIGHLIGHT" } ?: listOf()
|
||||
val highlights = item.highlights.filter { it.type == "HIGHLIGHT" }
|
||||
val yellowColor = colorResource(R.color.cta_yellow)
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
|
@ -286,7 +284,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
|||
}
|
||||
if (isMenuOpen) {
|
||||
DropdownMenu(
|
||||
expanded = isMenuOpen,
|
||||
expanded = true,
|
||||
onDismissRequest = { isMenuOpen = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
|
|
@ -294,7 +292,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
|||
onClick = {
|
||||
val clip = ClipData.newPlainText("highlight", highlight.quote)
|
||||
clipboard?.let {
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
} ?: run {
|
||||
coroutineScope.launch {
|
||||
snackBarHostState
|
||||
|
|
@ -381,10 +379,9 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun BottomSheetUI(content: @Composable () -> Unit) {
|
||||
OmnivoreTheme() {
|
||||
OmnivoreTheme {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.wrapContentHeight()
|
||||
|
|
@ -393,8 +390,7 @@ fun BottomSheetUI(content: @Composable () -> Unit) {
|
|||
.background(Color.Transparent)
|
||||
.statusBarsPadding()
|
||||
) {
|
||||
Scaffold(
|
||||
) { paddingValues ->
|
||||
Scaffold { paddingValues ->
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
content()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,16 @@
|
|||
package app.omnivore.omnivore.ui.notebook
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import androidx.room.Query
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.dataService.DataService
|
||||
import app.omnivore.omnivore.dataService.createNoteHighlight
|
||||
import app.omnivore.omnivore.dataService.updateWebHighlight
|
||||
import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.Networker
|
||||
import app.omnivore.omnivore.networking.updateHighlight
|
||||
import app.omnivore.omnivore.persistence.entities.Highlight
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights
|
||||
import app.omnivore.omnivore.ui.library.SavedItemViewModel
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -24,7 +18,6 @@ import javax.inject.Inject
|
|||
class NotebookViewModel @Inject constructor(
|
||||
private val networker: Networker,
|
||||
private val dataService: DataService,
|
||||
private val datastoreRepo: DatastoreRepository
|
||||
): ViewModel() {
|
||||
var highlightUnderEdit: Highlight? = null
|
||||
|
||||
|
|
@ -34,8 +27,8 @@ class NotebookViewModel @Inject constructor(
|
|||
|
||||
suspend fun addArticleNote(savedItemId: String, note: String) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val item = dataService.db.savedItemDao().getById(savedItemId)
|
||||
item?.let { item ->
|
||||
val savedItem = dataService.db.savedItemDao().getById(savedItemId)
|
||||
savedItem?.let { item ->
|
||||
val noteHighlight = item.highlights.firstOrNull { it.type == "NOTE" }
|
||||
noteHighlight?.let {
|
||||
dataService.db.highlightDao()
|
||||
|
|
|
|||
|
|
@ -1,19 +1,11 @@
|
|||
package app.omnivore.omnivore.ui.reader
|
||||
|
||||
import android.R
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.fragment.app.DialogFragment
|
||||
|
|
@ -21,8 +13,6 @@ import app.omnivore.omnivore.ui.notebook.EditNoteModal
|
|||
import app.omnivore.omnivore.ui.theme.OmnivoreTheme
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
|
||||
|
||||
class AnnotationEditFragment : DialogFragment() {
|
||||
private var onSave: (String) -> Unit = {}
|
||||
|
|
@ -43,7 +33,7 @@ class AnnotationEditFragment : DialogFragment() {
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
): View {
|
||||
|
||||
return ComposeView(requireContext()).apply {
|
||||
|
||||
|
|
@ -58,8 +48,6 @@ class AnnotationEditFragment : DialogFragment() {
|
|||
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
val annotation = remember { mutableStateOf(initialAnnotation ?: "") }
|
||||
|
||||
OmnivoreTheme {
|
||||
EditNoteModal(initialValue = initialAnnotation, onDismiss = { save, text ->
|
||||
if (save) {
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener, TextSelectionMan
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onBackPressed() {
|
||||
when {
|
||||
modularSearchView.isDisplayed -> {
|
||||
|
|
@ -290,7 +291,7 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener, TextSelectionMan
|
|||
}
|
||||
|
||||
override fun onEnterTextSelectionMode(p0: TextSelectionController) {
|
||||
val textRects = p0?.textSelection?.textBlocks ?: return
|
||||
val textRects = p0.textSelection?.textBlocks ?: return
|
||||
val pageIndex = p0.textSelection?.pageIndex ?: return
|
||||
pendingHighlightAnnotation = HighlightAnnotation(pageIndex, textRects)
|
||||
textSelectionController = p0
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import android.util.Log
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.dataService.DataService
|
||||
import app.omnivore.omnivore.dataService.NanoId
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput
|
||||
|
|
@ -20,7 +19,6 @@ import com.pspdfkit.annotations.Annotation
|
|||
import com.pspdfkit.annotations.HighlightAnnotation
|
||||
import com.pspdfkit.document.download.DownloadJob
|
||||
import com.pspdfkit.document.download.DownloadRequest
|
||||
import com.pspdfkit.document.download.Progress
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -29,9 +27,6 @@ import org.json.JSONObject
|
|||
import java.io.File
|
||||
import java.lang.Double.max
|
||||
import java.lang.Double.min
|
||||
import java.lang.Exception
|
||||
import java.net.URLEncoder
|
||||
import java.nio.file.FileSystem
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -43,7 +38,6 @@ data class PDFReaderParams(
|
|||
|
||||
@HiltViewModel
|
||||
class PDFReaderViewModel @Inject constructor(
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val dataService: DataService,
|
||||
private val networker: Networker
|
||||
): ViewModel() {
|
||||
|
|
@ -62,23 +56,23 @@ class PDFReaderViewModel @Inject constructor(
|
|||
private suspend fun loadItemFromDB(slug: String) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val persistedItem = dataService.db.savedItemDao().getSavedItemWithLabelsAndHighlights(slug)
|
||||
persistedItem?.let { persistedItem ->
|
||||
persistedItem?.savedItem?.localPDF?.let { localPDF ->
|
||||
persistedItem?.let { item ->
|
||||
item.savedItem.localPDF?.let { localPDF ->
|
||||
val localFile = File(localPDF)
|
||||
|
||||
if (localFile.exists()) {
|
||||
val articleContent = ArticleContent(
|
||||
title = persistedItem.savedItem.title,
|
||||
title = item.savedItem.title,
|
||||
htmlContent = "",
|
||||
highlights = persistedItem.highlights,
|
||||
highlights = item.highlights,
|
||||
contentStatus = "SUCCEEDED",
|
||||
objectID = "",
|
||||
labelsJSONString = Gson().toJson(persistedItem.labels)
|
||||
labelsJSONString = Gson().toJson(item.labels)
|
||||
)
|
||||
|
||||
pdfReaderParamsLiveData.postValue(
|
||||
PDFReaderParams(
|
||||
persistedItem.savedItem,
|
||||
item.savedItem,
|
||||
articleContent,
|
||||
Uri.fromFile(localFile)
|
||||
)
|
||||
|
|
@ -192,7 +186,7 @@ class PDFReaderViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
if (note != null) {
|
||||
storeUpdatedNoteLocally(newAnnotation, note!!)
|
||||
storeUpdatedNoteLocally(newAnnotation, note)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@ package app.omnivore.omnivore.ui.reader
|
|||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.Text
|
||||
|
|
@ -46,7 +44,7 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
|||
|
||||
val themeState = remember { mutableStateOf(currentWebPreferences.storedThemePreference) }
|
||||
|
||||
OmnivoreTheme() {
|
||||
OmnivoreTheme {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 15.dp)
|
||||
|
|
@ -169,11 +167,11 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
|||
onCheckedChange = {
|
||||
if (it) {
|
||||
themeState.value = "System"
|
||||
webReaderViewModel.updateStoredThemePreference("System", isDark)
|
||||
webReaderViewModel.updateStoredThemePreference("System")
|
||||
} else {
|
||||
val newThemeKey = if (isDark) "Black" else "Light"
|
||||
themeState.value = newThemeKey
|
||||
webReaderViewModel.updateStoredThemePreference(newThemeKey, isDark)
|
||||
webReaderViewModel.updateStoredThemePreference(newThemeKey)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -188,7 +186,7 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
|||
Button(
|
||||
onClick = {
|
||||
themeState.value = theme.themeKey
|
||||
webReaderViewModel.updateStoredThemePreference(theme.themeKey, isDark)
|
||||
webReaderViewModel.updateStoredThemePreference(theme.themeKey)
|
||||
},
|
||||
shape = CircleShape,
|
||||
border = BorderStroke(3.dp, if (isSelected) colorResource(R.color.cta_yellow) else Color.Transparent),
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ fun WebReader(
|
|||
|
||||
WebView.setWebContentsDebuggingEnabled(true)
|
||||
|
||||
val showHighlightColorPalette = webReaderViewModel.showHighlightColorPalette.observeAsState()
|
||||
val highlightColor = webReaderViewModel.highlightColor.observeAsState()
|
||||
// val showHighlightColorPalette = webReaderViewModel.showHighlightColorPalette.observeAsState()
|
||||
// val highlightColor = webReaderViewModel.highlightColor.observeAsState()
|
||||
|
||||
Box {
|
||||
AndroidView(factory = {
|
||||
|
|
@ -106,7 +106,7 @@ fun WebReader(
|
|||
): Boolean {
|
||||
var handled: Boolean? = null
|
||||
request?.let {
|
||||
if ((request?.isForMainFrame == true) && (request?.hasGesture() == true) && viewModel != null) {
|
||||
if (request.isForMainFrame && request.hasGesture() && viewModel != null) {
|
||||
viewModel?.showOpenLinkSheet(context, request.url)
|
||||
handled = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,8 +86,6 @@ class WebReaderLoadingContainerActivity: ComponentActivity() {
|
|||
Text(stringResource(R.string.web_reader_loading_container_error_msg))
|
||||
} else {
|
||||
WebReaderLoadingContainer(
|
||||
requestID = requestID,
|
||||
slug = slug,
|
||||
onLibraryIconTap = if (requestID != null) { { startMainActivity() } } else null,
|
||||
webReaderViewModel = viewModel,
|
||||
notebookViewModel = notebookViewModel,
|
||||
|
|
@ -115,23 +113,21 @@ class WebReaderLoadingContainerActivity: ComponentActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
enum class BottomSheetState(
|
||||
) {
|
||||
NONE(),
|
||||
PREFERENCES(),
|
||||
NOTEBOOK(),
|
||||
EDITNOTE(),
|
||||
HIGHLIGHTNOTE(),
|
||||
LABELS(),
|
||||
LINK(),
|
||||
EDIT_INFO(),
|
||||
enum class BottomSheetState {
|
||||
NONE,
|
||||
PREFERENCES,
|
||||
NOTEBOOK,
|
||||
EDITNOTE,
|
||||
HIGHLIGHTNOTE,
|
||||
LABELS,
|
||||
LINK,
|
||||
EDIT_INFO,
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
||||
onLibraryIconTap: (() -> Unit)? = null,
|
||||
fun WebReaderLoadingContainer(onLibraryIconTap: (() -> Unit)? = null,
|
||||
webReaderViewModel: WebReaderViewModel,
|
||||
notebookViewModel: NotebookViewModel,
|
||||
labelsViewModel: LabelsViewModel,
|
||||
|
|
@ -158,7 +154,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
articleContent = it.articleContent,
|
||||
)
|
||||
webReaderContent.styledContent()
|
||||
} ?: null
|
||||
}
|
||||
|
||||
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(
|
||||
|
|
@ -206,13 +202,13 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
sheetContent = {
|
||||
when (bottomSheetState) {
|
||||
BottomSheetState.PREFERENCES -> {
|
||||
BottomSheetUI(stringResource(R.string.web_reader_loading_container_bottom_sheet_reader_preferences)) {
|
||||
BottomSheetUI {
|
||||
ReaderPreferencesView(webReaderViewModel)
|
||||
}
|
||||
}
|
||||
BottomSheetState.NOTEBOOK -> {
|
||||
webReaderParams?.let { params ->
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_notebook)) {
|
||||
BottomSheetUI {
|
||||
NotebookView(savedItemId = params.item.savedItemId, viewModel = notebookViewModel, onEditNote = {
|
||||
notebookViewModel.highlightUnderEdit = it
|
||||
webReaderViewModel.setBottomSheet(BottomSheetState.EDITNOTE)
|
||||
|
|
@ -261,7 +257,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
)
|
||||
}
|
||||
BottomSheetState.LABELS -> {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_notebook)) {
|
||||
BottomSheetUI {
|
||||
LabelsSelectionSheetContent(
|
||||
labels = labels,
|
||||
labelsViewModel = labelsViewModel,
|
||||
|
|
@ -289,7 +285,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
}
|
||||
}
|
||||
BottomSheetState.EDIT_INFO -> {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_edit_info)) {
|
||||
BottomSheetUI {
|
||||
EditInfoSheetContent(
|
||||
savedItemId = webReaderParams?.item?.savedItemId,
|
||||
title = webReaderParams?.item?.title,
|
||||
|
|
@ -311,7 +307,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
}
|
||||
}
|
||||
BottomSheetState.LINK -> {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_open_link)) {
|
||||
BottomSheetUI {
|
||||
OpenLinkView(webReaderViewModel)
|
||||
}
|
||||
}
|
||||
|
|
@ -346,7 +342,6 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ReaderTopAppBar(webReaderViewModel: WebReaderViewModel, onLibraryIconTap: (() -> Unit)? = null) {
|
||||
val context = LocalContext.current
|
||||
|
|
@ -365,7 +360,7 @@ fun ReaderTopAppBar(webReaderViewModel: WebReaderViewModel, onLibraryIconTap: ((
|
|||
} else if (it.themeKey == "System" ) {
|
||||
Color(0xFFFFFFFF)
|
||||
} else {
|
||||
Color(it.backgroundColor ?: 0xFFFFFFFF)
|
||||
Color(it.backgroundColor)
|
||||
}
|
||||
} ?: Color(0xFFFFFFFF)
|
||||
|
||||
|
|
@ -440,7 +435,7 @@ fun ReaderTopAppBar(webReaderViewModel: WebReaderViewModel, onLibraryIconTap: ((
|
|||
webReaderParams?.let { params ->
|
||||
SavedItemContextMenu(
|
||||
context = context,
|
||||
isExpanded = isMenuExpanded,
|
||||
isExpanded = true,
|
||||
isArchived = params.item.isArchived,
|
||||
onDismiss = { isMenuExpanded = false },
|
||||
webReaderViewModel = webReaderViewModel,
|
||||
|
|
@ -458,9 +453,8 @@ fun ReaderTopAppBar(webReaderViewModel: WebReaderViewModel, onLibraryIconTap: ((
|
|||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun BottomSheetUI(title: String?, content: @Composable () -> Unit) {
|
||||
fun BottomSheetUI(content: @Composable () -> Unit) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.wrapContentHeight()
|
||||
|
|
@ -469,8 +463,7 @@ fun BottomSheetUI(title: String?, content: @Composable () -> Unit) {
|
|||
.background(Color.White)
|
||||
.statusBarsPadding()
|
||||
) {
|
||||
Scaffold(
|
||||
) { paddingValues ->
|
||||
Scaffold { paddingValues ->
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
content()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,16 +15,12 @@ import app.omnivore.omnivore.EventTracker
|
|||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemAndSavedItemLabelCrossRef
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.ui.components.HighlightColor
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import app.omnivore.omnivore.ui.setSavedItemLabels
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
|
@ -76,14 +72,14 @@ class WebReaderViewModel @Inject constructor(
|
|||
val savedItemLabelsLiveData = dataService.db.savedItemLabelDao().getSavedItemLabelsLiveData()
|
||||
|
||||
var currentLink: Uri? = null
|
||||
val bottomSheetStateLiveData = MutableLiveData<BottomSheetState>(BottomSheetState.NONE)
|
||||
val bottomSheetStateLiveData = MutableLiveData(BottomSheetState.NONE)
|
||||
|
||||
var hasTappedExistingHighlight = false
|
||||
var lastTapCoordinates: TapCoordinates? = null
|
||||
private var isLoading = false
|
||||
private var slug: String? = null
|
||||
|
||||
val showHighlightColorPalette = MutableLiveData(false)
|
||||
private val showHighlightColorPalette = MutableLiveData(false)
|
||||
val highlightColor = MutableLiveData(HighlightColor())
|
||||
|
||||
fun loadItem(slug: String?, requestID: String?) {
|
||||
|
|
@ -139,7 +135,7 @@ class WebReaderViewModel @Inject constructor(
|
|||
bottomSheetStateLiveData.postValue(BottomSheetState.NONE)
|
||||
}
|
||||
|
||||
fun openLink(context: Context, uri: Uri) {
|
||||
private fun openLink(context: Context, uri: Uri) {
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||
startActivity(context, browserIntent, null)
|
||||
}
|
||||
|
|
@ -164,11 +160,11 @@ class WebReaderViewModel @Inject constructor(
|
|||
val clipboard =
|
||||
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.setPrimaryClip(clip)
|
||||
clipboard?.let {
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
Toast.makeText(context,
|
||||
context.getString(R.string.web_reader_view_model_copy_link_success),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
clipboard.let {
|
||||
clipboard.setPrimaryClip(clip)
|
||||
Toast.makeText(context,
|
||||
context.getString(R.string.web_reader_view_model_copy_link_success),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
bottomSheetStateLiveData.postValue(BottomSheetState.NONE)
|
||||
|
|
@ -321,11 +317,11 @@ class WebReaderViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun setHighlightColor(color: HighlightColor) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
highlightColor.postValue(color)
|
||||
}
|
||||
}
|
||||
// fun setHighlightColor(color: HighlightColor) {
|
||||
// CoroutineScope(Dispatchers.Main).launch {
|
||||
// highlightColor.postValue(color)
|
||||
// }
|
||||
// }
|
||||
|
||||
fun handleIncomingWebMessage(actionID: String, jsonString: String) {
|
||||
when (actionID) {
|
||||
|
|
@ -396,7 +392,7 @@ class WebReaderViewModel @Inject constructor(
|
|||
cancelAnnotationEdit()
|
||||
}
|
||||
|
||||
fun cancelAnnotationEdit() {
|
||||
private fun cancelAnnotationEdit() {
|
||||
annotation = null
|
||||
resetBottomSheet()
|
||||
}
|
||||
|
|
@ -443,8 +439,8 @@ class WebReaderViewModel @Inject constructor(
|
|||
return storedThemePreference
|
||||
}
|
||||
|
||||
fun updateStoredThemePreference(newThemeKey: String, isDarkMode: Boolean) {
|
||||
Log.d("theme", "Setting theme key: ${newThemeKey}")
|
||||
fun updateStoredThemePreference(newThemeKey: String) {
|
||||
Log.d("theme", "Setting theme key: $newThemeKey")
|
||||
|
||||
runBlocking {
|
||||
datastoreRepo.putString(DatastoreKeys.preferredTheme, newThemeKey)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.root
|
||||
|
||||
import SettingsView
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
|
|
@ -24,6 +23,7 @@ import app.omnivore.omnivore.ui.library.LibraryViewModel
|
|||
import app.omnivore.omnivore.ui.library.SearchViewModel
|
||||
import app.omnivore.omnivore.ui.save.SaveViewModel
|
||||
import app.omnivore.omnivore.ui.settings.PolicyWebView
|
||||
import app.omnivore.omnivore.ui.settings.SettingsView
|
||||
import app.omnivore.omnivore.ui.settings.SettingsViewModel
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package app.omnivore.omnivore.ui.save
|
||||
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.MaterialTheme
|
||||
|
|
@ -16,9 +15,7 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.MainActivity
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.reader.PDFReaderActivity
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -29,7 +26,7 @@ fun SaveContent(viewModel: SaveViewModel, modalBottomSheetState: ModalBottomShee
|
|||
val context = LocalContext.current
|
||||
val enableReadNow = false
|
||||
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
|
||||
Surface(modifier = modifier, color = MaterialTheme.colors.background) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
|
|
|
|||
|
|
@ -4,42 +4,22 @@ import android.content.ContentValues
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.TextView.SavedState
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
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.material.icons.outlined.Close
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.rounded.AddCircle
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material3.BottomAppBarDefaults
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment.Companion.TopCenter
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -48,7 +28,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||
|
||||
// Not sure why we need this class, but directly opening SaveSheetActivity
|
||||
// causes the app to crash.
|
||||
class SaveSheetActivity : SaveSheetActivityBase() {}
|
||||
class SaveSheetActivity : SaveSheetActivityBase()
|
||||
|
||||
@AndroidEntryPoint
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
|
|
@ -57,7 +37,7 @@ abstract class SaveSheetActivityBase : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
|
||||
val viewModel: SaveViewModel by viewModels()
|
||||
var extractedText: String? = null
|
||||
var extractedText: String?
|
||||
|
||||
when (intent?.action) {
|
||||
Intent.ACTION_SEND -> {
|
||||
|
|
@ -208,8 +188,4 @@ abstract class SaveSheetActivityBase : AppCompatActivity() {
|
|||
super.onPause()
|
||||
overridePendingTransition(0, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = SaveSheetActivity::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.save
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.util.Log
|
||||
import android.util.Patterns
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -27,10 +25,10 @@ import java.util.regex.Pattern
|
|||
import javax.inject.Inject
|
||||
|
||||
enum class SaveState {
|
||||
DEFAULT(),
|
||||
SAVING(),
|
||||
ERROR(),
|
||||
SAVED()
|
||||
DEFAULT,
|
||||
SAVING,
|
||||
ERROR,
|
||||
SAVED
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
|
|
|
|||
|
|
@ -1,24 +1,14 @@
|
|||
package app.omnivore.omnivore.ui.savedItemViews
|
||||
|
||||
import LabelChip
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.SuggestionChipDefaults.elevatedSuggestionChipColors
|
||||
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.focus.focusTarget
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
|
|
@ -31,9 +21,9 @@ import androidx.compose.ui.unit.*
|
|||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights
|
||||
import app.omnivore.omnivore.ui.components.LabelChip
|
||||
import app.omnivore.omnivore.ui.components.LabelChipColors
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import app.omnivore.omnivore.ui.library.SavedItemFilter
|
||||
import app.omnivore.omnivore.ui.library.SavedItemViewModel
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
|
||||
|
|
@ -74,7 +64,7 @@ fun SavedItemCard(
|
|||
.padding(end = 20.dp)
|
||||
.defaultMinSize(minHeight = 55.dp)
|
||||
) {
|
||||
readInfo(item = savedItem)
|
||||
ReadInfo(item = savedItem)
|
||||
|
||||
Text(
|
||||
text = savedItem.savedItem.title,
|
||||
|
|
@ -154,7 +144,7 @@ fun byline(item: SavedItemWithLabelsAndHighlights): String {
|
|||
fun estimatedReadingTime(item: SavedItemWithLabelsAndHighlights): String {
|
||||
item.savedItem.wordsCount?.let {
|
||||
if (it > 0) {
|
||||
val readLen = Math.max(1, it / 235)
|
||||
val readLen = kotlin.math.max(1, it / 235)
|
||||
return "$readLen MIN READ • "
|
||||
}
|
||||
}
|
||||
|
|
@ -203,9 +193,9 @@ fun readingProgress(item: SavedItemWithLabelsAndHighlights): String {
|
|||
//}
|
||||
|
||||
|
||||
public enum class FlairIcon(
|
||||
public val rawValue: String,
|
||||
public val sortOrder: Int
|
||||
enum class FlairIcon(
|
||||
val rawValue: String,
|
||||
val sortOrder: Int
|
||||
) {
|
||||
FEED("feed", 0),
|
||||
RSS("rss", 0),
|
||||
|
|
@ -279,7 +269,7 @@ fun flairIcons(item: SavedItemWithLabelsAndHighlights) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun readInfo(item: SavedItemWithLabelsAndHighlights) {
|
||||
fun ReadInfo(item: SavedItemWithLabelsAndHighlights) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -2,17 +2,14 @@ package app.omnivore.omnivore.ui.savedItemViews
|
|||
|
||||
import android.content.Context
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.CheckCircle
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.List
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.omnivore.omnivore.R
|
||||
|
|
|
|||
|
|
@ -2,28 +2,18 @@ package app.omnivore.omnivore.ui.savedItemViews
|
|||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.SuggestionChipDefaults.elevatedSuggestionChipColors
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.*
|
||||
import app.omnivore.omnivore.persistence.entities.TypeaheadCardData
|
||||
import app.omnivore.omnivore.ui.components.LabelChipColors
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class,
|
||||
)
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun TypeaheadSearchCard(cardData: TypeaheadCardData, onClickHandler: () -> Unit, actionHandler: (SavedItemAction) -> Unit) {
|
||||
Column(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ fun PolicyWebView(navController: NavHostController, url: String) {
|
|||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { androidx.compose.material3.Text(stringResource(R.string.policy_webview_title)) },
|
||||
title = { Text(stringResource(R.string.policy_webview_title)) },
|
||||
actions = {
|
||||
IconButton(onClick = { navController.navigate(Routes.Settings.route) }) {
|
||||
Icon(
|
||||
|
|
|
|||
|
|
@ -1,36 +1,23 @@
|
|||
import android.util.Log
|
||||
package app.omnivore.omnivore.ui.settings
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowForward
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavHostController
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.Routes
|
||||
import app.omnivore.omnivore.networking.Networker
|
||||
import app.omnivore.omnivore.networking.viewer
|
||||
import app.omnivore.omnivore.ui.auth.LoginViewModel
|
||||
import app.omnivore.omnivore.ui.settings.LogoutDialog
|
||||
import app.omnivore.omnivore.ui.settings.ManageAccountDialog
|
||||
import app.omnivore.omnivore.ui.settings.SettingsViewModel
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
import io.intercom.android.sdk.Intercom
|
||||
import io.intercom.android.sdk.IntercomSpace
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ class SettingsViewModel @Inject constructor(
|
|||
fun presentIntercom() {
|
||||
viewModelScope.launch {
|
||||
val viewer = networker.viewer()
|
||||
viewer?.let { viewer ->
|
||||
viewer?.intercomHash?.let { intercomHash ->
|
||||
viewer?.let { v ->
|
||||
v.intercomHash?.let { intercomHash ->
|
||||
Intercom.client().setUserHash(intercomHash)
|
||||
}
|
||||
Intercom.client().present(space = IntercomSpace.Messages)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.theme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.os.Build
|
|||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
||||
private val LightColors = lightColorScheme(
|
||||
primary = md_theme_light_primary,
|
||||
|
|
|
|||
Loading…
Reference in a new issue