android: resolve issues and warnings

Signed-off-by: Remy Chantenay <remy.chantenay@gmail.com>
This commit is contained in:
Remy Chantenay 2023-12-20 11:28:43 +01:00
parent 78307b7149
commit ac47aaaee6
No known key found for this signature in database
GPG key ID: 74E0BA32424AB3DA
47 changed files with 144 additions and 345 deletions

View file

@ -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>

View file

@ -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

View file

@ -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?) {

View file

@ -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.*

View file

@ -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

View file

@ -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
)
)

View file

@ -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),

View file

@ -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.*

View file

@ -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

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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),

View file

@ -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))
}

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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"
)
}

View file

@ -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) {

View file

@ -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 {

View file

@ -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"),
}

View 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

View file

@ -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())

View file

@ -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()
}

View file

@ -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()

View file

@ -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) {

View file

@ -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

View file

@ -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)
}
}
}

View file

@ -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),

View file

@ -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
}

View file

@ -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()
}

View file

@ -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)

View file

@ -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

View file

@ -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,

View file

@ -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
}
}

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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(

View file

@ -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(

View file

@ -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

View file

@ -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)

View file

@ -1,5 +1,5 @@
package app.omnivore.omnivore.ui.theme
import androidx.compose.material3.darkColorScheme
import androidx.compose.ui.graphics.Color
//

View file

@ -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,