diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt index 5505cd6bb..de19c8193 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt @@ -43,6 +43,8 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) { val themeState = remember { mutableStateOf(currentWebPreferences.storedThemePreference) } + val volumeForScrollState = remember { mutableStateOf(currentWebPreferences.shouldUseVolumeRockerForScroll) } + OmnivoreTheme { Column( modifier = Modifier @@ -239,6 +241,24 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) { } ) } + + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + stringResource(R.string.reader_preferences_view_volume_scroll), + style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137)) + ) + Spacer(modifier = Modifier.weight(1.0F)) + Switch ( + checked = volumeForScrollState.value, + onCheckedChange = { + volumeForScrollState.value = it + webReaderViewModel.updateVolumeRockerForScroll(it) + } + ) + } } } } @@ -285,5 +305,6 @@ data class WebPreferences( val storedThemePreference: String, val fontFamily: WebFont, val prefersHighContrastText: Boolean, - val prefersJustifyText: Boolean + val prefersJustifyText: Boolean, + var shouldUseVolumeRockerForScroll: Boolean ) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt index 988565701..e56d10853 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt @@ -170,11 +170,17 @@ fun WebReader( if (event.action == KeyEvent.ACTION_DOWN) { when (keyCode) { KeyEvent.KEYCODE_VOLUME_UP -> { + if (!webReaderViewModel.shouldUseVolumeRockerForScroll) { + return@setOnKeyListener false + } scrollVertically(OmnivoreWebView.Direction.UP) return@setOnKeyListener true } KeyEvent.KEYCODE_VOLUME_DOWN -> { + if (!webReaderViewModel.shouldUseVolumeRockerForScroll) { + return@setOnKeyListener false + } scrollVertically(OmnivoreWebView.Direction.DOWN) return@setOnKeyListener true } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt index 3d85d3069..c727f278a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt @@ -111,6 +111,8 @@ class WebReaderViewModel @Inject constructor( private val showHighlightColorPalette = MutableLiveData(false) val highlightColor = MutableLiveData(HighlightColor()) + var shouldUseVolumeRockerForScroll = true + fun loadItem(slug: String?, requestID: String?) { this.slug = slug if (isLoading || webReaderParamsLiveData.value != null) { @@ -474,7 +476,8 @@ class WebReaderViewModel @Inject constructor( val prefersHighContrastFont = datastoreRepo.getString(prefersWebHighContrastText) == "true" - val prefersJustifyText = datastoreRepo.getString(prefersJustifyText) == "true" + val prefersJustifyText = datastoreRepo.getString(DatastoreKeys.prefersJustifyText) == "true" + val shouldUseVolumeRockerForScroll = datastoreRepo.getString(DatastoreKeys.volumeForScroll) != "false" WebPreferences( textFontSize = storedFontSize ?: 12, @@ -484,7 +487,8 @@ class WebReaderViewModel @Inject constructor( storedThemePreference = storedThemePreference, fontFamily = storedWebFont, prefersHighContrastText = prefersHighContrastFont, - prefersJustifyText = prefersJustifyText + prefersJustifyText = prefersJustifyText, + shouldUseVolumeRockerForScroll = shouldUseVolumeRockerForScroll ) } @@ -560,6 +564,13 @@ class WebReaderViewModel @Inject constructor( enqueueScript(script) } + fun updateVolumeRockerForScroll(shouldUseVolumeRockerForScroll: Boolean) { + runBlocking { + datastoreRepo.putString(DatastoreKeys.volumeForScroll, shouldUseVolumeRockerForScroll.toString()) + } + this.shouldUseVolumeRockerForScroll = shouldUseVolumeRockerForScroll + } + fun applyWebFont(font: WebFont) { runBlocking { datastoreRepo.putString(preferredWebFontFamily, font.rawValue) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt index 90e23d8e1..054bdf646 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt @@ -3,8 +3,27 @@ package app.omnivore.omnivore.utils import app.omnivore.omnivore.BuildConfig object Constants { - const val apiURL = BuildConfig.OMNIVORE_API_URL - const val dataStoreName = "omnivore-datastore" + const val apiURL = BuildConfig.OMNIVORE_API_URL + const val dataStoreName = "omnivore-datastore" +} + +object DatastoreKeys { + const val omnivoreSelfHostedAPIServer = "omnivoreSelfHostedAPIServer" + const val omnivoreSelfHostedWebServer = "omnivoreSelfHostedWebServer" + const val omnivoreAuthToken = "omnivoreAuthToken" + const val omnivoreAuthCookieString = "omnivoreAuthCookieString" + const val omnivorePendingUserToken = "omnivorePendingUserToken" + const val libraryLastSyncTimestamp = "libraryLastSyncTimestamp" + const val preferredWebFontSize = "preferredWebFontSize" + const val preferredWebLineHeight = "preferredWebLineHeight" + const val preferredWebMaxWidthPercentage = "preferredWebMaxWidthPercentage" + const val preferredWebFontFamily = "preferredWebFontFamily" + const val prefersWebHighContrastText = "prefersWebHighContrastText" + const val prefersJustifyText = "prefersJustifyText" + const val lastUsedSavedItemFilter = "lastUsedSavedItemFilter" + const val lastUsedSavedItemSortFilter = "lastUsedSavedItemSortFilter" + const val preferredTheme = "preferredTheme" + const val volumeForScroll = "volumeForScroll" } object AppleConstants { diff --git a/android/Omnivore/app/src/main/res/values-de/strings.xml b/android/Omnivore/app/src/main/res/values-de/strings.xml index a613ffc21..6a26fea50 100644 --- a/android/Omnivore/app/src/main/res/values-de/strings.xml +++ b/android/Omnivore/app/src/main/res/values-de/strings.xml @@ -148,6 +148,7 @@ Text ausrichten + Verwenden Sie die Lautstärketasten zum Scrollen Wir konnten deinen Inhalt nicht abrufen. Lese-Einstellungen Notizbuch diff --git a/android/Omnivore/app/src/main/res/values-zh-rCN/strings.xml b/android/Omnivore/app/src/main/res/values-zh-rCN/strings.xml index 50d49b110..4086cda39 100644 --- a/android/Omnivore/app/src/main/res/values-zh-rCN/strings.xml +++ b/android/Omnivore/app/src/main/res/values-zh-rCN/strings.xml @@ -149,6 +149,7 @@ 对齐文字 + 使用音量按钮滚动 我们无法取得您的内容。 阅读器偏好设定 笔记 diff --git a/android/Omnivore/app/src/main/res/values-zh-rTW/strings.xml b/android/Omnivore/app/src/main/res/values-zh-rTW/strings.xml index 0565c5155..c56adc88e 100644 --- a/android/Omnivore/app/src/main/res/values-zh-rTW/strings.xml +++ b/android/Omnivore/app/src/main/res/values-zh-rTW/strings.xml @@ -148,6 +148,7 @@ 對齊文字 + 使用音量按鈕捲動 我們無法取得您的內容。 閱讀器偏好設定 筆記本 diff --git a/android/Omnivore/app/src/main/res/values/strings.xml b/android/Omnivore/app/src/main/res/values/strings.xml index 289c0a675..d190f4f75 100644 --- a/android/Omnivore/app/src/main/res/values/strings.xml +++ b/android/Omnivore/app/src/main/res/values/strings.xml @@ -153,6 +153,7 @@ Auto High Contrast Text Justify Text + Use Volume Rocker to scroll We were unable to fetch your content. diff --git a/packages/api/src/resolvers/importers/uploadImportFileResolver.ts b/packages/api/src/resolvers/importers/uploadImportFileResolver.ts index 0a1c0dd53..40d0fc529 100644 --- a/packages/api/src/resolvers/importers/uploadImportFileResolver.ts +++ b/packages/api/src/resolvers/importers/uploadImportFileResolver.ts @@ -16,7 +16,6 @@ import { generateUploadSignedUrl, } from '../../utils/uploads' -const MAX_DAILY_UPLOADS = 1 const VALID_CONTENT_TYPES = ['text/csv', 'application/zip'] const extensionForContentType = (contentType: string) => { @@ -61,6 +60,7 @@ export const uploadImportFileResolver = authorized< const dirPath = `imports/${uid}/${dateStr}/` const fileCount = await countOfFilesWithPrefix(dirPath) + const MAX_DAILY_UPLOADS = env.fileUpload.dailyUploadLimit if (fileCount >= MAX_DAILY_UPLOADS) { return { errorCodes: [UploadImportFileErrorCode.UploadDailyLimitExceeded], diff --git a/packages/api/src/util.ts b/packages/api/src/util.ts index d42f84ce1..ee427c603 100755 --- a/packages/api/src/util.ts +++ b/packages/api/src/util.ts @@ -81,6 +81,7 @@ export interface BackendEnv { gcsUploadBucket: string gcsUploadSAKeyFilePath: string gcsUploadPrivateBucket: string + dailyUploadLimit: number } sender: { message: string @@ -144,6 +145,7 @@ const nullableEnvVars = [ 'POSTHOG_API_KEY', 'TWITTER_BEARER_TOKEN', 'GCS_UPLOAD_PRIVATE_BUCKET', + 'GCS_UPLOAD_DAILY_LIMIT', 'SENDER_MESSAGE', 'SENDER_FEEDBACK', 'SENDER_GENERAL', @@ -275,6 +277,9 @@ export function getEnv(): BackendEnv { gcsUploadBucket: parse('GCS_UPLOAD_BUCKET'), gcsUploadSAKeyFilePath: parse('GCS_UPLOAD_SA_KEY_FILE_PATH'), gcsUploadPrivateBucket: parse('GCS_UPLOAD_PRIVATE_BUCKET'), + dailyUploadLimit: parse('GCS_UPLOAD_DAILY_LIMIT') + ? parseInt(parse('GCS_UPLOAD_DAILY_LIMIT'), 10) + : 5, // default to 5 } const sender = { message: parse('SENDER_MESSAGE'), diff --git a/packages/api/src/utils/parser.ts b/packages/api/src/utils/parser.ts index 3122a72bd..8107d978a 100644 --- a/packages/api/src/utils/parser.ts +++ b/packages/api/src/utils/parser.ts @@ -78,7 +78,7 @@ const ARTICLE_PREFIX = 'omnivore:' export const FAKE_URL_PREFIX = 'https://omnivore.app/no_url?q=' export const RSS_PARSER_CONFIG = { - timeout: 5000, // 5 seconds + timeout: 20000, // 20 seconds headers: { // some rss feeds require user agent 'User-Agent':