diff --git a/.github/workflows/static-sonarqube.yml b/.github/workflows/static-sonarqube.yml
new file mode 100755
index 00000000..f4f67424
--- /dev/null
+++ b/.github/workflows/static-sonarqube.yml
@@ -0,0 +1,74 @@
+name: static-sonarqube
+
+on:
+ push:
+ branches:
+ - "*"
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+ submodules: true
+
+ - name: local.properties
+ env:
+ LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
+ run: |
+ echo "$LOCAL_PROPERTIES" | base64 -d > local.properties
+
+ - name: local.properties.cloudLib
+ env:
+ LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES_CLOUDLIB }}
+ run: |
+ echo "$LOCAL_PROPERTIES" | base64 -d > QuoteUnquote.cloudLib/local.properties
+ ls -al QuoteUnquote.cloudLib/local.properties
+
+ - name: local.properties.utilsLib
+ env:
+ LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES_UTILSLIB }}
+ run: |
+ echo "$LOCAL_PROPERTIES" | base64 -d > QuoteUnquote.utilsLib/local.properties
+ ls -al QuoteUnquote.utilsLib/local.properties
+
+ - name: set up jdk
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'zulu'
+ java-version: 17
+
+ - name: Cache SonarCloud packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.sonar/cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+
+ - name: Cache Gradle packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.gradle/caches
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
+ restore-keys: ${{ runner.os }}-gradle
+
+ - name: compileFdroidDebugKotlin
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: |
+ ./gradlew :app:compileFdroidDebugKotlin :app:compileFdroidDebugJavaWithJavac
+
+ - name: sonar
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: |
+ ./gradlew app:sonar --info
diff --git a/.idea/androidTestResultsUserPreferences.xml b/.idea/androidTestResultsUserPreferences.xml
index fb508698..d670621c 100644
--- a/.idea/androidTestResultsUserPreferences.xml
+++ b/.idea/androidTestResultsUserPreferences.xml
@@ -341,6 +341,19 @@
+
+
+
+
+
+
+
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 95b35e4b..920dabfb 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,9 +1,16 @@
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index b3bebd26..1f07edd7 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
-
+
diff --git a/.idea/runConfigurations/_app_androidTest.xml b/.idea/runConfigurations/_app_androidTest.xml
index 37e91ab6..5e02adcb 100755
--- a/.idea/runConfigurations/_app_androidTest.xml
+++ b/.idea/runConfigurations/_app_androidTest.xml
@@ -1,6 +1,6 @@
-
+
@@ -58,7 +58,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/_app_androidTest_espresso___Fdroid_SourceSet.xml b/.idea/runConfigurations/_app_androidTest_espresso___Fdroid_SourceSet.xml
index c95522ab..7974419f 100755
--- a/.idea/runConfigurations/_app_androidTest_espresso___Fdroid_SourceSet.xml
+++ b/.idea/runConfigurations/_app_androidTest_espresso___Fdroid_SourceSet.xml
@@ -1,6 +1,5 @@
-
@@ -58,7 +57,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/_app_androidTest_uiautomator___Fdroid_SourceSet.xml b/.idea/runConfigurations/_app_androidTest_uiautomator___Fdroid_SourceSet.xml
index d867d30e..5d642b35 100755
--- a/.idea/runConfigurations/_app_androidTest_uiautomator___Fdroid_SourceSet.xml
+++ b/.idea/runConfigurations/_app_androidTest_uiautomator___Fdroid_SourceSet.xml
@@ -1,6 +1,5 @@
-
@@ -58,7 +57,7 @@
-
+
\ No newline at end of file
diff --git a/QuoteUnquote.cloudLib b/QuoteUnquote.cloudLib
index a0332a10..9a0df87a 160000
--- a/QuoteUnquote.cloudLib
+++ b/QuoteUnquote.cloudLib
@@ -1 +1 @@
-Subproject commit a0332a109abd7c05df7622c35c06c3a55a479b43
+Subproject commit 9a0df87aff43c58931736380f925b014f0c9a313
diff --git a/QuoteUnquote.utilsLib b/QuoteUnquote.utilsLib
index aa81228e..dafb1b65 160000
--- a/QuoteUnquote.utilsLib
+++ b/QuoteUnquote.utilsLib
@@ -1 +1 @@
-Subproject commit aa81228e4b13ae9936f2374cf9ee1307bbf39556
+Subproject commit dafb1b65c4ea7632852590cbd9365b2aaf8c1b71
diff --git a/README.md b/README.md
index 4aec8e16..06d259d5 100755
--- a/README.md
+++ b/README.md
@@ -9,9 +9,9 @@
| | ci | codecov | codacy | sonarcloud | deployment |
|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| :app | codecov.yml | codecov.yml | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/0d6227a494f747439d748802ca595999)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote&utm_campaign=Badge_Grade) | | |
-| [:cloudLib](https://github.com/jameshnsears/QuoteUnquote.cloudLib) | [![coverage](https://github.com/jameshnsears/QuoteUnquote.cloudLib/actions/workflows/coverage.yml/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.cloudLib/actions/workflows/coverage.yml) | [![codecov](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib/branch/main/graph/badge.svg?token=hjNc1SbSgT)](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/78d7a9a166b9420b9dc47991ef7cb028)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote.cloudLib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote.cloudLib&utm_campaign=Badge_Grade) | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jameshnsears_QuoteUnquote.cloudLib&metric=alert_status)](https://sonarcloud.io/dashboard?id=jameshnsears_QuoteUnquote.cloudLib) | | |
+| [:cloudLib](https://github.com/jameshnsears/QuoteUnquote.cloudLib) | [![coverage](https://github.com/jameshnsears/QuoteUnquote.cloudLib/actions/workflows/coverage.yml/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.cloudLib/actions/workflows/coverage.yml) | [![codecov](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib/branch/main/graph/badge.svg?token=hjNc1SbSgT)](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/78d7a9a166b9420b9dc47991ef7cb028)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote.cloudLib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote.cloudLib&utm_campaign=Badge_Grade) | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jameshnsears_QuoteUnquote.cloudLib&metric=alert_status)](https://sonarcloud.io/dashboard?id=jameshnsears_QuoteUnquote.cloudLib) | | |
| [functions](https://github.com/jameshnsears/QuoteUnquote.cloudLib.functions) | [![coverage](https://github.com/jameshnsears/QuoteUnquote.cloudLib.functions/actions/workflows/coverage.yml/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.cloudLib.functions/actions/workflows/coverage.yml) | [![codecov](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib.functions/branch/main/graph/badge.svg?token=jc55AxH2ry)](https://codecov.io/gh/jameshnsears/QuoteUnquote.cloudLib.functions) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/5c0ebcf94aac443a8637460cf1a4068b)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote.cloudLib.functions/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote.cloudLib.functions&utm_campaign=Badge_Grade) | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jameshnsears_QuoteUnquote.cloudLib.functions&metric=alert_status)](https://sonarcloud.io/dashboard?id=jameshnsears_QuoteUnquote.cloudLib.functions) | [![deploy-gcp](https://github.com/jameshnsears/QuoteUnquote.cloudLib.functions/workflows/deploy-gcp/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.cloudLib.functions/actions?query=workflow%3Adeploy-gcp) |
-| [:utilsLib](https://github.com/jameshnsears/QuoteUnquote.utilsLib) | [![coverage](https://github.com/jameshnsears/QuoteUnquote.utilsLib/actions/workflows/coverage.yml/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.utilsLib/actions/workflows/coverage.yml) | [![codecov](https://codecov.io/gh/jameshnsears/QuoteUnquote.utilsLib/branch/main/graph/badge.svg?token=UmWdOTiqB7)](https://codecov.io/gh/jameshnsears/QuoteUnquote.utilsLib) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e9cd947f7acf4a5cb090d49a09a7df3f)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote.utilsLib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote.utilsLib&utm_campaign=Badge_Grade) | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jameshnsears_QuoteUnquote.utilsLib&metric=alert_status)](https://sonarcloud.io/dashboard?id=jameshnsears_QuoteUnquote.utilsLib) | | |
+| [:utilsLib](https://github.com/jameshnsears/QuoteUnquote.utilsLib) | [![coverage](https://github.com/jameshnsears/QuoteUnquote.utilsLib/actions/workflows/coverage.yml/badge.svg)](https://github.com/jameshnsears/QuoteUnquote.utilsLib/actions/workflows/coverage.yml) | [![codecov](https://codecov.io/gh/jameshnsears/QuoteUnquote.utilsLib/branch/main/graph/badge.svg?token=UmWdOTiqB7)](https://codecov.io/gh/jameshnsears/QuoteUnquote.utilsLib) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e9cd947f7acf4a5cb090d49a09a7df3f)](https://www.codacy.com/gh/jameshnsears/QuoteUnquote.utilsLib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jameshnsears/QuoteUnquote.utilsLib&utm_campaign=Badge_Grade) | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jameshnsears_QuoteUnquote.utilsLib&metric=alert_status)](https://sonarcloud.io/dashboard?id=jameshnsears_QuoteUnquote.utilsLib) | | |
### 1.1. codecov.yml
@@ -23,10 +23,9 @@
## 2. Build Instructions
-After cloning extract .gpg files - BuildConfig / GitHub Action Secrets values.
+After cloning I extract .gpg files (BuildConfig, GitHub Action Secrets values) to create local.properties
-The app can be built on Windows 11 but the ./bin folder contains bash scripts (that work with git
-bash; some require gh cli).
+The app can be built on Windows 11 but the ./bin folder contains bash scripts (that work with git bash; some require gh cli).
### 2.1. CLI
@@ -71,12 +70,12 @@ After a clone...
PyCharm > Open > QuoteUnquote.cloudLib.functions
File > Settings > Project:
- > set Intepreter > New Virtualenv Environment
+ > set Interpreter > New Virtualenv Environment
Virtualenv Terminal >
> python -m pip install -r requirements-test.txt
> python -m pip install -r src/requirements.txt
run a Run/Debug Configuration
- > setting Python Intepreter to Virtualenv Environment
+ > setting Python Interpreter to Virtualenv Environment
```
diff --git a/app/build.gradle b/app/build.gradle
index a05388c5..6cd7541d 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,7 +3,7 @@ apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-android'
apply plugin: 'com.diffplug.spotless'
-apply plugin: "org.jetbrains.kotlin.plugin.compose"
+apply plugin: 'org.jetbrains.kotlin.plugin.compose'
apply from: '../jacoco.gradle'
apply from: '../ktlint.gradle'
@@ -47,9 +47,9 @@ android {
applicationId "com.github.jameshnsears.quoteunquote"
// changelog version | min sdk | target sdk
- versionCode 1822435
+ versionCode 1832435
// semantic versioning
- versionName "4.47.0"
+ versionName "4.48.0"
vectorDrawables.useSupportLibrary = true
@@ -75,7 +75,7 @@ android {
}
composeOptions {
- kotlinCompilerExtensionVersion '1.5.1'
+ kotlinCompilerExtensionVersion '1.5.15'
}
packagingOptions {
@@ -221,7 +221,7 @@ android {
dependencies {
androidTestImplementation 'androidx.arch.core:core-testing:2.2.0'
- androidTestImplementation 'androidx.compose.ui:ui-test-junit4-android:1.7.5'
+ androidTestImplementation 'androidx.compose.ui:ui-test-junit4-android:1.7.6'
androidTestImplementation 'androidx.room:room-testing:2.6.1'
androidTestImplementation 'androidx.test:core:1.6.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
@@ -230,14 +230,14 @@ dependencies {
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0'
- androidTestImplementation 'io.mockk:mockk-android:1.13.13'
- androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit:2.0.21'
+ androidTestImplementation 'io.mockk:mockk-android:1.13.14'
+ androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit:2.1.0'
annotationProcessor 'androidx.room:room-compiler:2.6.1'
debugImplementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.fragment:fragment-testing:1.8.5'
debugImplementation 'androidx.test:core-ktx:1.6.1'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14'
- googleplayImplementation platform('com.google.firebase:firebase-bom:33.5.1')
+ googleplayImplementation platform('com.google.firebase:firebase-bom:33.7.0')
implementation 'androidx.activity:activity-compose'
implementation 'androidx.activity:activity-ktx:1.9.3'
implementation 'androidx.appcompat:appcompat:1.7.0'
@@ -249,7 +249,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
implementation 'androidx.core:core-ktx'
implementation 'androidx.core:core-ktx:1.15.0'
- implementation 'androidx.databinding:databinding-runtime:8.7.2'
+ implementation 'androidx.databinding:databinding-runtime:8.7.3'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.room:room-guava:2.6.1'
@@ -260,17 +260,17 @@ dependencies {
implementation 'com.github.skydoves:colorpickerpreference:2.0.6'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.google.code.gson:gson:2.11.0'
- implementation 'com.google.guava:guava:33.3.1-jre'
+ implementation 'com.google.guava:guava:33.4.0-jre'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.2.0'
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
- implementation 'net.pwall.json:json-kotlin-schema:0.50'
+ implementation 'net.pwall.json:json-kotlin-schema:0.52'
implementation 'org.apache.commons:commons-csv:1.12.0'
- implementation 'org.jsoup:jsoup:1.18.1'
- implementation platform('androidx.compose:compose-bom:2024.10.01')
+ implementation 'org.jsoup:jsoup:1.18.3'
+ implementation platform('androidx.compose:compose-bom:2024.12.01')
implementation project(path: ':cloudLib')
implementation project(path: ':utilsLib')
testImplementation 'androidx.arch.core:core-testing:2.2.0'
@@ -278,12 +278,12 @@ dependencies {
testImplementation 'androidx.test:core-ktx:1.6.1'
testImplementation 'androidx.test.ext:junit:1.2.1'
testImplementation 'androidx.test:rules:1.6.1'
- testImplementation 'ch.qos.logback:logback-classic:1.5.12'
- testImplementation 'com.google.guava:guava:33.3.1-jre'
+ testImplementation 'ch.qos.logback:logback-classic:1.5.15'
+ testImplementation 'com.google.guava:guava:33.4.0-jre'
testImplementation 'io.mockk:mockk:1.13.13'
testImplementation 'junit:junit:4.13.2'
- testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0'
- testImplementation 'org.robolectric:robolectric:4.13'
+ testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.1'
+ testImplementation 'org.robolectric:robolectric:4.14.1'
}
repositories {
diff --git a/app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/48.json b/app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/49.json
similarity index 99%
rename from app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/48.json
rename to app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/49.json
index f95b144a..4e70183c 100644
--- a/app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/48.json
+++ b/app/schemas/com.github.jameshnsears.quoteunquote.database.quotation.AbstractQuotationDatabase/49.json
@@ -1,7 +1,7 @@
{
"formatVersion": 1,
"database": {
- "version": 48,
+ "version": 49,
"identityHash": "4576f076a1896260b13b26d1a0d40a61",
"entities": [
{
diff --git a/app/sonar-project.properties b/app/sonar-project.properties
deleted file mode 100755
index 67f8f3f6..00000000
--- a/app/sonar-project.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-sonar.projectKey=jameshnsears_QuoteUnquote
-sonar.projectName=QuoteUnquote
-sonar.organization=jameshnsears-github
-sonar.projectVersion=HEAD
-sonar.sources=src/main/java
-sonar.tests=src/androidTest/java
-sonar.java.binaries=build/intermediates/javac/debug/classes
-sonar.android.lint.report=build/reports/lint-results.xml
-sonar.junit.reportPaths=build/test-results/testDebugUnitTest
-sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco-combined.xml
-sonar.java.source=11
-sonar.java.target=11
-sonar.sourceEncoding=UTF-8
-sonar.exclusions=src/test/**
-sonar.verbose=true
\ No newline at end of file
diff --git a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettingsTest.kt b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettingsTest.kt
index ae3d67ed..5cf1fb34 100755
--- a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettingsTest.kt
+++ b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettingsTest.kt
@@ -100,6 +100,8 @@ class TransferBackupSettingsTest : GsonTestHelper() {
0,
23,
1,
+ false,
+ false,
)
private fun expectedAppearance() = Appearance(
diff --git a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogDouble.kt b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogDouble.kt
index 44a234fb..987043f8 100644
--- a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogDouble.kt
+++ b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogDouble.kt
@@ -8,7 +8,7 @@ import com.github.jameshnsears.quoteunquote.database.DatabaseRepositoryDouble
import com.github.jameshnsears.quoteunquote.database.quotation.QuotationEntity
import com.github.jameshnsears.quoteunquote.utils.ContentSelection
-class FilesCsvInPlaceEditDialogDouble() : ContentCsvInPlaceEditDialog() {
+class FilesCsvInPlaceEditDialogDouble : ContentCsvInPlaceEditDialog() {
private var databaseRepositoryDouble: DatabaseRepositoryDouble =
DatabaseRepositoryDouble.getInstance(ApplicationProvider.getApplicationContext())
diff --git a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogTest.kt b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogTest.kt
index 83d2c048..18b5119c 100644
--- a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogTest.kt
+++ b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditDialogTest.kt
@@ -37,7 +37,7 @@ class FilesCsvInPlaceEditDialogTest : QuoteUnquoteModelUtility() {
)
scenario.onFragment { contentCsvInPlaceEditDialog ->
- assertTrue(contentCsvInPlaceEditDialog.quoteUnquoteModel.allQuotations.size == 20267)
+ assertTrue(contentCsvInPlaceEditDialog.quoteUnquoteModel.allQuotations.size == 19971)
}
composeRule.onNodeWithText("Save").assertExists().performClick()
diff --git a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarmTest.kt b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarmTest.kt
index 0cc85f60..bb0d601a 100755
--- a/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarmTest.kt
+++ b/app/src/androidTest/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarmTest.kt
@@ -32,7 +32,7 @@ class NotificationsCustomisableIntervalAlarmTest : QuoteUnquoteModelUtility() {
notificationsPreferences.customisableIntervalHours = hours
}
- class AlarmMock(context: Context, val current: Int) : NotificationsCustomisableIntervalAlarm(
+ class AlarmMock(context: Context, val current: Int) : NotificationCustomisableIntervalAlarm(
context,
WidgetIdHelper.WIDGET_ID_01,
) {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b60e7a8a..a57e6f1c 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,12 @@
-
+
-
+
@@ -55,14 +58,24 @@
+ android:exported="false">
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/assets/quotations.db.prod b/app/src/main/assets/quotations.db.prod
index 2f308bb1..60ed7561 100644
Binary files a/app/src/main/assets/quotations.db.prod and b/app/src/main/assets/quotations.db.prod differ
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteModel.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteModel.java
index a01bc485..51377932 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteModel.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteModel.java
@@ -56,9 +56,9 @@ public QuoteUnquoteModel(int widgetId, @NonNull final Context widgetContext) {
if (widgetId != -1) {
QuotationsPreferences quotationsPreferences = new QuotationsPreferences(widgetId, context);
if (quotationsPreferences.getDatabaseInternal()) {
- databaseRepository.useInternalDatabase = true;
+ DatabaseRepository.useInternalDatabase = true;
} else {
- databaseRepository.useInternalDatabase = false;
+ DatabaseRepository.useInternalDatabase = false;
}
}
}
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteWidget.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteWidget.java
index 1e9c28ce..351fc545 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteWidget.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/QuoteUnquoteWidget.java
@@ -31,6 +31,7 @@
import com.github.jameshnsears.quoteunquote.configure.fragment.appearance.AppearancePreferences;
import com.github.jameshnsears.quoteunquote.configure.fragment.notifications.NotificationsPreferences;
import com.github.jameshnsears.quoteunquote.configure.fragment.quotations.QuotationsPreferences;
+import com.github.jameshnsears.quoteunquote.database.DatabaseRepository;
import com.github.jameshnsears.quoteunquote.database.quotation.QuotationEntity;
import com.github.jameshnsears.quoteunquote.listview.ListViewService;
import com.github.jameshnsears.quoteunquote.scraper.ScraperData;
@@ -39,10 +40,11 @@
import com.github.jameshnsears.quoteunquote.utils.IntentFactoryHelper;
import com.github.jameshnsears.quoteunquote.utils.notification.NotificationContent;
import com.github.jameshnsears.quoteunquote.utils.notification.NotificationCoordinator;
+import com.github.jameshnsears.quoteunquote.utils.notification.NotificationCustomisableIntervalAlarm;
+import com.github.jameshnsears.quoteunquote.utils.notification.NotificationDailyAlarm;
import com.github.jameshnsears.quoteunquote.utils.notification.NotificationEvent;
import com.github.jameshnsears.quoteunquote.utils.notification.NotificationHelper;
-import com.github.jameshnsears.quoteunquote.utils.notification.NotificationsCustomisableIntervalAlarm;
-import com.github.jameshnsears.quoteunquote.utils.notification.NotificationsDailyAlarm;
+import com.github.jameshnsears.quoteunquote.utils.notification.NotificationTextToSpeechService;
import com.github.jameshnsears.quoteunquote.utils.preference.PreferencesFacade;
import com.github.jameshnsears.quoteunquote.utils.scraper.ScraperAlarm;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@@ -56,17 +58,24 @@
public class QuoteUnquoteWidget extends AppWidgetProvider {
@Nullable
public static ContentSelection currentContentSelection = ContentSelection.ALL;
+
@Nullable
public static String currentAuthorSelection;
+
@Nullable
public static int notificationPermissionDeniedCount = 0;
+
@Nullable
private static ExecutorService executorService;
+
private static volatile boolean receiversRegistered;
+
@Nullable
private static NotificationHelper notificationHelper;
+
@Nullable
public QuoteUnquoteModel quoteUnquoteModel;
+
@Nullable
private NotificationCoordinator notificationCoordinator;
@@ -110,7 +119,7 @@ public static ExecutorService getExecutorService() {
return executorService;
}
- public static void stopExecutorService() {
+ public static void executorServiceStop() {
if (executorService != null) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
executorService.shutdown();
@@ -160,7 +169,9 @@ public void onEnabled(@NonNull final Context context) {
quotationsPreferences.setContentLocalCode(CloudTransferHelper.getLocalCode());
}
- startDatabaseConnectivity(-1, context);
+ databaseConnectivityStart(-1, context);
+
+ textToSpeechServiceSpeak(-1, context, null);
}
@Override
@@ -242,7 +253,7 @@ private NotificationHelper getNotificationHelper(@NonNull Context context) {
return notificationHelper;
}
- private NotificationCoordinator getNotificationCoordinator(@NonNull Context context) {
+ private NotificationCoordinator getNotificationCoordinator() {
if (notificationCoordinator == null) {
notificationCoordinator = new NotificationCoordinator();
}
@@ -314,8 +325,8 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
try {
- final NotificationsDailyAlarm notificationsDailyAlarm = new NotificationsDailyAlarm(context, widgetId);
- final NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationsCustomisableIntervalAlarm(context, widgetId);
+ final NotificationDailyAlarm notificationDailyAlarm = new NotificationDailyAlarm(context, widgetId);
+ final NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationCustomisableIntervalAlarm(context, widgetId);
final ScraperAlarm scraperAlarm = new ScraperAlarm(context, widgetId);
switch (intent.getAction()) {
@@ -328,7 +339,7 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte
break;
case Intent.ACTION_USER_PRESENT:
- startDatabaseConnectivity(widgetId, context);
+ databaseConnectivityStart(widgetId, context);
onReceiveDeviceUnlock(context, appWidgetManager);
break;
@@ -344,26 +355,19 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte
onReceiveNotificationDismissed(context, intent);
break;
- /*
- # this now no longer works on API 34:
- adb shell
- am broadcast -a android.intent.action.BOOT_COMPLETED
-
- adb reboot
- */
case Intent.ACTION_BOOT_COMPLETED:
case Intent.ACTION_REBOOT:
case IntentFactoryHelper.ACTIVITY_FINISHED_CONFIGURATION:
onReceiveActivityFinishedConfiguration(
context,
widgetId,
- notificationsDailyAlarm,
+ notificationDailyAlarm,
notificationsCustomisableIntervalAlarm,
scraperAlarm);
break;
case IntentFactoryHelper.DAILY_ALARM:
- onReceiveDailyAlarm(context, widgetId, notificationsDailyAlarm);
+ onReceiveDailyAlarm(context, widgetId, notificationDailyAlarm);
break;
case IntentFactoryHelper.CUSTOMISABLE_INTERVAL_ALARM:
@@ -476,11 +480,11 @@ private void onReceiveActionAppwidgetEnabled(@NonNull final Context context,
int[] widgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, QuoteUnquoteWidget.class));
for (final int widgetId : widgetIds) {
Timber.d("setDailyAlarm: %d", widgetId);
- NotificationsDailyAlarm notificationsDailyAlarm = new NotificationsDailyAlarm(context, widgetId);
- notificationsDailyAlarm.setAlarm();
+ NotificationDailyAlarm notificationDailyAlarm = new NotificationDailyAlarm(context, widgetId);
+ notificationDailyAlarm.setAlarm();
Timber.d("setCustomisableIntervalAlarm: %d", widgetId);
- NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationsCustomisableIntervalAlarm(context, widgetId);
+ NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationCustomisableIntervalAlarm(context, widgetId);
notificationsCustomisableIntervalAlarm.setAlarm();
Timber.d("scraperAlarm: %d", widgetId);
@@ -523,11 +527,11 @@ private void onReceiveAllWidgetInstancesFavouriteNotification(
setAutoCloudBackupAlarm(context, widgetId);
}
- private void startDatabaseConnectivity(int widgetId, @NonNull Context context) {
+ private void databaseConnectivityStart(int widgetId, @NonNull Context context) {
setQuoteUnquoteModel(new QuoteUnquoteModel(widgetId, context));
}
- public void stopDatabaseConnectivity() {
+ public void databaseConnectivityStop() {
quoteUnquoteModel = null;
}
@@ -571,7 +575,7 @@ private void onReceiveToolbarPressedFavourite(
updateWidgetFavourite(context, widgetId, digest, appWidgetManager);
- if (getNotificationCoordinator(context).isNotificationShowingQuotation(digest)) {
+ if (getNotificationCoordinator().isNotificationShowingQuotation(digest)) {
updateNotificationFavourite(
context,
widgetId,
@@ -690,16 +694,16 @@ private void onReceiveToolbarPressedNext(
private void onReceiveDailyAlarm(
@NonNull final Context context,
final int widgetId,
- @NonNull final NotificationsDailyAlarm notificationsDailyAlarm) {
+ @NonNull final NotificationDailyAlarm notificationDailyAlarm) {
// reschedule, as recurring
- notificationsDailyAlarm.setAlarm();
+ notificationDailyAlarm.setAlarm();
scheduleEvent(context, widgetId, NotificationEvent.EVENT_DAILY);
}
private void onReceiveCustomisableIntervalAlarm(
@NonNull final Context context,
final int widgetId,
- @NonNull final NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm) {
+ @NonNull final NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm) {
Timber.d("customisableIntervalAlarm");
notificationsCustomisableIntervalAlarm.setAlarm();
scheduleEvent(context, widgetId, NotificationEvent.CUSTOMISABLE_INTERVAL);
@@ -796,9 +800,9 @@ private void scheduleEvent(
QuotationEntity currentQuotation
= getQuoteUnquoteModel(widgetId, context).getCurrentQuotation(widgetId);
- int notificationId = getNotificationCoordinator(context).createNotificationId(currentQuotation.digest);
+ int notificationId = getNotificationCoordinator().createNotificationId(currentQuotation.digest);
- getNotificationCoordinator(context).dismissNotification(context, getNotificationHelper(context), notificationId);
+ getNotificationCoordinator().dismissNotification(context, getNotificationHelper(context), notificationId);
displayNotification(context, widgetId, notificationEvent);
}
@@ -814,7 +818,7 @@ private void displayNotification(
if (currentQuotation != null) {
NotificationsPreferences notificationsPreferences = new NotificationsPreferences(widgetId, context);
- int notificationId = getNotificationCoordinator(context).createNotificationId(currentQuotation.digest);
+ int notificationId = getNotificationCoordinator().createNotificationId(currentQuotation.digest);
NotificationContent notificationContent = new NotificationContent(
context,
@@ -829,7 +833,39 @@ private void displayNotification(
displayNotificationInCorrectChannel(context, notificationContent, notificationEvent);
- getNotificationCoordinator(context).rememberNotification(notificationEvent, notificationId, currentQuotation.digest);
+ textToSpeechServiceSpeak(widgetId, context, notificationContent);
+
+ getNotificationCoordinator().rememberNotification(notificationEvent, notificationId, currentQuotation.digest);
+ }
+ }
+
+ private void textToSpeechServiceSpeak(int widgetId,
+ Context context,
+ NotificationContent notificationContent) {
+ if (notificationContent != null) {
+ NotificationsPreferences notificationsPreferences = new NotificationsPreferences(widgetId, context);
+
+ if (notificationsPreferences.getEventTtsUk() || notificationsPreferences.getEventTtsSystem()) {
+ Intent serviceIntent = new Intent(context, NotificationTextToSpeechService.class);
+ serviceIntent.putExtra("textToSpeak", notificationContent.getQuotation());
+
+ serviceIntent.putExtra("textToSpeakSource", notificationContent.getAuthor());
+ serviceIntent.putExtra("excludeSource", notificationsPreferences.getExcludeSourceFromNotification());
+
+ if (notificationsPreferences.getEventTtsUk()) {
+ serviceIntent.putExtra("localeTts", "UK");
+ } else {
+ serviceIntent.putExtra("localeTts", "SYSTEM");
+ }
+
+ context.startService(serviceIntent);
+ }
+ }
+ }
+
+ private void textToSpeechServiceStop(Context context) {
+ if (NotificationTextToSpeechService.Companion.isRunning()) {
+ context.stopService(new Intent(context, NotificationTextToSpeechService.class));
}
}
@@ -853,7 +889,7 @@ private void displayNotificationInCorrectChannel(
break;
case NotificationEvent.TOOLBAR_PRESSED_FAVOURITE:
- switch (getNotificationCoordinator(context).getNotificationChannelId(notificationContent.getNotificationId())) {
+ switch (getNotificationCoordinator().getNotificationChannelId(notificationContent.getNotificationId())) {
case NotificationEvent.DEVICE_UNLOCK:
getNotificationHelper(context).displayNotificationDeviceUnlock(notificationContent);
break;
@@ -890,7 +926,7 @@ private void onReceiveNotificationNext(
onReceiveToolbarPressedNextRandom(context, widgetId, appWidgetManager);
}
- getNotificationCoordinator(context).dismissNotification(context, getNotificationHelper(context), notificationId);
+ getNotificationCoordinator().dismissNotification(context, getNotificationHelper(context), notificationId);
displayNotification(context, widgetId, notificationEvent);
}
@@ -899,9 +935,9 @@ private void onReceiveNotificationDismissed(
@NonNull Context context,
@NonNull final Intent intent) {
final int notificationId = intent.getExtras().getInt("notificationId");
- getNotificationCoordinator(context).dismissNotification(context, getNotificationHelper(context), notificationId);
+ getNotificationCoordinator().dismissNotification(context, getNotificationHelper(context), notificationId);
- getNotificationCoordinator(context).forgetNotification(notificationId);
+ getNotificationCoordinator().forgetNotification(notificationId);
}
private void onReceiveNotificationFavourite(
@@ -957,7 +993,7 @@ private String markNotificationAsFavourite(
private void updateNotificationFavourite(
@NonNull Context context, int widgetId, @NonNull String widgetDigest) {
- if (getNotificationCoordinator(context).isNotificationShowingQuotation(widgetDigest)) {
+ if (getNotificationCoordinator().isNotificationShowingQuotation(widgetDigest)) {
NotificationsPreferences notificationsPreferences = new NotificationsPreferences(widgetId, context);
@@ -972,7 +1008,7 @@ private void updateNotificationFavourite(
widgetDigest,
getQuoteUnquoteModel(widgetId, context).isFavourite(quotationEntity.digest),
notificationsPreferences.getEventNextSequential(),
- getNotificationCoordinator(context).createNotificationId(quotationEntity.digest),
+ getNotificationCoordinator().createNotificationId(quotationEntity.digest),
NotificationEvent.TOOLBAR_PRESSED_FAVOURITE);
displayNotificationInCorrectChannel(context, notificationContent, NotificationEvent.TOOLBAR_PRESSED_FAVOURITE);
@@ -982,8 +1018,8 @@ private void updateNotificationFavourite(
private void onReceiveActivityFinishedConfiguration(
@NonNull final Context context,
final int widgetId,
- @NonNull final NotificationsDailyAlarm notificationsDailyAlarm,
- @NonNull final NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm,
+ @NonNull final NotificationDailyAlarm notificationDailyAlarm,
+ @NonNull final NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm,
@NonNull final ScraperAlarm scraperAlarm) {
if (getQuoteUnquoteModel(widgetId, context).getCurrentQuotation(widgetId) == null) {
@@ -996,13 +1032,13 @@ private void onReceiveActivityFinishedConfiguration(
}
manageAlarms(context, widgetId,
- notificationsDailyAlarm, notificationsCustomisableIntervalAlarm, scraperAlarm);
+ notificationDailyAlarm, notificationsCustomisableIntervalAlarm, scraperAlarm);
}
private void manageAlarms(
@NonNull Context context, int widgetId,
- @NonNull NotificationsDailyAlarm notificationsDailyAlarm,
- @NonNull NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm,
+ @NonNull NotificationDailyAlarm notificationDailyAlarm,
+ @NonNull NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm,
@NonNull ScraperAlarm scraperAlarm) {
QuotationsPreferences quotationsPreferences = new QuotationsPreferences(widgetId, context);
@@ -1014,9 +1050,9 @@ private void manageAlarms(
NotificationsPreferences notificationsPreferences = new NotificationsPreferences(widgetId, context);
if (notificationsPreferences.getEventDaily()) {
- notificationsDailyAlarm.setAlarm();
+ notificationDailyAlarm.setAlarm();
} else {
- notificationsDailyAlarm.resetAlarm();
+ notificationDailyAlarm.resetAlarm();
}
if (notificationsPreferences.getCustomisableInterval()) {
@@ -1226,10 +1262,10 @@ public void onDeleted(
getQuoteUnquoteModel(widgetId, context).delete(widgetId);
PreferencesFacade.delete(context, widgetId);
- final NotificationsDailyAlarm notificationsDailyAlarm = new NotificationsDailyAlarm(context, widgetId);
- notificationsDailyAlarm.resetAlarm();
+ final NotificationDailyAlarm notificationDailyAlarm = new NotificationDailyAlarm(context, widgetId);
+ notificationDailyAlarm.resetAlarm();
- final NotificationsCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationsCustomisableIntervalAlarm(context, widgetId);
+ final NotificationCustomisableIntervalAlarm notificationsCustomisableIntervalAlarm = new NotificationCustomisableIntervalAlarm(context, widgetId);
notificationsCustomisableIntervalAlarm.resetAlarm();
final ScraperAlarm scraperAlarm = new ScraperAlarm(context, widgetId);
@@ -1258,8 +1294,9 @@ public void onDisabled(@NonNull final Context context) {
context.stopService(new Intent(context, CloudServiceRestore.class));
}
} finally {
- stopDatabaseConnectivity();
- stopExecutorService();
+ databaseConnectivityStop();
+ executorServiceStop();
+ textToSpeechServiceStop(context);
}
}
@@ -1270,9 +1307,9 @@ public synchronized QuoteUnquoteModel getQuoteUnquoteModel(
quoteUnquoteModel = new QuoteUnquoteModel(widgetId, context);
} else {
if (getQuotationsPreferences(context, widgetId).getDatabaseInternal()) {
- quoteUnquoteModel.databaseRepository.useInternalDatabase = true;
+ DatabaseRepository.useInternalDatabase = true;
} else {
- quoteUnquoteModel.databaseRepository.useInternalDatabase = false;
+ DatabaseRepository.useInternalDatabase = false;
}
}
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/FragmentCommon.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/FragmentCommon.java
index e2fb9194..a281bfbc 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/FragmentCommon.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/FragmentCommon.java
@@ -27,7 +27,7 @@ public void makeButtonAlpha(@NonNull final Button button, final boolean enable)
}
public void rememberScreen(final Screen screen, Context applicationContext) {
- new QuotationsPreferences(widgetId, applicationContext).setScreen(screen.name);
+ new QuotationsPreferences(widgetId, applicationContext).setScreen(screen.screenName);
}
public enum Screen {
@@ -43,15 +43,15 @@ public enum Screen {
Sync("Sync");
- public final String name;
+ public final String screenName;
- Screen(String name) {
- this.name = name;
+ Screen(String screenName) {
+ this.screenName = screenName;
}
public static Screen fromString(String name) {
for (Screen screen : Screen.values()) {
- if (screen.name.equalsIgnoreCase(name)) {
+ if (screen.screenName.equalsIgnoreCase(name)) {
return screen;
}
}
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/AppearanceFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/AppearanceFragment.java
index f4c81eab..b925f6ae 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/AppearanceFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/AppearanceFragment.java
@@ -88,7 +88,7 @@ public void onPageSelected(int position) {
String screen =
new QuotationsPreferences(widgetId, getContext()).getScreen();
- if (screen.equals(Screen.AppearanceToolbar.name)) {
+ if (screen.equals(Screen.AppearanceToolbar.screenName)) {
fragmentAppearanceBinding.viewPager2Appearance.setCurrentItem(1);
} else {
fragmentAppearanceBinding.viewPager2Appearance.setCurrentItem(0);
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceStyleFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceStyleFragment.java
index 90f0d90d..b9b54626 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceStyleFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceStyleFragment.java
@@ -49,12 +49,6 @@ public class AppearanceStyleFragment extends FragmentCommon {
@Nullable
public AppearancePreferences appearancePreferences;
- @Override
- public void onResume() {
- super.onResume();
- rememberScreen(Screen.AppearanceStyle, getContext());
- }
-
public AppearanceStyleFragment() {
// dark mode support
}
@@ -70,6 +64,12 @@ public static AppearanceStyleFragment newInstance(final int widgetId) {
return fragment;
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ rememberScreen(Screen.AppearanceStyle, getContext());
+ }
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/toolbar/AppearanceToolbarFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/toolbar/AppearanceToolbarFragment.java
index 88d4f295..a1696074 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/toolbar/AppearanceToolbarFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/toolbar/AppearanceToolbarFragment.java
@@ -26,12 +26,6 @@ public class AppearanceToolbarFragment extends FragmentCommon {
@Nullable
public AppearancePreferences appearancePreferences;
- @Override
- public void onResume() {
- super.onResume();
- rememberScreen(Screen.AppearanceToolbar, getContext());
- }
-
public AppearanceToolbarFragment() {
// dark mode support
}
@@ -47,6 +41,12 @@ public static AppearanceToolbarFragment newInstance(final int widgetId) {
return fragment;
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ rememberScreen(Screen.AppearanceToolbar, getContext());
+ }
+
@Override
@NonNull
public View onCreateView(
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsFragment.java
index 24e87399..c3ac3fc1 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsFragment.java
@@ -65,6 +65,9 @@ public class NotificationsFragment extends FragmentCommon {
notificationsPreferences.setEventDisplayWidget(false);
notificationsPreferences.setEventDisplayWidgetAndNotification(true);
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsUk.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsSystem.setEnabled(true);
+
fragmentNotificationsBinding.textViewNotificationSizeWarningInfo.setEnabled(true);
fragmentNotificationsBinding.textViewNotificationSizeWarning1.setEnabled(true);
}
@@ -91,14 +94,6 @@ public class NotificationsFragment extends FragmentCommon {
}
);
- @Override
- public void onResume() {
- super.onResume();
- rememberScreen(Screen.Notifications, getContext());
-
- handleSpecialPermissionForExactAlarm();
- }
-
public NotificationsFragment() {
// dark mode support
}
@@ -114,6 +109,14 @@ public static NotificationsFragment newInstance(final int widgetId) {
return fragment;
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ rememberScreen(Screen.Notifications, getContext());
+
+ handleSpecialPermissionForExactAlarm();
+ }
+
@Override
@NonNull
public View onCreateView(
@@ -165,6 +168,15 @@ public void onViewCreated(
createListenerSpecificTime();
createListenerDaily();
+
+ createListenerTtsUk();
+ createListenerTtsSystem();
+
+ /*
+ ensureTtsSwitchesAligned()
+
+ only one TTS can be enabled
+ */
}
private void handleSpecialPermissionForExactAlarm() {
@@ -271,15 +283,31 @@ private void setDisplay() {
if (fragmentNotificationsBinding.radioButtonWhereAsNotification.isChecked()) {
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsUk.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsSystem.setEnabled(true);
+
fragmentNotificationsBinding.textViewNotificationSizeWarningInfo.setEnabled(true);
fragmentNotificationsBinding.textViewNotificationSizeWarning1.setEnabled(true);
} else {
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setEnabled(false);
+ fragmentNotificationsBinding.switchTtsUk.setEnabled(false);
+ fragmentNotificationsBinding.switchTtsSystem.setEnabled(false);
+
fragmentNotificationsBinding.textViewNotificationSizeWarningInfo.setEnabled(false);
fragmentNotificationsBinding.textViewNotificationSizeWarning1.setEnabled(false);
}
+ if (notificationsPreferences.getEventTtsUk()) {
+ fragmentNotificationsBinding.switchTtsUk.setChecked(true);
+ fragmentNotificationsBinding.switchTtsSystem.setChecked(false);
+ }
+
+ if (notificationsPreferences.getEventTtsSystem()) {
+ fragmentNotificationsBinding.switchTtsUk.setChecked(false);
+ fragmentNotificationsBinding.switchTtsSystem.setChecked(true);
+ }
+
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setChecked(notificationsPreferences.getExcludeSourceFromNotification());
}
@@ -314,6 +342,9 @@ private void createListenerDisplayRadioGroup() {
notificationsPreferences.setEventDisplayWidgetAndNotification(false);
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setEnabled(false);
+ fragmentNotificationsBinding.switchTtsUk.setEnabled(false);
+ fragmentNotificationsBinding.switchTtsSystem.setEnabled(false);
+
fragmentNotificationsBinding.textViewNotificationSizeWarningInfo.setEnabled(false);
fragmentNotificationsBinding.textViewNotificationSizeWarning1.setEnabled(false);
break;
@@ -334,6 +365,9 @@ private void createListenerDisplayRadioGroup() {
notificationsPreferences.setEventDisplayWidget(false);
notificationsPreferences.setEventDisplayWidgetAndNotification(true);
fragmentNotificationsBinding.switchExcludeSourceFromNotification.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsUk.setEnabled(true);
+ fragmentNotificationsBinding.switchTtsSystem.setEnabled(true);
+
fragmentNotificationsBinding.textViewNotificationSizeWarningInfo.setEnabled(true);
fragmentNotificationsBinding.textViewNotificationSizeWarning1.setEnabled(true);
break;
@@ -376,6 +410,26 @@ private void createListenerDaily() {
});
}
+ private void createListenerTtsUk() {
+ fragmentNotificationsBinding.switchTtsUk.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ notificationsPreferences.setEventTtsSystem(false);
+ fragmentNotificationsBinding.switchTtsSystem.setChecked(false);
+
+ notificationsPreferences.setEventTtsUk(isChecked);
+ fragmentNotificationsBinding.switchTtsUk.setChecked(isChecked);
+ });
+ }
+
+ private void createListenerTtsSystem() {
+ fragmentNotificationsBinding.switchTtsSystem.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ notificationsPreferences.setEventTtsUk(false);
+ fragmentNotificationsBinding.switchTtsUk.setChecked(false);
+
+ notificationsPreferences.setEventTtsSystem(isChecked);
+ fragmentNotificationsBinding.switchTtsSystem.setChecked(isChecked);
+ });
+ }
+
private void createListenerDailyCommon(boolean isChecked) {
if (notificationsPreferences.getEventDaily() != isChecked) {
notificationsPreferences.setEventDaily(isChecked);
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsPreferences.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsPreferences.java
index d66d1ba1..dbb971af 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsPreferences.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/notifications/NotificationsPreferences.java
@@ -21,6 +21,27 @@ public class NotificationsPreferences extends PreferencesFacade {
public static final String EVENT_CUSTOMISABLE_INTERVAL_HOUR_TO = "EVENT_CUSTOMISABLE_INTERVAL_HOUR_TO";
public static final String EVENT_CUSTOMISABLE_INTERVAL_HOURS = "EVENT_CUSTOMISABLE_INTERVAL_HOURS";
+ public static final String EVENT_TTS_UK = "EVENT_TTS_UK";
+ public static final String EVENT_TTS_SYSTEM = "EVENT_TTS_SYSTEM";
+
+ public boolean getEventTtsUk() {
+ return this.preferenceHelper.getPreferenceBoolean(this.getPreferenceKey(NotificationsPreferences.EVENT_TTS_UK), false);
+ }
+
+ public void setEventTtsUk(boolean value) {
+ this.preferenceHelper.setPreference(this.getPreferenceKey(NotificationsPreferences.EVENT_TTS_UK), value);
+ }
+
+ public boolean getEventTtsSystem() {
+ return this.preferenceHelper.getPreferenceBoolean(this.getPreferenceKey(NotificationsPreferences.EVENT_TTS_SYSTEM), false);
+ }
+
+ public void setEventTtsSystem(boolean value) {
+ this.preferenceHelper.setPreference(this.getPreferenceKey(NotificationsPreferences.EVENT_TTS_SYSTEM), value);
+ }
+
+ //////////////////
+
public NotificationsPreferences(int widgetId, @NonNull Context applicationContext) {
super(widgetId, applicationContext);
}
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsFragment.java
index e0a64db1..6ff75e78 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsFragment.java
@@ -106,9 +106,9 @@ public void onPageSelected(int position) {
String screen =
new QuotationsPreferences(widgetId, getContext()).getScreen();
- if (screen.equals(Screen.ContentInternal.name)
- || screen.equals(Screen.ContentFiles.name)
- || screen.equals(Screen.ContentWeb.name)
+ if (screen.equals(Screen.ContentInternal.screenName)
+ || screen.equals(Screen.ContentFiles.screenName)
+ || screen.equals(Screen.ContentWeb.screenName)
) {
fragmentQuotationsBinding.viewPager2Quotations.setCurrentItem(1);
} else {
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsPreferences.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsPreferences.java
index 3dc42cab..d40eb134 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsPreferences.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/QuotationsPreferences.java
@@ -36,6 +36,14 @@ public class QuotationsPreferences extends PreferencesFacade {
public static final String DATABASE_EXTERNAL_CONTENT = "DATABASE_EXTERNAL_CONTENT";
+ public QuotationsPreferences(@NonNull Context applicationContext) {
+ super(0, applicationContext);
+ }
+
+ public QuotationsPreferences(int widgetId, @NonNull Context applicationContext) {
+ super(widgetId, applicationContext);
+ }
+
@NonNull
public String getScreen() {
return this.preferenceHelper.getPreferenceString(this.getPreferenceKey(SCREEN));
@@ -45,14 +53,6 @@ public void setScreen(@NonNull String value) {
this.preferenceHelper.setPreference(this.getPreferenceKey(SCREEN), value);
}
- public QuotationsPreferences(@NonNull Context applicationContext) {
- super(0, applicationContext);
- }
-
- public QuotationsPreferences(int widgetId, @NonNull Context applicationContext) {
- super(widgetId, applicationContext);
- }
-
@NonNull
public boolean getDatabaseWebKeepLatestOnly() {
return this.preferenceHelper.getPreferenceBoolean(this.getPreferenceKey(QuotationsPreferences.DATABASE_WEB_KEEP_LATEST_ONLY), true);
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/QuotationsContentFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/QuotationsContentFragment.java
index 48fc8d91..d1ce4160 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/QuotationsContentFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/QuotationsContentFragment.java
@@ -105,10 +105,10 @@ public void onTabReselected(TabLayout.Tab tab) {
String screen =
new QuotationsPreferences(widgetId, getContext()).getScreen();
- if (screen.equals(Screen.ContentFiles.name)) {
+ if (screen.equals(Screen.ContentFiles.screenName)) {
fragmentQuotationsTabDatabaseBinding.tabDatabase.getTabAt(1).select();
- } else if (screen.equals(Screen.ContentWeb.name)) {
+ } else if (screen.equals(Screen.ContentWeb.screenName)) {
fragmentQuotationsTabDatabaseBinding.tabDatabase.getTabAt(2).select();
} else {
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/internal/ContentInternalFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/internal/ContentInternalFragment.java
index 86cca6fc..e9239b24 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/internal/ContentInternalFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/internal/ContentInternalFragment.java
@@ -19,8 +19,9 @@ public class ContentInternalFragment extends ContentFragment {
@Nullable
public FragmentQuotationsTabDatabaseTabInternalBinding fragmentQuotationsTabDatabaseTabInternalBinding;
- @Nullable
- public QuotationsPreferences quotationsPreferences;
+ public ContentInternalFragment(int widgetId) {
+ super(widgetId);
+ }
@Override
public void onResume() {
@@ -28,10 +29,6 @@ public void onResume() {
rememberScreen(Screen.ContentInternal, getContext());
}
- public ContentInternalFragment(int widgetId) {
- super(widgetId);
- }
-
@Override
@NonNull
public View onCreateView(
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/web/ContentWebFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/web/ContentWebFragment.java
index 43d93aa7..e9e3ad9b 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/web/ContentWebFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/web/ContentWebFragment.java
@@ -26,8 +26,9 @@ public class ContentWebFragment extends ContentFragment {
@Nullable
public FragmentQuotationsTabDatabaseTabWebBinding fragmentQuotationsTabDatabaseTabWebBinding;
- @Nullable
- public QuotationsPreferences quotationsPreferences;
+ public ContentWebFragment(int widgetId) {
+ super(widgetId);
+ }
@Override
public void onResume() {
@@ -35,10 +36,6 @@ public void onResume() {
rememberScreen(Screen.ContentWeb, getContext());
}
- public ContentWebFragment(int widgetId) {
- super(widgetId);
- }
-
@Override
@NonNull
public View onCreateView(
@@ -185,7 +182,7 @@ private void createListenerButtonImportWebPage() {
String xpathQuotation = getWebXpathQuotation();
String xpathSource = getWebXpathSource();
- if ("".equals(url) || "".equals(xpathQuotation) | "".equals(xpathSource)
+ if ("".equals(url) || "".equals(xpathQuotation) || "".equals(xpathSource)
|| 10 > url.length()) {
useInternalDatabase();
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/QuotationsFilterFragment.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/QuotationsFilterFragment.java
index 165bf80c..29d8e149 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/QuotationsFilterFragment.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/QuotationsFilterFragment.java
@@ -75,12 +75,6 @@ public class QuotationsFilterFragment extends FragmentCommon {
@NonNull
private ActivityResultLauncher activityExportSource = activityExport();
- @Override
- public void onResume() {
- super.onResume();
- rememberScreen(Screen.QuotationsFilter, getContext());
- }
-
public QuotationsFilterFragment() {
}
@@ -111,6 +105,12 @@ public static void ensureFragmentContentSearchConsistency(
}
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ rememberScreen(Screen.QuotationsFilter, getContext());
+ }
+
@Override
public void onCreate(@NonNull final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/browse/adapter/BrowseAdapter.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/browse/adapter/BrowseAdapter.java
index 3d21a0a5..0834a597 100644
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/browse/adapter/BrowseAdapter.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/filter/browse/adapter/BrowseAdapter.java
@@ -32,7 +32,7 @@ public BrowseAdapter(final int widgetId,
DIALOG dialogType) {
BrowseAdapter.widgetId = widgetId;
browseDataList = new CopyOnWriteArrayList<>(browseDataItems);
- this.dialogType = dialogType;
+ BrowseAdapter.dialogType = dialogType;
}
@Override
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/database/quotation/AbstractQuotationDatabase.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/database/quotation/AbstractQuotationDatabase.java
index 821227b8..6b5b0792 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/database/quotation/AbstractQuotationDatabase.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/database/quotation/AbstractQuotationDatabase.java
@@ -10,7 +10,7 @@
import com.github.jameshnsears.quoteunquote.BuildConfig;
-@Database(entities = {QuotationEntity.class}, version = 48)
+@Database(entities = {QuotationEntity.class}, version = 49)
public abstract class AbstractQuotationDatabase extends RoomDatabase {
@Nullable
public static AbstractQuotationDatabase quotationDatabase;
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarm.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationCustomisableIntervalAlarm.java
similarity index 96%
rename from app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarm.java
rename to app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationCustomisableIntervalAlarm.java
index c125afb3..3da3e22f 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsCustomisableIntervalAlarm.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationCustomisableIntervalAlarm.java
@@ -15,11 +15,11 @@
import timber.log.Timber;
-public class NotificationsCustomisableIntervalAlarm extends NotificationsDailyAlarm {
+public class NotificationCustomisableIntervalAlarm extends NotificationDailyAlarm {
int nextAlarmHour;
boolean nextAlarmDay;
- public NotificationsCustomisableIntervalAlarm(
+ public NotificationCustomisableIntervalAlarm(
@NonNull Context widgetContext, int theWidgetId) {
super(widgetContext, theWidgetId);
}
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsDailyAlarm.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationDailyAlarm.java
similarity index 97%
rename from app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsDailyAlarm.java
rename to app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationDailyAlarm.java
index 543b06ea..bd3fce06 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationsDailyAlarm.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/notification/NotificationDailyAlarm.java
@@ -17,14 +17,14 @@
import timber.log.Timber;
-public class NotificationsDailyAlarm {
+public class NotificationDailyAlarm {
@Nullable
protected final NotificationsPreferences notificationsPreferences;
@NonNull
protected final Context context;
protected final int widgetId;
- public NotificationsDailyAlarm(
+ public NotificationDailyAlarm(
@NonNull final Context widgetContext, final int theWidgetId) {
this.context = widgetContext;
this.widgetId = theWidgetId;
diff --git a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/preference/PreferencesFacade.java b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/preference/PreferencesFacade.java
index 35101939..3ebd0674 100755
--- a/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/preference/PreferencesFacade.java
+++ b/app/src/main/java/com/github/jameshnsears/quoteunquote/utils/preference/PreferencesFacade.java
@@ -19,11 +19,11 @@ public class PreferencesFacade {
protected int widgetId;
- public PreferencesFacade(@NonNull Context applicationContext) {
+ public PreferencesFacade(Context applicationContext) {
init(applicationContext);
}
- public PreferencesFacade(int theWidgetId, @NonNull Context applicationContext) {
+ public PreferencesFacade(int theWidgetId, Context applicationContext) {
widgetId = theWidgetId;
init(applicationContext);
}
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettings.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettings.kt
index 0f1c962e..0b1056f5 100755
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettings.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/TransferBackupSettings.kt
@@ -139,6 +139,8 @@ open class TransferBackupSettings(val context: Context) {
notificationsPreferences.customisableIntervalHourFrom,
notificationsPreferences.customisableIntervalHourTo,
notificationsPreferences.customisableIntervalHours,
+ notificationsPreferences.eventTtsSystem,
+ notificationsPreferences.eventTtsUk,
)
}
}
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/restore/TransferRestore.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/restore/TransferRestore.kt
index e7b77f9d..688fc68a 100755
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/restore/TransferRestore.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/cloud/transfer/backup/restore/TransferRestore.kt
@@ -253,34 +253,29 @@ class TransferRestore : TransferCommon() {
context,
)
+ notificationsPreferences.eventTtsUk = schedule.eventEventTtsUk
+ notificationsPreferences.eventTtsSystem = schedule.eventEventTtsSystem
+
notificationsPreferences.eventDaily = schedule.eventDaily
notificationsPreferences.eventDailyTimeHour = schedule.eventDailyHour
notificationsPreferences.eventDailyTimeMinute = schedule.eventDailyMinute
- if (schedule.eventEventCustomisableInterval != null) {
- notificationsPreferences.customisableInterval = schedule.eventEventCustomisableInterval
- }
-
- if (schedule.eventEventCustomisableIntervalHourFrom != null) {
- Timber.d("from = %d", schedule.eventEventCustomisableIntervalHourFrom)
- notificationsPreferences.customisableIntervalHourFrom =
- schedule.eventEventCustomisableIntervalHourFrom
- }
+ notificationsPreferences.customisableInterval = schedule.eventEventCustomisableInterval
- if (schedule.eventEventCustomisableIntervalHourTo != null) {
- Timber.d("to = %d", schedule.eventEventCustomisableIntervalHourTo)
- notificationsPreferences.customisableIntervalHourTo =
- schedule.eventEventCustomisableIntervalHourTo
- }
+ Timber.d("from = %d", schedule.eventEventCustomisableIntervalHourFrom)
+ notificationsPreferences.customisableIntervalHourFrom =
+ schedule.eventEventCustomisableIntervalHourFrom
- if (schedule.eventEventCustomisableIntervalHours != null) {
- Timber.d("hours = %d", schedule.eventEventCustomisableIntervalHours)
+ Timber.d("to = %d", schedule.eventEventCustomisableIntervalHourTo)
+ notificationsPreferences.customisableIntervalHourTo =
+ schedule.eventEventCustomisableIntervalHourTo
- notificationsPreferences.customisableIntervalHours =
- schedule.eventEventCustomisableIntervalHours
- }
+ Timber.d("hours = %d", schedule.eventEventCustomisableIntervalHours)
+ notificationsPreferences.customisableIntervalHours =
+ schedule.eventEventCustomisableIntervalHours
- notificationsPreferences.setEventDisplayWidgetAndNotification(schedule.eventDisplayWidgetAndNotification)
+ notificationsPreferences.eventDisplayWidgetAndNotification =
+ schedule.eventDisplayWidgetAndNotification
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val alarmManager: AlarmManager = context.getSystemService()!!
@@ -290,7 +285,7 @@ class TransferRestore : TransferCommon() {
}
if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
- notificationsPreferences.setEventDisplayWidgetAndNotification(false)
+ notificationsPreferences.eventDisplayWidgetAndNotification = false
}
}
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextFamilySpinnerAdapter.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextFamilySpinnerAdapter.kt
index 4e4d04f7..d1fc9d7f 100755
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextFamilySpinnerAdapter.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextFamilySpinnerAdapter.kt
@@ -50,7 +50,7 @@ class AppearanceTextFamilySpinnerAdapter(private val context: Context) : BaseAda
)
}
- view = view?.findViewById(android.R.id.text1) as TextView
+ view = view?.findViewById(android.R.id.text1)!!
view.text = getItem(position)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextStyleSpinnerAdapter.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextStyleSpinnerAdapter.kt
index cd3024ad..26552a00 100755
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextStyleSpinnerAdapter.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/appearance/tabs/style/AppearanceTextStyleSpinnerAdapter.kt
@@ -51,7 +51,7 @@ class AppearanceTextStyleSpinnerAdapter(private val context: Context) : BaseAdap
)
}
- view = view?.findViewById(android.R.id.text1) as TextView
+ view = view?.findViewById(android.R.id.text1)!!
view.text = getItem(position)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/ContentFilesFragment.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/ContentFilesFragment.kt
index 9f54c0e5..a9a20e0c 100644
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/ContentFilesFragment.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/ContentFilesFragment.kt
@@ -35,8 +35,6 @@ class ContentFilesFragment(widgetId: Int) : ContentFragment(widgetId) {
private val fragmentQuotationsTabDatabaseTabCsvBinding get() = _binding!!
- var quotationsPreferences: QuotationsPreferences? = null
-
private var storageAccessFrameworkActivityImportCSV: ActivityResultLauncher? = null
private var storageAccessFrameworkActivityExportCsv: ActivityResultLauncher? = null
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditComposable.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditComposable.kt
index 5660a641..fdb0654f 100644
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditComposable.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilesCsvInPlaceEditComposable.kt
@@ -95,7 +95,7 @@ fun InPlaceEditList(
.height(320.dp)
.padding(top = 4.dp, bottom = 14.dp),
) {
- LazyColumn() {
+ LazyColumn {
itemsIndexed(list) { index, quotation ->
val isSelected = selectedItemIndex == index
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilestCsvInPlaceEditDialog.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilestCsvInPlaceEditDialog.kt
index 60f5119b..748f451b 100644
--- a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilestCsvInPlaceEditDialog.kt
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/configure/fragment/quotations/tabs/content/files/csv/FilestCsvInPlaceEditDialog.kt
@@ -16,7 +16,7 @@ interface OnDialogDismissedListener {
fun onDialogDismissed()
}
-open class ContentCsvInPlaceEditDialog() : DialogFragment() {
+open class ContentCsvInPlaceEditDialog : DialogFragment() {
private var listener: OnDialogDismissedListener? = null
fun setListener(listener: OnDialogDismissedListener) {
diff --git a/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationTextToSpeechService.kt b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationTextToSpeechService.kt
new file mode 100644
index 00000000..f75f13e7
--- /dev/null
+++ b/app/src/main/kotlin/com/github/jameshnsears/quoteunquote/utils/notification/NotificationTextToSpeechService.kt
@@ -0,0 +1,85 @@
+package com.github.jameshnsears.quoteunquote.utils.notification
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.speech.tts.TextToSpeech
+import timber.log.Timber
+import java.util.Locale
+import java.util.concurrent.ConcurrentLinkedQueue
+
+class NotificationTextToSpeechService : Service(), TextToSpeech.OnInitListener {
+ companion object {
+ var isRunning = false
+ var localeTts = Locale.UK
+ }
+
+ private var tts: TextToSpeech? = null
+ private var isTtsInitialized = false
+ private val textQueue = ConcurrentLinkedQueue()
+
+ override fun onCreate() {
+ super.onCreate()
+ tts = TextToSpeech(this, this)
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ localeTts = when (intent?.getStringExtra("localeTts") ?: "UK") {
+ "UK" -> Locale.UK
+ else -> Locale.getDefault()
+ }
+ Timber.d("TTS: localeTts: $localeTts")
+
+ var textToSpeak = intent?.getStringExtra("textToSpeak") ?: ""
+
+ if (intent?.getBooleanExtra("excludeSource", false) == false) {
+ textToSpeak += intent.getStringExtra("textToSpeakSource")
+ }
+
+ Timber.d("TTS: textToSpeak: $textToSpeak")
+ textQueue.add(textToSpeak)
+
+ processTextQueue()
+
+ return START_NOT_STICKY
+ }
+
+ private fun processTextQueue() {
+ if (isTtsInitialized && tts != null && textQueue.isNotEmpty()) {
+ val text = textQueue.poll() ?: return
+
+ tts?.speak(
+ text,
+ TextToSpeech.QUEUE_FLUSH,
+ null,
+ "utteranceId-${System.currentTimeMillis()}",
+ )
+ }
+ }
+
+ override fun onInit(status: Int) {
+ if (status == TextToSpeech.SUCCESS) {
+ isTtsInitialized = true
+ Timber.d("TTS: init success")
+
+ val result = tts?.setLanguage(localeTts)
+
+ if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
+ Timber.e("TTS: init fail: language not supported")
+ } else {
+ processTextQueue()
+ }
+ } else {
+ Timber.e("TTS: init fail")
+ }
+ }
+
+ override fun onDestroy() {
+ tts?.shutdown()
+
+ isRunning = false
+ super.onDestroy()
+ }
+
+ override fun onBind(intent: Intent?): IBinder? = null
+}
diff --git a/app/src/main/res/drawable/example_appwidget_preview.png b/app/src/main/res/drawable/example_appwidget_preview.png
index b11876ca..81ef5d11 100644
Binary files a/app/src/main/res/drawable/example_appwidget_preview.png and b/app/src/main/res/drawable/example_appwidget_preview.png differ
diff --git a/app/src/main/res/layout/activity_instructions.xml b/app/src/main/res/layout/activity_instructions.xml
index c3dd82e2..d8db9fad 100755
--- a/app/src/main/res/layout/activity_instructions.xml
+++ b/app/src/main/res/layout/activity_instructions.xml
@@ -50,7 +50,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
+ android:padding="12dp">
+ android:padding="12dp">
diff --git a/app/src/main/res/layout/fragment_appearance_tab_style.xml b/app/src/main/res/layout/fragment_appearance_tab_style.xml
index 4a992945..472ae43a 100755
--- a/app/src/main/res/layout/fragment_appearance_tab_style.xml
+++ b/app/src/main/res/layout/fragment_appearance_tab_style.xml
@@ -27,7 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
+ android:paddingEnd="10dp"
+ android:paddingBottom="3dp">
@@ -243,10 +244,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingStart="10dp"
+ android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
- android:paddingBottom="5dp">
+ android:paddingBottom="9dp">
diff --git a/app/src/main/res/layout/fragment_appearance_tab_toolbar.xml b/app/src/main/res/layout/fragment_appearance_tab_toolbar.xml
index 7937c039..1843fd5f 100755
--- a/app/src/main/res/layout/fragment_appearance_tab_toolbar.xml
+++ b/app/src/main/res/layout/fragment_appearance_tab_toolbar.xml
@@ -124,6 +124,20 @@
tools:ignore="TextContrastCheck" />
+
+
+
+
+
+
+
+
+
+
+
+
@@ -47,7 +47,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
@@ -130,7 +130,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
+
+
+
+
+
+
-
-
+
+
+
+
+
+
@@ -224,7 +262,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
@@ -392,12 +431,14 @@
android:id="@+id/specificTimeLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:hint="@string/fragment_notifications_time_textfield">
+ android:hint="@string/fragment_notifications_time_textfield"
+ android:paddingBottom="5dp">
@@ -440,7 +481,7 @@
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="0dp"
- android:paddingBottom="10dp"
+ android:paddingBottom="8dp"
android:text="@string/fragment_notifications_exact_alarm_warning"
android:visibility="gone" />
diff --git a/app/src/main/res/layout/fragment_quotations.xml b/app/src/main/res/layout/fragment_quotations.xml
index 0585a5d6..a2038da9 100755
--- a/app/src/main/res/layout/fragment_quotations.xml
+++ b/app/src/main/res/layout/fragment_quotations.xml
@@ -24,7 +24,7 @@
android:paddingEnd="10dp"
android:text="@string/fragment_quotations_title"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
- android:textSize="24sp"
+ android:textSize="22sp"
android:textStyle="bold" />
diff --git a/app/src/main/res/layout/fragment_quotations_tab_database_tab_files.xml b/app/src/main/res/layout/fragment_quotations_tab_database_tab_files.xml
index aae58c22..58269691 100755
--- a/app/src/main/res/layout/fragment_quotations_tab_database_tab_files.xml
+++ b/app/src/main/res/layout/fragment_quotations_tab_database_tab_files.xml
@@ -27,7 +27,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="10dp">
+ android:padding="12dp">
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+
+ android:textSize="18sp"
+ android:textStyle="bold" />