Compare commits
25 Commits
1e04152687
...
v125010031
Author | SHA1 | Date | |
---|---|---|---|
11c39ae87c | |||
6645902ec8 | |||
0a07a5dfad | |||
d88d38fd3b | |||
28fe38aa17 | |||
d524c30732 | |||
8c00aa65da | |||
ae81261cb1 | |||
03c567ee33 | |||
d23dd82fc2 | |||
2e7a168424 | |||
5bc2f614af | |||
934c112db5 | |||
ad7549a89f | |||
fb9ceecabd | |||
61b9fd30e0 | |||
806e56e20b | |||
cd8b7aaf9d | |||
c25ad7621e | |||
63da3b9fe7 | |||
1d99eeb633 | |||
162a350a8f | |||
27c1bba146 | |||
b7f3a9877a | |||
47f78754dc |
@ -3,7 +3,7 @@ on:
|
|||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
BuildAndTest:
|
BuildAndTestAndCoverage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
@ -16,9 +16,30 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
- name: Setup Android SDK
|
cache: gradle
|
||||||
uses: android-actions/setup-android@v3
|
- uses: gradle/actions/setup-gradle@v3
|
||||||
|
- uses: android-actions/setup-android@v3
|
||||||
- name: Configure gradle...
|
- name: Configure gradle...
|
||||||
run: mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true" >> ~/.gradle/gradle.properties
|
run: mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true" >> ~/.gradle/gradle.properties
|
||||||
- name: Build and test
|
- name: Build and test
|
||||||
run: ./gradlew build -x test --stacktrace
|
run: ./gradlew build -x testReleaseUnitTest -x testDebugUnitTest -x testGithubConfigReleaseUnitTest -x testGithubConfigDebugUnitTest # These tests will be done
|
||||||
|
- uses: KengoTODA/actions-setup-docker-compose@v1
|
||||||
|
with:
|
||||||
|
version: "2.23.3"
|
||||||
|
- name: run selfoss
|
||||||
|
run: |
|
||||||
|
docker compose -f .gitea/workflows/assets/docker-compose.yml up -d
|
||||||
|
- name: coverage
|
||||||
|
run: |
|
||||||
|
./gradlew :koverHtmlReport
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: coverage
|
||||||
|
path: build/reports/kover/html
|
||||||
|
retention-days: 1
|
||||||
|
overwrite: true
|
||||||
|
include-hidden-files: true
|
||||||
|
- name: Clean
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
docker compose -f .gitea/workflows/assets/docker-compose.yml stop
|
@ -85,6 +85,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
|
cache: gradle
|
||||||
- name: Setup Android SDK
|
- name: Setup Android SDK
|
||||||
uses: android-actions/setup-android@v3
|
uses: android-actions/setup-android@v3
|
||||||
- name: Configure gradle...
|
- name: Configure gradle...
|
||||||
|
@ -12,8 +12,9 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
distribution: 'temurin'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
|
cache: gradle
|
||||||
- name: Install klint
|
- name: Install klint
|
||||||
run: curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.0.0/ktlint && chmod a+x ktlint && mv ktlint /usr/local/bin/
|
run: curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.0.0/ktlint && chmod a+x ktlint && mv ktlint /usr/local/bin/
|
||||||
- name: Install detekt
|
- name: Install detekt
|
||||||
@ -23,4 +24,5 @@ jobs:
|
|||||||
- name: Detecting...
|
- name: Detecting...
|
||||||
run: ./detekt-cli-1.23.1/bin/detekt-cli --all-rules --excludes '**/shared/build/**/*.kt' || true
|
run: ./detekt-cli-1.23.1/bin/detekt-cli --all-rules --excludes '**/shared/build/**/*.kt' || true
|
||||||
build:
|
build:
|
||||||
|
needs: Lint
|
||||||
uses: ./.gitea/workflows/common_build.yml
|
uses: ./.gitea/workflows/common_build.yml
|
@ -1,44 +0,0 @@
|
|||||||
name: Check master code
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
coverage:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Fetch tags
|
|
||||||
run: git fetch --tags -p
|
|
||||||
- uses: KengoTODA/actions-setup-docker-compose@v1
|
|
||||||
with:
|
|
||||||
version: "2.23.3"
|
|
||||||
- name: run selfoss
|
|
||||||
run: |
|
|
||||||
docker compose -f .gitea/workflows/assets/docker-compose.yml up -d
|
|
||||||
- uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: '17'
|
|
||||||
cache: gradle
|
|
||||||
- uses: gradle/actions/setup-gradle@v3
|
|
||||||
- uses: android-actions/setup-android@v3
|
|
||||||
- name: Configure gradle...
|
|
||||||
run: mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true" >> ~/.gradle/gradle.properties
|
|
||||||
- name: coverage
|
|
||||||
run: |
|
|
||||||
./gradlew :koverHtmlReport
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: coverage
|
|
||||||
path: build/reports/kover/html
|
|
||||||
retention-days: 1
|
|
||||||
overwrite: true
|
|
||||||
include-hidden-files: true
|
|
||||||
- name: Clean
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
docker compose -f .gitea/workflows/assets/docker-compose.yml stop
|
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -1,3 +1,22 @@
|
|||||||
|
**v124123651
|
||||||
|
|
||||||
|
- Merge pull request 'Bugfixes' (#171) from bugfixes into master
|
||||||
|
- config: crowdin
|
||||||
|
- chore: can links be empty ?
|
||||||
|
- fix: Context issues in article fragment.
|
||||||
|
- fix: Context issues in fragment sheet.
|
||||||
|
- fix: build.
|
||||||
|
- chore: compile issue fix.
|
||||||
|
- chore: filter some bugs.
|
||||||
|
- bugfix: catch users using something other than selfoss.
|
||||||
|
- bugfix: No browser, no link.
|
||||||
|
- translations
|
||||||
|
- chore: remove log.
|
||||||
|
- translation
|
||||||
|
- Changelog for v124123641
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
**v124123641
|
**v124123641
|
||||||
|
|
||||||
- Chore: no tests on build.
|
- Chore: no tests on build.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
val ignoreGitVersion: String by project
|
val ignoreGitVersion: String by project
|
||||||
val acraVersion = "5.9.7"
|
val acraVersion = "5.12.0"
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
@ -9,6 +9,7 @@ plugins {
|
|||||||
kotlin("kapt")
|
kotlin("kapt")
|
||||||
id("com.mikepenz.aboutlibraries.plugin")
|
id("com.mikepenz.aboutlibraries.plugin")
|
||||||
id("org.jetbrains.kotlinx.kover")
|
id("org.jetbrains.kotlinx.kover")
|
||||||
|
id("app.cash.sqldelight") version "2.0.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
||||||
@ -65,14 +66,14 @@ android {
|
|||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "17"
|
jvmTarget = "17"
|
||||||
}
|
}
|
||||||
compileSdk = 34
|
compileSdk = 35
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "bou.amine.apps.readerforselfossv2.android"
|
applicationId = "bou.amine.apps.readerforselfossv2.android"
|
||||||
minSdk = 25
|
minSdk = 25
|
||||||
targetSdk = 34
|
targetSdk = 34 // 35 when edge-to-edge is handled
|
||||||
versionCode = versionCodeFromGit()
|
versionCode = versionCodeFromGit()
|
||||||
versionName = versionNameFromGit()
|
versionName = versionNameFromGit()
|
||||||
|
|
||||||
@ -119,28 +120,26 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
|
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
|
||||||
|
|
||||||
implementation(project(":shared"))
|
implementation(project(":shared"))
|
||||||
implementation("com.google.android.material:material:1.9.0")
|
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
|
|
||||||
|
|
||||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
implementation("androidx.preference:preference-ktx:1.2.1")
|
||||||
|
|
||||||
implementation(fileTree(mapOf("include" to listOf("*.jar"), "dir" to "libs")))
|
implementation(fileTree(mapOf("include" to listOf("*.jar"), "dir" to "libs")))
|
||||||
|
|
||||||
// Android Support
|
// Android Support
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
implementation("com.google.android.material:material:1.9.0")
|
implementation("androidx.recyclerview:recyclerview:1.4.0-rc01")
|
||||||
implementation("androidx.recyclerview:recyclerview:1.3.1")
|
|
||||||
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
||||||
implementation("androidx.vectordrawable:vectordrawable:1.2.0-beta01")
|
implementation("androidx.vectordrawable:vectordrawable:1.2.0")
|
||||||
implementation("androidx.cardview:cardview:1.0.0")
|
implementation("androidx.cardview:cardview:1.0.0")
|
||||||
implementation("androidx.annotation:annotation:1.7.0")
|
implementation("androidx.annotation:annotation:1.9.1")
|
||||||
implementation("androidx.work:work-runtime-ktx:2.8.1")
|
implementation("androidx.work:work-runtime-ktx:2.10.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
|
||||||
implementation("org.jsoup:jsoup:1.15.4")
|
implementation("org.jsoup:jsoup:1.18.3")
|
||||||
|
|
||||||
//multidex
|
//multidex
|
||||||
implementation("androidx.multidex:multidex:2.0.1")
|
implementation("androidx.multidex:multidex:2.0.1")
|
||||||
@ -153,31 +152,31 @@ dependencies {
|
|||||||
implementation("com.ashokvarma.android:bottom-navigation-bar:2.2.0")
|
implementation("com.ashokvarma.android:bottom-navigation-bar:2.2.0")
|
||||||
|
|
||||||
// glide
|
// glide
|
||||||
kapt("com.github.bumptech.glide:compiler:4.15.0")
|
kapt("com.github.bumptech.glide:compiler:4.16.0")
|
||||||
implementation("com.github.bumptech.glide:okhttp3-integration:4.15.0")
|
implementation("com.github.bumptech.glide:okhttp3-integration:4.16.0")
|
||||||
|
|
||||||
// Themes
|
// Themes
|
||||||
implementation("com.github.rubensousa:floatingtoolbar:1.5.1")
|
implementation("com.github.rubensousa:floatingtoolbar:1.5.1")
|
||||||
|
|
||||||
// Pager
|
// Pager
|
||||||
implementation("me.relex:circleindicator:2.1.6")
|
implementation("me.relex:circleindicator:2.1.6")
|
||||||
implementation("androidx.viewpager2:viewpager2:1.1.0-beta02")
|
implementation("androidx.viewpager2:viewpager2:1.1.0")
|
||||||
|
|
||||||
//Dependency Injection
|
//Dependency Injection
|
||||||
implementation("org.kodein.di:kodein-di:7.14.0")
|
implementation("org.kodein.di:kodein-di:7.23.1")
|
||||||
implementation("org.kodein.di:kodein-di-framework-android-x:7.14.0")
|
implementation("org.kodein.di:kodein-di-framework-android-x:7.23.1")
|
||||||
implementation("org.kodein.di:kodein-di-framework-android-x-viewmodel:7.14.0")
|
implementation("org.kodein.di:kodein-di-framework-android-x-viewmodel:7.23.1")
|
||||||
|
|
||||||
//Settings
|
//Settings
|
||||||
implementation("com.russhwolf:multiplatform-settings-no-arg:0.9")
|
implementation("com.russhwolf:multiplatform-settings-no-arg:1.3.0")
|
||||||
|
|
||||||
//Logging
|
//Logging
|
||||||
implementation("io.github.aakira:napier:2.6.1")
|
implementation("io.github.aakira:napier:2.7.1")
|
||||||
|
|
||||||
//PhotoView
|
//PhotoView
|
||||||
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.12.0")
|
implementation("androidx.core:core-ktx:1.15.0")
|
||||||
|
|
||||||
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
|
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
|
||||||
|
|
||||||
@ -185,13 +184,13 @@ dependencies {
|
|||||||
implementation("com.github.ln-12:multiplatform-connectivity-status:1.3.0")
|
implementation("com.github.ln-12:multiplatform-connectivity-status:1.3.0")
|
||||||
|
|
||||||
// SQLDELIGHT
|
// SQLDELIGHT
|
||||||
implementation("com.squareup.sqldelight:android-driver:1.5.4")
|
implementation("app.cash.sqldelight:android-driver:2.0.2")
|
||||||
|
|
||||||
//test
|
//test
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
testImplementation("io.mockk:mockk:1.12.0")
|
testImplementation("io.mockk:mockk:1.13.14")
|
||||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
|
||||||
androidTestImplementation("androidx.test:runner:1.6.2")
|
androidTestImplementation("androidx.test:runner:1.6.2")
|
||||||
androidTestImplementation("androidx.test:rules:1.6.1")
|
androidTestImplementation("androidx.test:rules:1.6.1")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||||
@ -203,7 +202,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation("ch.acra:acra-http:$acraVersion")
|
implementation("ch.acra:acra-http:$acraVersion")
|
||||||
implementation("ch.acra:acra-toast:$acraVersion")
|
implementation("ch.acra:acra-toast:$acraVersion")
|
||||||
|
implementation("com.google.auto.service:auto-service:1.1.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test> {
|
tasks.withType<Test> {
|
||||||
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.ArrayRes
|
import androidx.annotation.ArrayRes
|
||||||
|
import androidx.test.espresso.Espresso.onData
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.action.ViewActions.replaceText
|
import androidx.test.espresso.action.ViewActions.replaceText
|
||||||
@ -14,6 +15,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
|||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
|
import org.hamcrest.Matchers.hasToString
|
||||||
|
|
||||||
fun performLogin(someUrl: String? = null) {
|
fun performLogin(someUrl: String? = null) {
|
||||||
onView(withId(R.id.urlView)).perform(click()).perform(
|
onView(withId(R.id.urlView)).perform(click()).perform(
|
||||||
@ -22,7 +24,6 @@ fun performLogin(someUrl: String? = null) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
onView(withId(R.id.signInButton)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
Thread.sleep(10000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loginAndInitHome() {
|
fun loginAndInitHome() {
|
||||||
@ -87,4 +88,22 @@ fun testPreferencesFromArray(
|
|||||||
openSettingItem()
|
openSettingItem()
|
||||||
onView(withText(res)).check(matches(allOf(isDisplayed(), isChecked())))
|
onView(withText(res)).check(matches(allOf(isDisplayed(), isChecked())))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAddSourceWithUrl(url: String, sourceName: String) {
|
||||||
|
onView(withId(R.id.fab))
|
||||||
|
.perform(click())
|
||||||
|
onView(withId(R.id.nameInput))
|
||||||
|
.perform(click()).perform(typeTextIntoFocusedView(sourceName))
|
||||||
|
onView(withId(R.id.sourceUri))
|
||||||
|
.perform(click())
|
||||||
|
.perform(typeTextIntoFocusedView(url))
|
||||||
|
onView(withId(R.id.tags))
|
||||||
|
.perform(click()).perform(typeTextIntoFocusedView("tag1,tag2,tag3"))
|
||||||
|
onView(withId(R.id.spoutsSpinner))
|
||||||
|
.perform(click())
|
||||||
|
onData(hasToString("RSS Feed")).perform(click())
|
||||||
|
onView(withId(R.id.saveBtn))
|
||||||
|
.perform(click())
|
||||||
|
onView(withText(sourceName)).check(matches(isDisplayed()))
|
||||||
}
|
}
|
@ -1,9 +1,6 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.test.core.app.ApplicationProvider
|
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
@ -47,9 +44,7 @@ class HomeActivityTest {
|
|||||||
isClickable()
|
isClickable()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
onView(withText(R.string.readAll)).check(matches(isDisplayed()))
|
onView(withText(R.string.readAll)).check(matches(isDisplayed()))
|
||||||
onView(withText(R.string.menu_home_sources)).check(matches(isDisplayed()))
|
onView(withText(R.string.menu_home_sources)).check(matches(isDisplayed()))
|
||||||
onView(withText(R.string.title_activity_settings)).check(matches(isDisplayed()))
|
onView(withText(R.string.title_activity_settings)).check(matches(isDisplayed()))
|
||||||
@ -78,43 +73,31 @@ class HomeActivityTest {
|
|||||||
).check(matches(isDisplayed()))
|
).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
|
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
onView(withText(R.string.readAll)).perform(click())
|
onView(withText(R.string.readAll)).perform(click())
|
||||||
onView(withText(R.string.markall_dialog_message)).check(matches(isDisplayed()))
|
onView(withText(R.string.markall_dialog_message)).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
|
|
||||||
onView(withText(R.string.menu_home_sources)).perform(click())
|
onView(withText(R.string.menu_home_sources)).perform(click())
|
||||||
onView(withId(R.id.fab)).check(matches(isDisplayed()))
|
onView(withId(R.id.fab)).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
|
|
||||||
onView(withText(R.string.title_activity_settings)).perform(click())
|
onView(withText(R.string.title_activity_settings)).perform(click())
|
||||||
onView(withText(R.string.pref_header_general)).check(matches(isDisplayed()))
|
onView(withText(R.string.pref_header_general)).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
|
|
||||||
onView(withText(R.string.menu_home_refresh)).perform(click())
|
onView(withText(R.string.menu_home_refresh)).perform(click())
|
||||||
onView(withText(R.string.refresh_dialog_message)).check(matches(isDisplayed()))
|
onView(withText(R.string.refresh_dialog_message)).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
|
|
||||||
/*onView(withText(R.string.issue_tracker_link)).perform(click())
|
/*onView(withText(R.string.issue_tracker_link)).perform(click())
|
||||||
onView(withText(R.string.markall_dialog_message)).check(matches(isDisplayed()))
|
onView(withText(R.string.markall_dialog_message)).check(matches(isDisplayed()))
|
||||||
onView(isRoot()).perform(ViewActions.pressBack())
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()*/
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)*/
|
|
||||||
|
|
||||||
onView(withText(R.string.action_disconnect)).perform(click())
|
onView(withText(R.string.action_disconnect)).perform(click())
|
||||||
onView(withText(R.string.confirm_disconnect_title)).check(matches(isDisplayed()))
|
onView(withText(R.string.confirm_disconnect_title)).check(matches(isDisplayed()))
|
||||||
|
@ -62,7 +62,7 @@ class LoginActivityTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun urlError() {
|
fun urlError() {
|
||||||
performLogin("172.17.0.1:8888")
|
performLogin("10.0.2.2:8888")
|
||||||
onView(withId(R.id.urlView)).perform(click())
|
onView(withId(R.id.urlView)).perform(click())
|
||||||
onView(withId(R.id.urlView)).check(matches(withError(R.string.wrong_infos)))
|
onView(withId(R.id.urlView)).check(matches(withError(R.string.wrong_infos)))
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
|||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.action.ViewActions.replaceText
|
import androidx.test.espresso.action.ViewActions.replaceText
|
||||||
|
import androidx.test.espresso.action.ViewActions.swipeUp
|
||||||
import androidx.test.espresso.action.ViewActions.typeTextIntoFocusedView
|
import androidx.test.espresso.action.ViewActions.typeTextIntoFocusedView
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
||||||
@ -102,6 +103,7 @@ class SettingsActivityGeneralTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
onView(withId(R.id.settings)).perform(swipeUp())
|
||||||
onView(withSettingsCheckboxWidget(R.string.display_all_counts_title)).check(
|
onView(withSettingsCheckboxWidget(R.string.display_all_counts_title)).check(
|
||||||
matches(
|
matches(
|
||||||
allOf(
|
allOf(
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.core.app.ApplicationProvider
|
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
@ -33,9 +31,7 @@ class SettingsActivityTest {
|
|||||||
context = activity.window.context
|
context = activity.window.context
|
||||||
}
|
}
|
||||||
loginAndInitHome()
|
loginAndInitHome()
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openMenu()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
onView(withText(R.string.title_activity_settings)).perform(click())
|
onView(withText(R.string.title_activity_settings)).perform(click())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
import android.content.Context
|
import androidx.test.espresso.AmbiguousViewMatcherException
|
||||||
import androidx.test.core.app.ApplicationProvider
|
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.action.ViewActions.scrollCompletelyTo
|
import androidx.test.espresso.action.ViewActions.swipeDown
|
||||||
import androidx.test.espresso.action.ViewActions.typeTextIntoFocusedView
|
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -23,7 +24,6 @@ import java.util.UUID
|
|||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@LargeTest
|
@LargeTest
|
||||||
class SourcesActivityTest {
|
class SourcesActivityTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val activityRule = ActivityScenarioRule(LoginActivity::class.java)
|
val activityRule = ActivityScenarioRule(LoginActivity::class.java)
|
||||||
|
|
||||||
@ -34,32 +34,50 @@ class SourcesActivityTest {
|
|||||||
sourceName = UUID.randomUUID().toString().substring(0, 15)
|
sourceName = UUID.randomUUID().toString().substring(0, 15)
|
||||||
|
|
||||||
loginAndInitHome()
|
loginAndInitHome()
|
||||||
openActionBarOverflowOrOptionsMenu(
|
goToSources()
|
||||||
ApplicationProvider.getApplicationContext<Context>()
|
|
||||||
)
|
|
||||||
onView(withText(R.string.menu_home_sources))
|
|
||||||
.perform(click())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun addSource() {
|
fun addSource() {
|
||||||
onView(withId(R.id.fab))
|
testAddSourceWithUrl(
|
||||||
.perform(click())
|
"https://lorem-rss.herokuapp.com/feed?unit=year&interval=1&length=10",
|
||||||
onView(withId(R.id.nameInput))
|
sourceName
|
||||||
.perform(click()).perform(typeTextIntoFocusedView(sourceName))
|
)
|
||||||
onView(withId(R.id.sourceUri))
|
|
||||||
.perform(click())
|
|
||||||
.perform(typeTextIntoFocusedView("https://lorem-rss.herokuapp.com/feed?unit=year&interval=1&length=10"))
|
|
||||||
onView(withId(R.id.tags))
|
|
||||||
.perform(click()).perform(typeTextIntoFocusedView("tag1,tag2,tag3"))
|
|
||||||
onView(withId(R.id.spoutsSpinner))
|
|
||||||
.perform(click())
|
|
||||||
onView(withText("RSS Feed"))
|
|
||||||
.perform(scrollCompletelyTo())
|
|
||||||
.perform(click())
|
|
||||||
onView(withId(R.id.saveBtn))
|
|
||||||
.perform(click())
|
|
||||||
onView(withText(sourceName)).check(matches(isDisplayed()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addSourceCheckContent() {
|
||||||
|
testAddSourceWithUrl("https://news.google.com/rss?hl=en-US&gl=US&ceid=US:en", sourceName)
|
||||||
|
onView(isRoot()).perform(ViewActions.pressBack())
|
||||||
|
openMenu()
|
||||||
|
onView(withText(R.string.menu_home_refresh)).perform(click())
|
||||||
|
onView(withText(R.string.refresh_dialog_message)).check(matches(isDisplayed()))
|
||||||
|
onView(
|
||||||
|
withId(android.R.id.button1)
|
||||||
|
).perform(click())
|
||||||
|
Thread.sleep(10000)
|
||||||
|
onView(withId(R.id.swipeRefreshLayout)).perform(swipeDown())
|
||||||
|
Thread.sleep(2000)
|
||||||
|
try {
|
||||||
|
onView(withId(R.id.sourceTitleAndDate)).check(matches(isDisplayed()))
|
||||||
|
} catch (e: AmbiguousViewMatcherException) {
|
||||||
|
assert(true)
|
||||||
|
}
|
||||||
|
goToSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun deleteTheCreatedSource() {
|
||||||
|
onView(withText(sourceName)).check(matches(isDisplayed()))
|
||||||
|
onView(withId(R.id.deleteBtn)).perform(click())
|
||||||
|
onView(withText(sourceName)).check(doesNotExist())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun goToSources() {
|
||||||
|
openMenu()
|
||||||
|
onView(withText(R.string.menu_home_sources))
|
||||||
|
.perform(click())
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
@ -7,6 +8,8 @@ import android.widget.RelativeLayout
|
|||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||||
import androidx.test.espresso.Root
|
import androidx.test.espresso.Root
|
||||||
import androidx.test.espresso.matcher.RootMatchers.isPlatformPopup
|
import androidx.test.espresso.matcher.RootMatchers.isPlatformPopup
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
|
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
|
||||||
@ -98,4 +101,10 @@ fun withSettingsCheckboxFrame(@StringRes id: Int): Matcher<View>? {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openMenu() {
|
||||||
|
openActionBarOverflowOrOptionsMenu(
|
||||||
|
ApplicationProvider.getApplicationContext<Context>()
|
||||||
|
)
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@ -32,6 +31,7 @@ import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
|||||||
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow
|
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge
|
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
||||||
@ -589,9 +589,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.issue_tracker -> {
|
R.id.issue_tracker -> {
|
||||||
val browserIntent =
|
baseContext.openUrlInBrowser(AppSettingsService.trackerUrl)
|
||||||
Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl))
|
|
||||||
startActivity(browserIntent)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,11 +8,11 @@ import android.widget.ImageView.ScaleType
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener
|
import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask
|
import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
|
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
@ -71,7 +71,7 @@ class ItemCardAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.browserBtn.setOnClickListener {
|
binding.browserBtn.setOnClickListener {
|
||||||
c.openInBrowserAsNewTask(items[position])
|
c.openItemUrlInBrowserAsNewTask(items[position])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,4 +126,4 @@ class ItemCardAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(val binding: CardItemBinding) : RecyclerView.ViewHolder(binding.root)
|
inner class ViewHolder(val binding: CardItemBinding) : RecyclerView.ViewHolder(binding.root)
|
||||||
}
|
}
|
@ -6,8 +6,8 @@ import android.view.ViewGroup
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.ListItemBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.ListItemBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener
|
import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
@ -73,4 +73,4 @@ class ItemListAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root)
|
inner class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root)
|
||||||
}
|
}
|
@ -1,16 +1,20 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.fragments
|
package bou.amine.apps.readerforselfossv2.android.fragments
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.TypedArray
|
import android.content.res.TypedArray
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.*
|
import android.view.GestureDetector
|
||||||
|
import android.view.InflateException
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.webkit.WebResourceResponse
|
import android.webkit.WebResourceResponse
|
||||||
import android.webkit.WebSettings
|
import android.webkit.WebSettings
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
@ -25,10 +29,11 @@ import bou.amine.apps.readerforselfossv2.android.databinding.FragmentArticleBind
|
|||||||
import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem
|
import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.toModel
|
import bou.amine.apps.readerforselfossv2.android.model.toModel
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.toParcelable
|
import bou.amine.apps.readerforselfossv2.android.model.toParcelable
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid
|
import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask
|
import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
|
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
|
||||||
import bou.amine.apps.readerforselfossv2.model.MercuryModel
|
import bou.amine.apps.readerforselfossv2.model.MercuryModel
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
@ -47,13 +52,14 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.acra.ktx.sendSilentlyWithAcra
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.DIAware
|
import org.kodein.di.DIAware
|
||||||
import org.kodein.di.android.x.closestDI
|
import org.kodein.di.android.x.closestDI
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import java.net.MalformedURLException
|
import java.net.MalformedURLException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
|
|
||||||
private const val IMAGE_JPG = "image/jpg"
|
private const val IMAGE_JPG = "image/jpg"
|
||||||
@ -98,7 +104,12 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
try {
|
try {
|
||||||
binding = FragmentArticleBinding.inflate(inflater, container, false)
|
binding = FragmentArticleBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
url = item.getLinkDecoded()
|
try {
|
||||||
|
url = item.getLinkDecoded()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
|
}
|
||||||
|
|
||||||
contentText = item.content
|
contentText = item.content
|
||||||
contentTitle = item.title.getHtmlDecoded()
|
contentTitle = item.title.getHtmlDecoded()
|
||||||
contentImage = item.getThumbnail(repository.baseUrl)
|
contentImage = item.getThumbnail(repository.baseUrl)
|
||||||
@ -152,7 +163,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
)
|
)
|
||||||
} catch (e: InflateException) {
|
} catch (e: InflateException) {
|
||||||
e.sendSilentlyWithAcraWithName("webview not available")
|
e.sendSilentlyWithAcraWithName("webview not available")
|
||||||
if (context != null) {
|
try {
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
|
.setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
|
||||||
.setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
|
.setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
|
||||||
@ -164,6 +175,8 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
}
|
}
|
||||||
.create()
|
.create()
|
||||||
.show()
|
.show()
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.sendSilentlyWithAcraWithName("Context required is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,16 +224,16 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
override fun onItemClick(item: MenuItem) {
|
override fun onItemClick(item: MenuItem) {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.share_action -> requireActivity().shareLink(url, contentTitle)
|
R.id.share_action -> requireActivity().shareLink(url, contentTitle)
|
||||||
R.id.open_action -> requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item)
|
R.id.open_action -> requireActivity().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
|
||||||
R.id.unread_action ->
|
R.id.unread_action ->
|
||||||
if (context != null) {
|
try {
|
||||||
if (this@ArticleFragment.item.unread) {
|
if (this@ArticleFragment.item.unread) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
repository.markAsRead(this@ArticleFragment.item)
|
repository.markAsRead(this@ArticleFragment.item)
|
||||||
}
|
}
|
||||||
this@ArticleFragment.item.unread = false
|
this@ArticleFragment.item.unread = false
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
requireContext(),
|
||||||
R.string.marked_as_read,
|
R.string.marked_as_read,
|
||||||
Toast.LENGTH_LONG,
|
Toast.LENGTH_LONG,
|
||||||
).show()
|
).show()
|
||||||
@ -235,7 +248,10 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
Toast.LENGTH_LONG,
|
Toast.LENGTH_LONG,
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.sendSilentlyWithAcraWithName("Context required is null")
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,7 +304,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
contentText = data.content.orEmpty()
|
contentText = data.content.orEmpty()
|
||||||
htmlToWebview()
|
htmlToWebview()
|
||||||
|
|
||||||
handleLeadImage(data?.lead_image_url)
|
handleLeadImage(data.lead_image_url)
|
||||||
|
|
||||||
binding.nestedScrollView.scrollTo(0, 0)
|
binding.nestedScrollView.scrollTo(0, 0)
|
||||||
binding.progressBar.visibility = View.GONE
|
binding.progressBar.visibility = View.GONE
|
||||||
@ -320,11 +336,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
url: String,
|
url: String,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return if (context != null && url.isUrlValid() && binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
return if (context != null && url.isUrlValid() && binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||||
try {
|
requireContext().openUrlInBrowser(url)
|
||||||
requireContext().startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
e.sendSilentlyWithAcraWithName("activityNotFound > $url")
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -343,7 +355,8 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
val image =
|
val image =
|
||||||
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
|
||||||
|
.get()
|
||||||
return WebResourceResponse(
|
return WebResourceResponse(
|
||||||
IMAGE_JPG,
|
IMAGE_JPG,
|
||||||
"UTF-8",
|
"UTF-8",
|
||||||
@ -355,7 +368,8 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
} else if (url.lowercase(Locale.US).contains(".png")) {
|
} else if (url.lowercase(Locale.US).contains(".png")) {
|
||||||
try {
|
try {
|
||||||
val image =
|
val image =
|
||||||
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
|
||||||
|
.get()
|
||||||
return WebResourceResponse(
|
return WebResourceResponse(
|
||||||
IMAGE_JPG,
|
IMAGE_JPG,
|
||||||
"UTF-8",
|
"UTF-8",
|
||||||
@ -367,7 +381,8 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
} else if (url.lowercase(Locale.US).contains(".webp")) {
|
} else if (url.lowercase(Locale.US).contains(".webp")) {
|
||||||
try {
|
try {
|
||||||
val image =
|
val image =
|
||||||
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
|
||||||
|
.get()
|
||||||
return WebResourceResponse(
|
return WebResourceResponse(
|
||||||
IMAGE_JPG,
|
IMAGE_JPG,
|
||||||
"UTF-8",
|
"UTF-8",
|
||||||
@ -384,7 +399,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun htmlToWebview() {
|
private fun htmlToWebview() {
|
||||||
if (context != null) {
|
try {
|
||||||
val attrs: IntArray = intArrayOf(android.R.attr.fontFamily)
|
val attrs: IntArray = intArrayOf(android.R.attr.fontFamily)
|
||||||
val a: TypedArray = requireContext().obtainStyledAttributes(resId, attrs)
|
val a: TypedArray = requireContext().obtainStyledAttributes(resId, attrs)
|
||||||
|
|
||||||
@ -529,6 +544,8 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
"utf-8",
|
"utf-8",
|
||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.sendSilentlyWithAcraWithName("Context required is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,10 +561,10 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
|
|
||||||
private fun openInBrowserAfterFailing() {
|
private fun openInBrowserAfterFailing() {
|
||||||
binding.progressBar.visibility = View.GONE
|
binding.progressBar.visibility = View.GONE
|
||||||
if (context != null) {
|
try {
|
||||||
requireContext().openInBrowserAsNewTask(this@ArticleFragment.item)
|
requireContext().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
|
||||||
} else {
|
} catch (e: IllegalStateException) {
|
||||||
Exception("openInBrowserAfterFailing context is null").sendSilentlyWithAcraWithName("openInBrowserAfterFailing > $context")
|
e.sendSilentlyWithAcraWithName("Context required is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,9 +582,9 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
|
|
||||||
fun performClick(): Boolean {
|
fun performClick(): Boolean {
|
||||||
if (allImages != null && (
|
if (allImages != null && (
|
||||||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
|
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
|
||||||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
val position: Int = allImages.indexOf(binding.webcontent.hitTestResult.extra)
|
val position: Int = allImages.indexOf(binding.webcontent.hitTestResult.extra)
|
||||||
|
|
||||||
@ -579,4 +596,4 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ import android.view.ViewGroup
|
|||||||
import bou.amine.apps.readerforselfossv2.android.HomeActivity
|
import bou.amine.apps.readerforselfossv2.android.HomeActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getColorHexCode
|
import bou.amine.apps.readerforselfossv2.utils.getColorHexCode
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
@ -52,19 +52,17 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
val context: Context? = context
|
try {
|
||||||
|
|
||||||
if (context == null) {
|
|
||||||
dismiss()
|
|
||||||
Exception("FilterSheetFragment context is null").sendSilentlyWithAcraWithName("FilterSheetFragment > onCreateView")
|
|
||||||
} else {
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
handleTagChips(context)
|
handleTagChips(requireContext())
|
||||||
handleSourceChips(context)
|
handleSourceChips(requireContext())
|
||||||
|
|
||||||
binding.progressBar2.visibility = GONE
|
binding.progressBar2.visibility = GONE
|
||||||
binding.filterView.visibility = VISIBLE
|
binding.filterView.visibility = VISIBLE
|
||||||
}
|
}
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
dismiss()
|
||||||
|
e.sendSilentlyWithAcraWithName("FilterSheetFragment > onCreateView")
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.floatingActionButton2.setOnClickListener {
|
binding.floatingActionButton2.setOnClickListener {
|
||||||
@ -192,4 +190,4 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
|
|||||||
companion object {
|
companion object {
|
||||||
const val TAG = "FilterModalBottomSheet"
|
const val TAG = "FilterModalBottomSheet"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ package bou.amine.apps.readerforselfossv2.android.model
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.webkit.URLUtil
|
import android.webkit.URLUtil
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getImages
|
import bou.amine.apps.readerforselfossv2.utils.getImages
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
@ -40,4 +40,4 @@ fun String.toTextDrawableString(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return textDrawable.toString()
|
return textDrawable.toString()
|
||||||
}
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.settings
|
package bou.amine.apps.readerforselfossv2.android.settings
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.InputFilter
|
import android.text.InputFilter
|
||||||
@ -16,7 +14,8 @@ import androidx.preference.Preference
|
|||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
|
||||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||||
import org.kodein.di.DIAware
|
import org.kodein.di.DIAware
|
||||||
@ -105,7 +104,9 @@ class SettingsActivity :
|
|||||||
|
|
||||||
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
|
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
|
||||||
Preference.OnPreferenceChangeListener { _, newValue ->
|
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
AppCompatDelegate.setDefaultNightMode(newValue.toString().toInt()) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
|
AppCompatDelegate.setDefaultNightMode(
|
||||||
|
newValue.toString().toInt()
|
||||||
|
) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +130,8 @@ class SettingsActivity :
|
|||||||
) {
|
) {
|
||||||
setPreferencesFromResource(R.xml.pref_general, rootKey)
|
setPreferencesFromResource(R.xml.pref_general, rootKey)
|
||||||
|
|
||||||
val editTextPreference = preferenceManager.findPreference<EditTextPreference>("prefer_api_items_number")
|
val editTextPreference =
|
||||||
|
preferenceManager.findPreference<EditTextPreference>("prefer_api_items_number")
|
||||||
editTextPreference?.setOnBindEditTextListener { editText ->
|
editTextPreference?.setOnBindEditTextListener { editText ->
|
||||||
editText.inputType = InputType.TYPE_CLASS_NUMBER
|
editText.inputType = InputType.TYPE_CLASS_NUMBER
|
||||||
editText.filters =
|
editText.filters =
|
||||||
@ -139,8 +141,11 @@ class SettingsActivity :
|
|||||||
val input: Int = (dest.toString() + source.toString()).toInt()
|
val input: Int = (dest.toString() + source.toString()).toInt()
|
||||||
if (input in 1..200) return@InputFilter null
|
if (input in 1..200) return@InputFilter null
|
||||||
} catch (nfe: NumberFormatException) {
|
} catch (nfe: NumberFormatException) {
|
||||||
nfe.sendSilentlyWithAcraWithName("GeneralPreferenceFragment")
|
Toast.makeText(
|
||||||
Toast.makeText(activity, R.string.items_number_should_be_number, Toast.LENGTH_LONG).show()
|
activity,
|
||||||
|
R.string.items_number_should_be_number,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
@ -222,16 +227,17 @@ class SettingsActivity :
|
|||||||
|
|
||||||
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
|
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
|
||||||
Preference.OnPreferenceChangeListener { _, newValue ->
|
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
AppCompatDelegate.setDefaultNightMode(newValue.toString().toInt()) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
|
AppCompatDelegate.setDefaultNightMode(
|
||||||
|
newValue.toString().toInt()
|
||||||
|
) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LinksPreferenceFragment : PreferenceFragmentCompat() {
|
class LinksPreferenceFragment : PreferenceFragmentCompat() {
|
||||||
private fun openUrl(uri: Uri?) {
|
private fun openUrl(url: String) {
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, uri)
|
context?.openUrlInBrowser(url)
|
||||||
startActivity(browserIntent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreatePreferences(
|
override fun onCreatePreferences(
|
||||||
@ -242,19 +248,19 @@ class SettingsActivity :
|
|||||||
|
|
||||||
preferenceManager.findPreference<Preference>("trackerLink")?.onPreferenceClickListener =
|
preferenceManager.findPreference<Preference>("trackerLink")?.onPreferenceClickListener =
|
||||||
Preference.OnPreferenceClickListener {
|
Preference.OnPreferenceClickListener {
|
||||||
openUrl(Uri.parse(AppSettingsService.trackerUrl))
|
openUrl(AppSettingsService.trackerUrl)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
preferenceManager.findPreference<Preference>("sourceLink")?.onPreferenceClickListener =
|
preferenceManager.findPreference<Preference>("sourceLink")?.onPreferenceClickListener =
|
||||||
Preference.OnPreferenceClickListener {
|
Preference.OnPreferenceClickListener {
|
||||||
openUrl(Uri.parse(AppSettingsService.sourceUrl))
|
openUrl(AppSettingsService.sourceUrl)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
preferenceManager.findPreference<Preference>("translation")?.onPreferenceClickListener =
|
preferenceManager.findPreference<Preference>("translation")?.onPreferenceClickListener =
|
||||||
Preference.OnPreferenceClickListener {
|
Preference.OnPreferenceClickListener {
|
||||||
openUrl(Uri.parse(AppSettingsService.translationUrl))
|
openUrl(AppSettingsService.translationUrl)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,4 +274,4 @@ class SettingsActivity :
|
|||||||
setPreferencesFromResource(R.xml.pref_experimental, rootKey)
|
setPreferencesFromResource(R.xml.pref_experimental, rootKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.utils
|
package bou.amine.apps.readerforselfossv2.android.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@ -17,6 +18,7 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
|||||||
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
|
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
|
|
||||||
|
|
||||||
fun Context.openItemUrl(
|
fun Context.openItemUrl(
|
||||||
currentItem: Int,
|
currentItem: Int,
|
||||||
linkDecoded: String,
|
linkDecoded: String,
|
||||||
@ -35,15 +37,13 @@ fun Context.openItemUrl(
|
|||||||
intent.putExtra("currentItem", currentItem)
|
intent.putExtra("currentItem", currentItem)
|
||||||
app.startActivity(intent)
|
app.startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
this.openUrlInBrowserAsNewTask(linkDecoded)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
intent.data = Uri.parse(linkDecoded.toStringUriWithHttp())
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.isUrlValid(): Boolean = this.toHttpUrlOrNull() != null && Patterns.WEB_URL.matcher(this).matches()
|
fun String.isUrlValid(): Boolean =
|
||||||
|
this.toHttpUrlOrNull() != null && Patterns.WEB_URL.matcher(this).matches()
|
||||||
|
|
||||||
fun String.isBaseUrlInvalid(): Boolean {
|
fun String.isBaseUrlInvalid(): Boolean {
|
||||||
val baseUrl = this.toHttpUrlOrNull()
|
val baseUrl = this.toHttpUrlOrNull()
|
||||||
@ -56,11 +56,31 @@ fun String.isBaseUrlInvalid(): Boolean {
|
|||||||
return !(Patterns.WEB_URL.matcher(this).matches() && existsAndEndsWithSlash)
|
return !(Patterns.WEB_URL.matcher(this).matches() && existsAndEndsWithSlash)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openInBrowserAsNewTask(i: SelfossModel.Item) {
|
fun Context.openItemUrlInBrowserAsNewTask(i: SelfossModel.Item) {
|
||||||
|
this.openUrlInBrowserAsNewTask(i.getLinkDecoded().toStringUriWithHttp())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.openUrlInBrowserAsNewTask(url: String) {
|
||||||
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
intent.data = Uri.parse(i.getLinkDecoded().toStringUriWithHttp())
|
intent.data = Uri.parse(url)
|
||||||
startActivity(intent)
|
this.mayBeStartActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.openUrlInBrowser(url: String) {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
|
intent.data = Uri.parse(url)
|
||||||
|
this.mayBeStartActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.mayBeStartActivity(intent: Intent) {
|
||||||
|
try {
|
||||||
|
this.startActivity(intent)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
Toast.makeText(this, getString(R.string.no_browser), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LinkOnTouchListener : View.OnTouchListener {
|
class LinkOnTouchListener : View.OnTouchListener {
|
||||||
@ -102,4 +122,4 @@ class LinkOnTouchListener : View.OnTouchListener {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android.utils.acra
|
||||||
|
|
||||||
import org.acra.ACRA
|
import org.acra.ACRA
|
||||||
import org.acra.ktx.sendSilentlyWithAcra
|
import org.acra.ktx.sendSilentlyWithAcra
|
||||||
@ -6,4 +6,4 @@ import org.acra.ktx.sendSilentlyWithAcra
|
|||||||
fun Throwable.sendSilentlyWithAcraWithName(name: String) {
|
fun Throwable.sendSilentlyWithAcraWithName(name: String) {
|
||||||
ACRA.errorReporter.putCustomData("error_source", name)
|
ACRA.errorReporter.putCustomData("error_source", name)
|
||||||
this.sendSilentlyWithAcra()
|
this.sendSilentlyWithAcra()
|
||||||
}
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package bou.amine.apps.readerforselfossv2.android.utils.acra
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.DeadSystemException
|
||||||
|
import com.google.auto.service.AutoService
|
||||||
|
import org.acra.builder.ReportBuilder
|
||||||
|
import org.acra.config.CoreConfiguration
|
||||||
|
import org.acra.config.ReportingAdministrator
|
||||||
|
import org.acra.data.CrashReportData
|
||||||
|
|
||||||
|
|
||||||
|
@AutoService(ReportingAdministrator::class)
|
||||||
|
class AcraReportingAdministrator : ReportingAdministrator {
|
||||||
|
override fun shouldStartCollecting(
|
||||||
|
context: Context,
|
||||||
|
config: CoreConfiguration,
|
||||||
|
reportBuilder: ReportBuilder
|
||||||
|
): Boolean {
|
||||||
|
return reportBuilder.exception !is DeadSystemException && (reportBuilder.exception != null && reportBuilder.exception!!::class.simpleName != "CannotDeliverBroadcastException")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldSendReport(
|
||||||
|
context: Context,
|
||||||
|
config: CoreConfiguration,
|
||||||
|
crashReportData: CrashReportData
|
||||||
|
): Boolean {
|
||||||
|
return crashReportData.get("BRAND") != "redroid"
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="@dimen/activity_horizontal_margin">
|
android:padding="@dimen/activity_horizontal_margin">
|
||||||
<!-- Login progress -->
|
<!-- Login progress -->
|
||||||
@ -37,7 +38,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/loginForm"
|
android:id="@+id/loginForm"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@ -100,4 +101,4 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"La contrasenya és massa curta"</string>
|
<string name="error_invalid_password">"La contrasenya és massa curta"</string>
|
||||||
<string name="error_field_required">"Camp necessari"</string>
|
<string name="error_field_required">"Camp necessari"</string>
|
||||||
<string name="prompt_url">"URL"</string>
|
<string name="prompt_url">"URL"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Autenticació (si és necessària)"</string>
|
<string name="withLoginSwitch">"Autenticació (si és necessària)"</string>
|
||||||
<string name="login_url_problem">"Pot ser que falti una \"/\" al final de l'url."</string>
|
<string name="login_url_problem">"Pot ser que falti una \"/\" al final de l'url."</string>
|
||||||
<string name="prompt_login">"Nom d'usuari"</string>
|
<string name="prompt_login">"Nom d'usuari"</string>
|
||||||
@ -83,7 +84,7 @@
|
|||||||
<string name="pref_switch_items_caching">Guarda els elements per utilitzar-los sense connexió</string>
|
<string name="pref_switch_items_caching">Guarda els elements per utilitzar-los sense connexió</string>
|
||||||
<string name="pref_switch_update_sources">Check for new sources and tags</string>
|
<string name="pref_switch_update_sources">Check for new sources and tags</string>
|
||||||
<string name="pref_switch_update_sources_summary">Disable this if your server is receiving excessive amounts of database queries.</string>
|
<string name="pref_switch_update_sources_summary">Disable this if your server is receiving excessive amounts of database queries.</string>
|
||||||
<string name="network_connectivity_lost">Sense connexió!</string>
|
<string name="network_connectivity_lost">"Sense connexió!"</string>
|
||||||
<string name="network_connectivity_retrieved">"Network connection is now available"</string>
|
<string name="network_connectivity_retrieved">"Network connection is now available"</string>
|
||||||
<string name="pref_switch_periodic_refresh">Sincronitza els articles</string>
|
<string name="pref_switch_periodic_refresh">Sincronitza els articles</string>
|
||||||
<string name="pref_switch_periodic_refresh_off">Els articles no se sincronitzaran en segon pla</string>
|
<string name="pref_switch_periodic_refresh_off">Els articles no se sincronitzaran en segon pla</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"No hi ha res"</string>
|
||||||
|
<string name="tab_new">"Nou"</string>
|
||||||
|
<string name="tab_read">"Tot"</string>
|
||||||
|
<string name="tab_favs">"Preferits"</string>
|
||||||
|
<string name="action_about">"Quant a"</string>
|
||||||
|
<string name="marked_as_read">"Element llegit"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Passwort ist nicht lang genug"</string>
|
<string name="error_invalid_password">"Passwort ist nicht lang genug"</string>
|
||||||
<string name="error_field_required">"Pflichtfeld"</string>
|
<string name="error_field_required">"Pflichtfeld"</string>
|
||||||
<string name="prompt_url">"URL"</string>
|
<string name="prompt_url">"URL"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Anmeldung erforderlich?"</string>
|
<string name="withLoginSwitch">"Anmeldung erforderlich?"</string>
|
||||||
<string name="login_url_problem">"Ups. Du musst eventuell ein \"/\" am Ende der URL anhängen."</string>
|
<string name="login_url_problem">"Ups. Du musst eventuell ein \"/\" am Ende der URL anhängen."</string>
|
||||||
<string name="prompt_login">"Benutzername"</string>
|
<string name="prompt_login">"Benutzername"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">Diese App teilt keine persönlichen Daten.</string>
|
<string name="gdpr_dialog_title">Diese App teilt keine persönlichen Daten.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Das Senden von Absturzberichten ist jetzt aktiviert. Die Funktion kann auf der Einstellungsseite deaktiviert werden, beachte aber bitte, dass Absturzberichte für die Anwendungsentwicklung von entscheidender Bedeutung sind.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Das Senden von Absturzberichten ist jetzt aktiviert. Die Funktion kann auf der Einstellungsseite deaktiviert werden, beachte aber bitte, dass Absturzberichte für die Anwendungsentwicklung von entscheidender Bedeutung sind.]]></string>
|
||||||
<string name="crash_toast_text">Die App ist abgestürzt. Details werden an den Entwickler gesendet.</string>
|
<string name="crash_toast_text">Die App ist abgestürzt. Details werden an den Entwickler gesendet.</string>
|
||||||
<string name="pref_switch_disable_acra">"Automatische Fehlerberichterstattung deaktivieren. "</string>
|
<string name="pref_switch_disable_acra">"Automatische Fehlerberichterstattung deaktivieren."</string>
|
||||||
<string name="menu_home_filter">Filter</string>
|
<string name="menu_home_filter">Filter</string>
|
||||||
<string name="application_selfoss_only">Diese App funktioniert nur mit einer Selfoss-Instanz, nicht mit einzelnen RSS-Feeds.</string>
|
<string name="application_selfoss_only">Diese App funktioniert nur mit einer Selfoss-Instanz, nicht mit einzelnen RSS-Feeds.</string>
|
||||||
<string name="menu_home_sources">Quellen</string>
|
<string name="menu_home_sources">Quellen</string>
|
||||||
<string name="update_source">Quelle aktualisieren</string>
|
<string name="update_source">Quelle aktualisieren</string>
|
||||||
<string name="confirm_disconnect_title">Verbindung trennen?</string>
|
<string name="confirm_disconnect_title">Verbindung trennen?</string>
|
||||||
<string name="confirm_disconnect_description">Die Verbindung zur Selfoss-Instanz wird getrennt.</string>
|
<string name="confirm_disconnect_description">Die Verbindung zur Selfoss-Instanz wird getrennt.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Keine Einträge vorhanden"</string>
|
||||||
|
<string name="tab_new">"Neu"</string>
|
||||||
|
<string name="tab_read">"Alle"</string>
|
||||||
|
<string name="tab_favs">"Favoriten"</string>
|
||||||
|
<string name="action_about">"Über"</string>
|
||||||
|
<string name="marked_as_read">"Artikel gelesen"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"La contraseña no es suficientemente larga"</string>
|
<string name="error_invalid_password">"La contraseña no es suficientemente larga"</string>
|
||||||
<string name="error_field_required">"Campo requerido"</string>
|
<string name="error_field_required">"Campo requerido"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Inicio de sesión requerido ?"</string>
|
<string name="withLoginSwitch">"Inicio de sesión requerido ?"</string>
|
||||||
<string name="login_url_problem">"Oops. Puede que necesite añadir un \"/\" al final de la url."</string>
|
<string name="login_url_problem">"Oops. Puede que necesite añadir un \"/\" al final de la url."</string>
|
||||||
<string name="prompt_login">"Nombre de usuario"</string>
|
<string name="prompt_login">"Nombre de usuario"</string>
|
||||||
@ -83,7 +84,7 @@
|
|||||||
<string name="pref_switch_items_caching">Guardar elementos para uso sin conexión</string>
|
<string name="pref_switch_items_caching">Guardar elementos para uso sin conexión</string>
|
||||||
<string name="pref_switch_update_sources">Check for new sources and tags</string>
|
<string name="pref_switch_update_sources">Check for new sources and tags</string>
|
||||||
<string name="pref_switch_update_sources_summary">Disable this if your server is receiving excessive amounts of database queries.</string>
|
<string name="pref_switch_update_sources_summary">Disable this if your server is receiving excessive amounts of database queries.</string>
|
||||||
<string name="network_connectivity_lost">Sin conexión!</string>
|
<string name="network_connectivity_lost">"Sin conexión!"</string>
|
||||||
<string name="network_connectivity_retrieved">"Network connection is now available"</string>
|
<string name="network_connectivity_retrieved">"Network connection is now available"</string>
|
||||||
<string name="pref_switch_periodic_refresh">Sincronizar artículos</string>
|
<string name="pref_switch_periodic_refresh">Sincronizar artículos</string>
|
||||||
<string name="pref_switch_periodic_refresh_off">Los artículos no se sincronizarán en segundo plano</string>
|
<string name="pref_switch_periodic_refresh_off">Los artículos no se sincronizarán en segundo plano</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Nada aquí"</string>
|
||||||
|
<string name="tab_new">"Nuevo"</string>
|
||||||
|
<string name="tab_read">"Todo"</string>
|
||||||
|
<string name="tab_favs">"Favoritos"</string>
|
||||||
|
<string name="action_about">"Acerca de"</string>
|
||||||
|
<string name="marked_as_read">"Artículo leído"</string>
|
||||||
|
<string name="marked_as_unread">"Artículo no leído"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Mot de passe trop court"</string>
|
<string name="error_invalid_password">"Mot de passe trop court"</string>
|
||||||
<string name="error_field_required">"Champ requis"</string>
|
<string name="error_field_required">"Champ requis"</string>
|
||||||
<string name="prompt_url">"Url Selfoss"</string>
|
<string name="prompt_url">"Url Selfoss"</string>
|
||||||
|
<string name="disable_ssl">"Désactiver la vérification SSL"</string>
|
||||||
<string name="withLoginSwitch">"Avec login ?"</string>
|
<string name="withLoginSwitch">"Avec login ?"</string>
|
||||||
<string name="login_url_problem">"Petit souci. Il manque peut-être un / à la fin ?"</string>
|
<string name="login_url_problem">"Petit souci. Il manque peut-être un / à la fin ?"</string>
|
||||||
<string name="prompt_login">"Utilisateur"</string>
|
<string name="prompt_login">"Utilisateur"</string>
|
||||||
@ -24,7 +25,7 @@
|
|||||||
<string name="all_posts_read">"Tous les posts sont lus"</string>
|
<string name="all_posts_read">"Tous les posts sont lus"</string>
|
||||||
<string name="undo_string">"Annuler"</string>
|
<string name="undo_string">"Annuler"</string>
|
||||||
<string name="addStringNoUrl">"Identifiez-vous pour ajouter une source."</string>
|
<string name="addStringNoUrl">"Identifiez-vous pour ajouter une source."</string>
|
||||||
<string name="cant_get_sources">"Impossible de récupérer la liste des sources"</string>
|
<string name="cant_get_sources">"Impossible de récupérer la liste des sources."</string>
|
||||||
<string name="cant_create_source">"Impossible de créer la source."</string>
|
<string name="cant_create_source">"Impossible de créer la source."</string>
|
||||||
<string name="cant_get_spouts_no_network">"Impossible d'obtenir la liste des spouts en raison d'un problème de réseau."</string>
|
<string name="cant_get_spouts_no_network">"Impossible d'obtenir la liste des spouts en raison d'un problème de réseau."</string>
|
||||||
<string name="cant_get_spouts">"Impossible d'obtenir la liste des spouts. Cela pourrait venir de l'api."</string>
|
<string name="cant_get_spouts">"Impossible d'obtenir la liste des spouts. Cela pourrait venir de l'api."</string>
|
||||||
@ -35,13 +36,13 @@
|
|||||||
<string name="warning_wrong_url">"ATTENTION"</string>
|
<string name="warning_wrong_url">"ATTENTION"</string>
|
||||||
<string name="pref_switch_card_view_title">"Vue en carte"</string>
|
<string name="pref_switch_card_view_title">"Vue en carte"</string>
|
||||||
<string name="share">"Partager"</string>
|
<string name="share">"Partager"</string>
|
||||||
<string name="switch_unread_count">"Afficher le nombre d'articles non lus sur la barre en bas de l'écran"</string>
|
<string name="switch_unread_count">"Afficher le nombre d'articles non lus sur la barre en bas de l'écran."</string>
|
||||||
<string name="switch_unread_count_title">"Afficher le nombre de non lus"</string>
|
<string name="switch_unread_count_title">"Afficher le nombre de non lus"</string>
|
||||||
<string name="display_all_counts_title">"Afficher le nombre de favoris et d'articles lus"</string>
|
<string name="display_all_counts_title">"Afficher le nombre de favoris et d'articles lus"</string>
|
||||||
<string name="text_wrong_url">"Vous semblez essayer de vous connecter avec une URL invalide. Assurez-vous que c'est la bonne, et si le problème persiste, contactez-moi via le lien du play store. Notez aussi que l'application ne peut fonctionner sans l'application web Selfoss. Vous ne pouvez pas utiliser l'application pour accéder directement aux flux RSS."</string>
|
<string name="text_wrong_url">"Vous semblez essayer de vous connecter avec une URL invalide. Assurez-vous que c'est la bonne, et si le problème persiste, contactez-moi via le lien du play store. Notez aussi que l'application ne peut fonctionner sans l'application web Selfoss. Vous ne pouvez pas utiliser l'application pour accéder directement aux flux RSS."</string>
|
||||||
<string name="pref_article_viewer_title">"Ouvrir les liens dans l'application"</string>
|
<string name="pref_article_viewer_title">"Ouvrir les liens dans l'application"</string>
|
||||||
<string name="pref_article_viewer_on">"Les articles s'ouvriront dans l'application"</string>
|
<string name="pref_article_viewer_on">"Les articles s'ouvriront dans l'application"</string>
|
||||||
<string name="pref_article_viewer_off">"Les articles s'ouvriront dans votre naviguateur par défaut"</string>
|
<string name="pref_article_viewer_off">"Les articles s'ouvriront dans votre navigateur par défaut"</string>
|
||||||
<string name="pref_general_category_links">"Gestion des liens"</string>
|
<string name="pref_general_category_links">"Gestion des liens"</string>
|
||||||
<string name="pref_general_category_displaying">"Affichage"</string>
|
<string name="pref_general_category_displaying">"Affichage"</string>
|
||||||
<string name="pref_switch_card_view_on">"Les articles seront affichés en forme de carte"</string>
|
<string name="pref_switch_card_view_on">"Les articles seront affichés en forme de carte"</string>
|
||||||
@ -58,7 +59,7 @@
|
|||||||
<string name="filter_item_sources">Sources</string>
|
<string name="filter_item_sources">Sources</string>
|
||||||
<string name="menu_home_search">Rechercher</string>
|
<string name="menu_home_search">Rechercher</string>
|
||||||
<string name="can_delete_source">Impossible de supprimer la source…</string>
|
<string name="can_delete_source">Impossible de supprimer la source…</string>
|
||||||
<string name="base_url_error">Il y a eu un souci lors de la communication avec votre instance Selfoss. Si le problèmes persiste, contactez-moi pour trouver une solution.</string>
|
<string name="base_url_error">Il y a eu un souci lors de la communication avec votre instance Selfoss. Si le problème persiste, contactez-moi pour trouver une solution.</string>
|
||||||
<string name="pref_header_theme">Thèmes</string>
|
<string name="pref_header_theme">Thèmes</string>
|
||||||
<string name="pref_selfoss_category">Api Selfoss</string>
|
<string name="pref_selfoss_category">Api Selfoss</string>
|
||||||
<string name="pref_api_items_number_title">Nombre d\'articles chargés</string>
|
<string name="pref_api_items_number_title">Nombre d\'articles chargés</string>
|
||||||
@ -74,7 +75,7 @@
|
|||||||
<string name="pref_header_viewer">Lecteur d\'articles</string>
|
<string name="pref_header_viewer">Lecteur d\'articles</string>
|
||||||
<string name="refresh_dialog_message">En validant, votre instance Selfoss sera mise à jour.</string>
|
<string name="refresh_dialog_message">En validant, votre instance Selfoss sera mise à jour.</string>
|
||||||
<string name="markall_dialog_message">Marquer tous les éléments comme lus ?</string>
|
<string name="markall_dialog_message">Marquer tous les éléments comme lus ?</string>
|
||||||
<string name="pref_switch_actions_pager_scroll">Marquer comme lu à la navigation.</string>
|
<string name="pref_switch_actions_pager_scroll">Marquer comme lu à la navigation</string>
|
||||||
<string name="pref_switch_actions_pager_scroll_off">Ne pas marquer les articles comme lus à la navigation.</string>
|
<string name="pref_switch_actions_pager_scroll_off">Ne pas marquer les articles comme lus à la navigation.</string>
|
||||||
<string name="unmark">Marquer l\'article comme non lu</string>
|
<string name="unmark">Marquer l\'article comme non lu</string>
|
||||||
<string name="pref_header_offline">Hors ligne et cache</string>
|
<string name="pref_header_offline">Hors ligne et cache</string>
|
||||||
@ -86,9 +87,9 @@
|
|||||||
<string name="network_connectivity_lost">"Connexion au réseau perdue"</string>
|
<string name="network_connectivity_lost">"Connexion au réseau perdue"</string>
|
||||||
<string name="network_connectivity_retrieved">"Connexion réseau de nouveau disponible"</string>
|
<string name="network_connectivity_retrieved">"Connexion réseau de nouveau disponible"</string>
|
||||||
<string name="pref_switch_periodic_refresh">Synchroniser les articles</string>
|
<string name="pref_switch_periodic_refresh">Synchroniser les articles</string>
|
||||||
<string name="pref_switch_periodic_refresh_off">Les articles ne seront pas synchronisés en arrière plan</string>
|
<string name="pref_switch_periodic_refresh_off">Les articles ne seront pas synchronisés en arrière-plan</string>
|
||||||
<string name="pref_switch_periodic_refresh_on">Articles seront périodiquement synchronisées</string>
|
<string name="pref_switch_periodic_refresh_on">Articles seront périodiquement synchronisés</string>
|
||||||
<string name="pref_periodic_refresh_minutes_title"><![CDATA[Interval de synchronisation ( >= 15 minutes)]]></string>
|
<string name="pref_periodic_refresh_minutes_title"><![CDATA[Intervalle de synchronisation ( >= 15 minutes)]]></string>
|
||||||
<string name="pref_switch_refresh_when_charging">Synchroniser uniquement lorsque le téléphone est en charge</string>
|
<string name="pref_switch_refresh_when_charging">Synchroniser uniquement lorsque le téléphone est en charge</string>
|
||||||
<string name="loading_notification_title">Chargement …</string>
|
<string name="loading_notification_title">Chargement …</string>
|
||||||
<string name="loading_notification_text">Selfoss synchronise vos articles</string>
|
<string name="loading_notification_text">Selfoss synchronise vos articles</string>
|
||||||
@ -100,7 +101,7 @@
|
|||||||
<string name="shortcut_offline">Hors ligne</string>
|
<string name="shortcut_offline">Hors ligne</string>
|
||||||
<string name="pref_api_timeout">Timeout de l\'api</string>
|
<string name="pref_api_timeout">Timeout de l\'api</string>
|
||||||
<string name="pref_header_experimental">Expérimental</string>
|
<string name="pref_header_experimental">Expérimental</string>
|
||||||
<string name="webview_dialog_issue_message">Pas de Webview disponible. Désactivation du lecteur d\'article pour éviter les futures erreurs. Les articles seront lu via votre navigateur à l\'avenir.</string>
|
<string name="webview_dialog_issue_message">Pas de Webview disponible. Désactivation du lecteur d\'article pour éviter les futures erreurs. Les articles seront lus via votre navigateur à l\'avenir.</string>
|
||||||
<string name="webview_dialog_issue_title">Problème de Webview</string>
|
<string name="webview_dialog_issue_title">Problème de Webview</string>
|
||||||
<string name="reader_text_align_left">Aligner à gauche</string>
|
<string name="reader_text_align_left">Aligner à gauche</string>
|
||||||
<string name="reader_text_align_justify">Justifier le texte</string>
|
<string name="reader_text_align_justify">Justifier le texte</string>
|
||||||
@ -113,8 +114,8 @@
|
|||||||
<string name="mode_dark">Thème sombre</string>
|
<string name="mode_dark">Thème sombre</string>
|
||||||
<string name="mode_system">Utiliser les paramètres système</string>
|
<string name="mode_system">Utiliser les paramètres système</string>
|
||||||
<string name="mode_light">Thème clair</string>
|
<string name="mode_light">Thème clair</string>
|
||||||
<string name="gdpr_dialog_title">L\'application ne partage aucune information personnelle</string>
|
<string name="gdpr_dialog_title">L\'application ne partage aucune information personnelle.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Le rapport de plantage est activés par défaut. Il peut être désactivé depuis les paramètres de l\'application. Notez que les rapports de plantage sont essentiels pour le développement de l'application.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Le rapport de plantage est activés par défaut. Il peut être désactivé depuis les paramètres de l\'application. Notez que les rapports de plantage sont essentiels pour le développement de l\'application.]]></string>
|
||||||
<string name="crash_toast_text">Un bug s\'est produit. Le développeur en sera informé.</string>
|
<string name="crash_toast_text">Un bug s\'est produit. Le développeur en sera informé.</string>
|
||||||
<string name="pref_switch_disable_acra">"Désactiver les rapports de plantage."</string>
|
<string name="pref_switch_disable_acra">"Désactiver les rapports de plantage."</string>
|
||||||
<string name="menu_home_filter">Filtres</string>
|
<string name="menu_home_filter">Filtres</string>
|
||||||
@ -123,5 +124,12 @@
|
|||||||
<string name="update_source">Mise à jour des sources</string>
|
<string name="update_source">Mise à jour des sources</string>
|
||||||
<string name="confirm_disconnect_title">Se déconnecter ?</string>
|
<string name="confirm_disconnect_title">Se déconnecter ?</string>
|
||||||
<string name="confirm_disconnect_description">Vous allez être déconnecté de votre instance Selfoss.</string>
|
<string name="confirm_disconnect_description">Vous allez être déconnecté de votre instance Selfoss.</string>
|
||||||
<string name="disable_ssl">Désactiver la vérification SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Il n'y a rien ici !"</string>
|
||||||
|
<string name="tab_new">"Non lus"</string>
|
||||||
|
<string name="tab_read">"Tous"</string>
|
||||||
|
<string name="tab_favs">"Favoris"</string>
|
||||||
|
<string name="action_about">"À propos"</string>
|
||||||
|
<string name="marked_as_read">"Marqué comme lu"</string>
|
||||||
|
<string name="marked_as_unread">"Marqué comme non lu"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"O contrasinal non é suficientemente longo"</string>
|
<string name="error_invalid_password">"O contrasinal non é suficientemente longo"</string>
|
||||||
<string name="error_field_required">"Campo requirido"</string>
|
<string name="error_field_required">"Campo requirido"</string>
|
||||||
<string name="prompt_url">"URL"</string>
|
<string name="prompt_url">"URL"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"É preciso iniciar sesión?"</string>
|
<string name="withLoginSwitch">"É preciso iniciar sesión?"</string>
|
||||||
<string name="login_url_problem">"Ups! Pode que precises engadir un \"/\" o final da URL."</string>
|
<string name="login_url_problem">"Ups! Pode que precises engadir un \"/\" o final da URL."</string>
|
||||||
<string name="prompt_login">"Nome de usuario"</string>
|
<string name="prompt_login">"Nome de usuario"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">A aplicación non comparte ningún dato persoal seu.</string>
|
<string name="gdpr_dialog_title">A aplicación non comparte ningún dato persoal seu.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[O envío de informes de erros está habilitado. Pode deshabilitarse dende a páxina de axustes. Ten en conta que os informes de erros son esenciais para o desenvolvemento da aplicación.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[O envío de informes de erros está habilitado. Pode deshabilitarse dende a páxina de axustes. Ten en conta que os informes de erros son esenciais para o desenvolvemento da aplicación.]]></string>
|
||||||
<string name="crash_toast_text">Ocurriu un erro. Enviando os detalles o desenvolvedor.</string>
|
<string name="crash_toast_text">Ocurriu un erro. Enviando os detalles o desenvolvedor.</string>
|
||||||
<string name="pref_switch_disable_acra">"Deshabilitar o reporte automático de erros. "</string>
|
<string name="pref_switch_disable_acra">"Deshabilitar o reporte automático de erros."</string>
|
||||||
<string name="menu_home_filter">Filtros</string>
|
<string name="menu_home_filter">Filtros</string>
|
||||||
<string name="application_selfoss_only">Esta aplicación só funciona cunha instancia de Selfoss, e con ningún outro filtro RSS.</string>
|
<string name="application_selfoss_only">Esta aplicación só funciona cunha instancia de Selfoss, e con ningún outro filtro RSS.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Non hai nada aquí"</string>
|
||||||
|
<string name="tab_new">"Novo"</string>
|
||||||
|
<string name="tab_read">"Todos"</string>
|
||||||
|
<string name="tab_favs">"Favoritos"</string>
|
||||||
|
<string name="action_about">"Acerca de"</string>
|
||||||
|
<string name="marked_as_read">"Elemento lido"</string>
|
||||||
|
<string name="marked_as_unread">"Elemento non lido"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Kata sandinya tidak cukup panjang"</string>
|
<string name="error_invalid_password">"Kata sandinya tidak cukup panjang"</string>
|
||||||
<string name="error_field_required">"Kolom wajib diisi"</string>
|
<string name="error_field_required">"Kolom wajib diisi"</string>
|
||||||
<string name="prompt_url">"URL"</string>
|
<string name="prompt_url">"URL"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Harus masuk?"</string>
|
<string name="withLoginSwitch">"Harus masuk?"</string>
|
||||||
<string name="login_url_problem">"Ups. Anda mungkin harus menambahkan \"/\" di akhir url."</string>
|
<string name="login_url_problem">"Ups. Anda mungkin harus menambahkan \"/\" di akhir url."</string>
|
||||||
<string name="prompt_login">"Nama pengguna"</string>
|
<string name="prompt_login">"Nama pengguna"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Tidak ada di sini"</string>
|
||||||
|
<string name="tab_new">"Baru"</string>
|
||||||
|
<string name="tab_read">"Semua"</string>
|
||||||
|
<string name="tab_favs">"Favorit"</string>
|
||||||
|
<string name="action_about">"Tentang"</string>
|
||||||
|
<string name="marked_as_read">"Membaca item"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"La password non è sufficientemente lunga"</string>
|
<string name="error_invalid_password">"La password non è sufficientemente lunga"</string>
|
||||||
<string name="error_field_required">"Campo obbligatorio"</string>
|
<string name="error_field_required">"Campo obbligatorio"</string>
|
||||||
<string name="prompt_url">"URL"</string>
|
<string name="prompt_url">"URL"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"È richiesto l'accesso?"</string>
|
<string name="withLoginSwitch">"È richiesto l'accesso?"</string>
|
||||||
<string name="login_url_problem">"Oops. Potrebbe essere necessario aggiungere un \"/\" alla fine dell'url."</string>
|
<string name="login_url_problem">"Oops. Potrebbe essere necessario aggiungere un \"/\" alla fine dell'url."</string>
|
||||||
<string name="prompt_login">"Nome utente"</string>
|
<string name="prompt_login">"Nome utente"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Non c'è niente qui"</string>
|
||||||
|
<string name="tab_new">"Nuovi"</string>
|
||||||
|
<string name="tab_read">"Tutti"</string>
|
||||||
|
<string name="tab_favs">"Preferiti"</string>
|
||||||
|
<string name="action_about">"Informazioni"</string>
|
||||||
|
<string name="marked_as_read">"Articolo letto"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"패스워드가 짧습니다."</string>
|
<string name="error_invalid_password">"패스워드가 짧습니다."</string>
|
||||||
<string name="error_field_required">"필수 항목"</string>
|
<string name="error_field_required">"필수 항목"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"로그인이 필요합니까?"</string>
|
<string name="withLoginSwitch">"로그인이 필요합니까?"</string>
|
||||||
<string name="login_url_problem">"죄송합니다. Url의 끝에 \"/\"를 추가할 필요가 있습니다."</string>
|
<string name="login_url_problem">"죄송합니다. Url의 끝에 \"/\"를 추가할 필요가 있습니다."</string>
|
||||||
<string name="prompt_login">"사용자 이름"</string>
|
<string name="prompt_login">"사용자 이름"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"비어있음"</string>
|
||||||
|
<string name="tab_new">"새로운"</string>
|
||||||
|
<string name="tab_read">"전체"</string>
|
||||||
|
<string name="tab_favs">"즐겨찾기"</string>
|
||||||
|
<string name="action_about">"정보"</string>
|
||||||
|
<string name="marked_as_read">"항목 읽기"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Wachtwoord niet lang genoeg"</string>
|
<string name="error_invalid_password">"Wachtwoord niet lang genoeg"</string>
|
||||||
<string name="error_field_required">"Dit veld is verplicht"</string>
|
<string name="error_field_required">"Dit veld is verplicht"</string>
|
||||||
<string name="prompt_url">"Selfoss server"</string>
|
<string name="prompt_url">"Selfoss server"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Authenticatie vereist?"</string>
|
<string name="withLoginSwitch">"Authenticatie vereist?"</string>
|
||||||
<string name="login_url_problem">"Oeps, ben je soms de \"/\" vergeten aan het eind?"</string>
|
<string name="login_url_problem">"Oeps, ben je soms de \"/\" vergeten aan het eind?"</string>
|
||||||
<string name="prompt_login">"Gebruikersnaam"</string>
|
<string name="prompt_login">"Gebruikersnaam"</string>
|
||||||
@ -22,7 +23,6 @@
|
|||||||
<string name="wrong_infos">"Controleer de gegevens nogmaals."</string>
|
<string name="wrong_infos">"Controleer de gegevens nogmaals."</string>
|
||||||
<string name="all_posts_not_read">"Fout bij markeren als gelezen"</string>
|
<string name="all_posts_not_read">"Fout bij markeren als gelezen"</string>
|
||||||
<string name="all_posts_read">"Alle artikelen gemarkeerd als gelezen"</string>
|
<string name="all_posts_read">"Alle artikelen gemarkeerd als gelezen"</string>
|
||||||
<string name="undo_string">"Ongedaan maken"</string>
|
|
||||||
<string name="addStringNoUrl">"Login om bronnen toe te voegen"</string>
|
<string name="addStringNoUrl">"Login om bronnen toe te voegen"</string>
|
||||||
<string name="cant_get_sources">"Kan de lijst met bronnen niet ophalen"</string>
|
<string name="cant_get_sources">"Kan de lijst met bronnen niet ophalen"</string>
|
||||||
<string name="cant_create_source">"Kan bron niet creëeren"</string>
|
<string name="cant_create_source">"Kan bron niet creëeren"</string>
|
||||||
@ -116,12 +116,20 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Niets gevonden"</string>
|
||||||
|
<string name="tab_new">"Nieuw"</string>
|
||||||
|
<string name="tab_read">"Alle"</string>
|
||||||
|
<string name="tab_favs">"Favorieten"</string>
|
||||||
|
<string name="action_about">"Over"</string>
|
||||||
|
<string name="marked_as_read">"Artikel gelezen"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
|
<string name="undo_string">"Ongedaan maken"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Senha muito pequena"</string>
|
<string name="error_invalid_password">"Senha muito pequena"</string>
|
||||||
<string name="error_field_required">"Campo obrigatório"</string>
|
<string name="error_field_required">"Campo obrigatório"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"É necessário o login ?"</string>
|
<string name="withLoginSwitch">"É necessário o login ?"</string>
|
||||||
<string name="login_url_problem">"Oops. Talvez você precise adicionar uma \"/\" no final da url."</string>
|
<string name="login_url_problem">"Oops. Talvez você precise adicionar uma \"/\" no final da url."</string>
|
||||||
<string name="prompt_login">"Usuário"</string>
|
<string name="prompt_login">"Usuário"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Nada aqui"</string>
|
||||||
|
<string name="tab_new">"Novo"</string>
|
||||||
|
<string name="tab_read">"Todos"</string>
|
||||||
|
<string name="tab_favs">"Favoritos"</string>
|
||||||
|
<string name="action_about">"Sobre"</string>
|
||||||
|
<string name="marked_as_read">"Item lido"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Senha não é longa o suficiente"</string>
|
<string name="error_invalid_password">"Senha não é longa o suficiente"</string>
|
||||||
<string name="error_field_required">"Campo obrigatório"</string>
|
<string name="error_field_required">"Campo obrigatório"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"É necessário fazer login?"</string>
|
<string name="withLoginSwitch">"É necessário fazer login?"</string>
|
||||||
<string name="login_url_problem">"Uups. Você pode precisar adicionar uma \"/\" no final da url."</string>
|
<string name="login_url_problem">"Uups. Você pode precisar adicionar uma \"/\" no final da url."</string>
|
||||||
<string name="prompt_login">"Nome do usuário"</string>
|
<string name="prompt_login">"Nome do usuário"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Nada aqui"</string>
|
||||||
|
<string name="tab_new">"Novo"</string>
|
||||||
|
<string name="tab_read">"Tudo"</string>
|
||||||
|
<string name="tab_favs">"Favoritos"</string>
|
||||||
|
<string name="action_about">"Sobre"</string>
|
||||||
|
<string name="marked_as_read">"Item lido"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Password not long enough"</string>
|
<string name="error_invalid_password">"Password not long enough"</string>
|
||||||
<string name="error_field_required">"Field required"</string>
|
<string name="error_field_required">"Field required"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Login required ?"</string>
|
<string name="withLoginSwitch">"Login required ?"</string>
|
||||||
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
|
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
|
||||||
<string name="prompt_login">"පරිශීලක නාමය"</string>
|
<string name="prompt_login">"පරිශීලක නාමය"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Nothing here"</string>
|
||||||
|
<string name="tab_new">"New"</string>
|
||||||
|
<string name="tab_read">"සියල්ල"</string>
|
||||||
|
<string name="tab_favs">"Favorites"</string>
|
||||||
|
<string name="action_about">"මේ ගැන"</string>
|
||||||
|
<string name="marked_as_read">"Item read"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"Parola yeterince uzun değil"</string>
|
<string name="error_invalid_password">"Parola yeterince uzun değil"</string>
|
||||||
<string name="error_field_required">"Alan gereklidir"</string>
|
<string name="error_field_required">"Alan gereklidir"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Kullanıcı Girişi Gerekli?"</string>
|
<string name="withLoginSwitch">"Kullanıcı Girişi Gerekli?"</string>
|
||||||
<string name="login_url_problem">"Oops. Url'nin sonuna \"/\" eklemek gerekebilir."</string>
|
<string name="login_url_problem">"Oops. Url'nin sonuna \"/\" eklemek gerekebilir."</string>
|
||||||
<string name="prompt_login">"Kullanıcı adı"</string>
|
<string name="prompt_login">"Kullanıcı adı"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Burada hiçbir şey yok"</string>
|
||||||
|
<string name="tab_new">"Yeni"</string>
|
||||||
|
<string name="tab_read">"Tüm"</string>
|
||||||
|
<string name="tab_favs">"Favoriler"</string>
|
||||||
|
<string name="action_about">"Hakkında"</string>
|
||||||
|
<string name="marked_as_read">"Öğeleri oku"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"密码不够长"</string>
|
<string name="error_invalid_password">"密码不够长"</string>
|
||||||
<string name="error_field_required">"必填字段"</string>
|
<string name="error_field_required">"必填字段"</string>
|
||||||
<string name="prompt_url">"网址"</string>
|
<string name="prompt_url">"网址"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"需要登录?"</string>
|
<string name="withLoginSwitch">"需要登录?"</string>
|
||||||
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</string>
|
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</string>
|
||||||
<string name="prompt_login">"用户名"</string>
|
<string name="prompt_login">"用户名"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">该应用不分享任何关于您的个人数据。</string>
|
<string name="gdpr_dialog_title">该应用不分享任何关于您的个人数据。</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[崩溃报告发送现已启用。 可以从设置页面禁用它。 请记住,崩溃报告对于应用程序开发是必需的。]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[崩溃报告发送现已启用。 可以从设置页面禁用它。 请记住,崩溃报告对于应用程序开发是必需的。]]></string>
|
||||||
<string name="crash_toast_text">发生崩溃。请将细节发送给开发人员。</string>
|
<string name="crash_toast_text">发生崩溃。请将细节发送给开发人员。</string>
|
||||||
<string name="pref_switch_disable_acra">"禁用自动错误报告 "</string>
|
<string name="pref_switch_disable_acra">"禁用自动错误报告"</string>
|
||||||
<string name="menu_home_filter">筛选器</string>
|
<string name="menu_home_filter">筛选器</string>
|
||||||
<string name="application_selfoss_only">此应用只适用于 Selfoss 实例,不适用于其他 RSS 。</string>
|
<string name="application_selfoss_only">此应用只适用于 Selfoss 实例,不适用于其他 RSS 。</string>
|
||||||
<string name="menu_home_sources">源</string>
|
<string name="menu_home_sources">源</string>
|
||||||
<string name="update_source">更新源</string>
|
<string name="update_source">更新源</string>
|
||||||
<string name="confirm_disconnect_title">断开连接?</string>
|
<string name="confirm_disconnect_title">断开连接?</string>
|
||||||
<string name="confirm_disconnect_description">您将断开与 selfoss 实例的连接。</string>
|
<string name="confirm_disconnect_description">您将断开与 selfoss 实例的连接。</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"暂无内容!"</string>
|
||||||
|
<string name="tab_new">"新建"</string>
|
||||||
|
<string name="tab_read">"所有"</string>
|
||||||
|
<string name="tab_favs">"收藏夹"</string>
|
||||||
|
<string name="action_about">"关于我们"</string>
|
||||||
|
<string name="marked_as_read">"已读"</string>
|
||||||
|
<string name="marked_as_unread">"未读条目"</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
<string name="error_invalid_password">"密码不够长"</string>
|
<string name="error_invalid_password">"密码不够长"</string>
|
||||||
<string name="error_field_required">"欄位必填"</string>
|
<string name="error_field_required">"欄位必填"</string>
|
||||||
<string name="prompt_url">"网址"</string>
|
<string name="prompt_url">"网址"</string>
|
||||||
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"需要登入?"</string>
|
<string name="withLoginSwitch">"需要登入?"</string>
|
||||||
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</string>
|
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</string>
|
||||||
<string name="prompt_login">"使用者名稱"</string>
|
<string name="prompt_login">"使用者名稱"</string>
|
||||||
@ -116,12 +117,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
<string name="disable_ssl">Disable SSL</string>
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"暂无内容!"</string>
|
||||||
|
<string name="tab_new">"新建"</string>
|
||||||
|
<string name="tab_read">"所有"</string>
|
||||||
|
<string name="tab_favs">"收藏夹"</string>
|
||||||
|
<string name="action_about">"关于我们"</string>
|
||||||
|
<string name="marked_as_read">"已读"</string>
|
||||||
|
<string name="marked_as_unread">"未讀項目"</string>
|
||||||
</resources>
|
</resources>
|
@ -119,11 +119,19 @@
|
|||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
<string name="pref_switch_disable_acra">"Disable automatic bug reporting. "</string>
|
<string name="pref_switch_disable_acra">"Disable automatic bug reporting."</string>
|
||||||
<string name="menu_home_filter">Filters</string>
|
<string name="menu_home_filter">Filters</string>
|
||||||
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
<string name="application_selfoss_only">This app only works with a Selfoss instance, and no other RSS feed.</string>
|
||||||
<string name="menu_home_sources">Sources</string>
|
<string name="menu_home_sources">Sources</string>
|
||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="no_browser">Can\'t open a link without a browser installed</string>
|
||||||
|
<string name="nothing_here">"Nothing here"</string>
|
||||||
|
<string name="tab_new">"New"</string>
|
||||||
|
<string name="tab_read">"All"</string>
|
||||||
|
<string name="tab_favs">"Favorites"</string>
|
||||||
|
<string name="action_about">"About"</string>
|
||||||
|
<string name="marked_as_read">"Item read"</string>
|
||||||
|
<string name="marked_as_unread">"Item unread"</string>
|
||||||
</resources>
|
</resources>
|
@ -1,10 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
dependencies {
|
|
||||||
// SqlDelight
|
|
||||||
classpath("com.squareup.sqldelight:gradle-plugin:1.5.5")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
//trick: for the same plugin versions in all sub-modules
|
//trick: for the same plugin versions in all sub-modules
|
||||||
id("com.android.application").version("8.7.3").apply(false)
|
id("com.android.application").version("8.7.3").apply(false)
|
||||||
|
@ -3,3 +3,4 @@ files:
|
|||||||
translation: /androidApp/src/main/res/values-%android_code%/%original_file_name%
|
translation: /androidApp/src/main/res/values-%android_code%/%original_file_name%
|
||||||
translate_attributes: '0'
|
translate_attributes: '0'
|
||||||
content_segmentation: '0'
|
content_segmentation: '0'
|
||||||
|
preserve_hierarchy: true
|
16
fastlane/metadata/android/en-US/changelogs/v124123651.txt
Normal file
16
fastlane/metadata/android/en-US/changelogs/v124123651.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
**v124123651**
|
||||||
|
|
||||||
|
- Merge pull request 'Bugfixes' (#171) from bugfixes into master
|
||||||
|
- config: crowdin
|
||||||
|
- chore: can links be empty ?
|
||||||
|
- fix: Context issues in article fragment.
|
||||||
|
- fix: Context issues in fragment sheet.
|
||||||
|
- fix: build.
|
||||||
|
- chore: compile issue fix.
|
||||||
|
- chore: filter some bugs.
|
||||||
|
- bugfix: catch users using something other than selfoss.
|
||||||
|
- bugfix: No browser, no link.
|
||||||
|
- translations
|
||||||
|
- chore: remove log.
|
||||||
|
- translation
|
||||||
|
- Changelog for v124123641
|
Binary file not shown.
Before Width: | Height: | Size: 294 KiB After Width: | Height: | Size: 24 KiB |
@ -1,18 +1,18 @@
|
|||||||
val ktorVersion = "2.3.2"
|
val ktorVersion = "3.0.3"
|
||||||
|
|
||||||
object SqlDelight {
|
object SqlDelight {
|
||||||
const val runtime = "com.squareup.sqldelight:runtime:1.5.4"
|
const val runtime = "app.cash.sqldelight:runtime:2.0.2"
|
||||||
const val android = "com.squareup.sqldelight:android-driver:1.5.4"
|
const val android = "app.cash.sqldelight:android-driver:2.0.2"
|
||||||
const val native = "com.squareup.sqldelight:native-driver:1.5.4"
|
const val native = "app.cash.sqldelight:native-driver:2.0.2"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
id("com.android.library")
|
id("com.android.library")
|
||||||
id("com.squareup.sqldelight")
|
|
||||||
kotlin("plugin.serialization") version "1.9.0"
|
kotlin("plugin.serialization") version "1.9.0"
|
||||||
id("org.jetbrains.kotlinx.kover")
|
id("org.jetbrains.kotlinx.kover")
|
||||||
|
id("app.cash.sqldelight") version "2.0.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
@ -37,7 +37,7 @@ kotlin {
|
|||||||
implementation("io.ktor:ktor-client-logging:$ktorVersion")
|
implementation("io.ktor:ktor-client-logging:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-auth:$ktorVersion")
|
implementation("io.ktor:ktor-client-auth:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
|
||||||
|
|
||||||
implementation("org.jsoup:jsoup:1.15.4")
|
implementation("org.jsoup:jsoup:1.15.4")
|
||||||
|
|
||||||
@ -66,7 +66,6 @@ kotlin {
|
|||||||
val androidMain by getting {
|
val androidMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.11.0")
|
implementation("com.squareup.okhttp3:okhttp:4.11.0")
|
||||||
implementation("io.ktor:ktor-client-okhttp:2.2.4")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
||||||
|
|
||||||
// Sql
|
// Sql
|
||||||
@ -86,7 +85,6 @@ kotlin {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(SqlDelight.native)
|
implementation(SqlDelight.native)
|
||||||
implementation("io.ktor:ktor-client-ios:2.1.1")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val iosX64Test by getting
|
val iosX64Test by getting
|
||||||
@ -110,11 +108,10 @@ android {
|
|||||||
namespace = "bou.amine.apps.readerforselfossv2"
|
namespace = "bou.amine.apps.readerforselfossv2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sqldelight {
|
sqldelight {
|
||||||
database("ReaderForSelfossDB") {
|
databases {
|
||||||
packageName = "bou.amine.apps.readerforselfossv2.dao"
|
create("ReaderForSelfossDB") {
|
||||||
sourceFolders = listOf("sqldelight")
|
packageName.set("bou.amine.apps.readerforselfossv2.dao")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,15 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.dao
|
package bou.amine.apps.readerforselfossv2.dao
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.squareup.sqldelight.android.AndroidSqliteDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import com.squareup.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
|
||||||
|
|
||||||
actual class DriverFactory(private val context: Context) {
|
actual class DriverFactory(private val context: Context) {
|
||||||
actual fun createDriver(): SqlDriver {
|
actual fun createDriver(): SqlDriver {
|
||||||
return AndroidSqliteDriver(ReaderForSelfossDB.Schema, context, "ReaderForSelfossV2-android.db")
|
return AndroidSqliteDriver(
|
||||||
|
ReaderForSelfossDB.Schema,
|
||||||
|
context,
|
||||||
|
"ReaderForSelfossV2-android.db"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.dao
|
package bou.amine.apps.readerforselfossv2.dao
|
||||||
|
|
||||||
import com.squareup.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
|
|
||||||
expect class DriverFactory {
|
expect class DriverFactory {
|
||||||
fun createDriver(): SqlDriver
|
fun createDriver(): SqlDriver
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.model
|
|||||||
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||||
@ -10,7 +11,12 @@ import kotlinx.serialization.descriptors.SerialDescriptor
|
|||||||
import kotlinx.serialization.encoding.Decoder
|
import kotlinx.serialization.encoding.Decoder
|
||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
import kotlinx.serialization.encoding.encodeCollection
|
import kotlinx.serialization.encoding.encodeCollection
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonDecoder
|
||||||
|
import kotlinx.serialization.json.boolean
|
||||||
|
import kotlinx.serialization.json.booleanOrNull
|
||||||
|
import kotlinx.serialization.json.int
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
|
||||||
class SelfossModel {
|
class SelfossModel {
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -134,6 +140,10 @@ class SelfossModel {
|
|||||||
stringUrl = "http:$stringUrl"
|
stringUrl = "http:$stringUrl"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stringUrl.isEmptyOrNullOrNullString()) {
|
||||||
|
throw Exception("Link ${link} was translated to ${stringUrl}, but was empty. Handle this.")
|
||||||
|
}
|
||||||
|
|
||||||
return stringUrl
|
return stringUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +186,10 @@ class SelfossModel {
|
|||||||
encoder: Encoder,
|
encoder: Encoder,
|
||||||
value: List<String>,
|
value: List<String>,
|
||||||
) {
|
) {
|
||||||
encoder.encodeCollection(PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING), value.size) { this.toString() }
|
encoder.encodeCollection(
|
||||||
|
PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING),
|
||||||
|
value.size
|
||||||
|
) { this.toString() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +204,10 @@ class SelfossModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val descriptor: SerialDescriptor
|
override val descriptor: SerialDescriptor
|
||||||
get() = PrimitiveSerialDescriptor("BooleanOrIntForSomeSelfossVersions", PrimitiveKind.BOOLEAN)
|
get() = PrimitiveSerialDescriptor(
|
||||||
|
"BooleanOrIntForSomeSelfossVersions",
|
||||||
|
PrimitiveKind.BOOLEAN
|
||||||
|
)
|
||||||
|
|
||||||
override fun serialize(
|
override fun serialize(
|
||||||
encoder: Encoder,
|
encoder: Encoder,
|
||||||
@ -200,4 +216,4 @@ class SelfossModel {
|
|||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +1,26 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.rest
|
package bou.amine.apps.readerforselfossv2.rest
|
||||||
|
|
||||||
import bou.amine.apps.readerforselfossv2.model.*
|
import bou.amine.apps.readerforselfossv2.model.MercuryModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.model.StatusAndData
|
||||||
import io.github.aakira.napier.Napier
|
import io.github.aakira.napier.Napier
|
||||||
import io.ktor.client.*
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.plugins.cache.*
|
import io.ktor.client.plugins.cache.HttpCache
|
||||||
import io.ktor.client.plugins.contentnegotiation.*
|
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||||
import io.ktor.client.plugins.logging.*
|
import io.ktor.client.plugins.logging.LogLevel
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.plugins.logging.Logger
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.request.parameter
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class MercuryApi() {
|
class MercuryApi {
|
||||||
var client = createHttpClient()
|
var client = createHttpClient()
|
||||||
|
|
||||||
private fun createHttpClient(): HttpClient {
|
private fun createHttpClient(): HttpClient {
|
||||||
return HttpClient {
|
return HttpClient {
|
||||||
|
install(HttpCache)
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
install(HttpCache)
|
|
||||||
json(
|
json(
|
||||||
Json {
|
Json {
|
||||||
prettyPrint = true
|
prettyPrint = true
|
||||||
@ -44,4 +48,4 @@ class MercuryApi() {
|
|||||||
parameter("link", url)
|
parameter("link", url)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -30,10 +30,14 @@ suspend fun maybeResponse(r: HttpResponse?): SuccessResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend inline fun <reified T> bodyOrFailure(r: HttpResponse?): StatusAndData<T> {
|
suspend inline fun <reified T> bodyOrFailure(r: HttpResponse?): StatusAndData<T> {
|
||||||
return if (r != null && r.status.isSuccess()) {
|
try {
|
||||||
StatusAndData.succes(r.body())
|
return if (r != null && r.status.isSuccess()) {
|
||||||
} else {
|
StatusAndData.succes(r.body())
|
||||||
StatusAndData.error()
|
} else {
|
||||||
|
StatusAndData.error()
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
return StatusAndData.error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,4 +98,4 @@ suspend fun HttpClient.tryToSubmitForm(
|
|||||||
url(url)
|
url(url)
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,8 +45,8 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
setupInsecureHTTPEngine(this)
|
setupInsecureHTTPEngine(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
install(HttpCache)
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
install(HttpCache)
|
|
||||||
json(
|
json(
|
||||||
Json {
|
Json {
|
||||||
prettyPrint = true
|
prettyPrint = true
|
||||||
@ -105,8 +105,8 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
|
|
||||||
private fun hasLoginInfo() =
|
private fun hasLoginInfo() =
|
||||||
appSettingsService.getUserName().isNotEmpty() &&
|
appSettingsService.getUserName().isNotEmpty() &&
|
||||||
appSettingsService.getPassword()
|
appSettingsService.getPassword()
|
||||||
.isNotEmpty()
|
.isNotEmpty()
|
||||||
|
|
||||||
suspend fun login(): SuccessResponse =
|
suspend fun login(): SuccessResponse =
|
||||||
if (appSettingsService.getUserName().isNotEmpty() &&
|
if (appSettingsService.getUserName().isNotEmpty() &&
|
||||||
@ -127,7 +127,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
client.tryToGet(url("/login")) {
|
client.tryToGet(url("/login")) {
|
||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -148,7 +150,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
client.tryToPost(url("/login")) {
|
client.tryToPost(url("/login")) {
|
||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -164,7 +168,8 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun shouldHaveNewLogout() = appSettingsService.getApiVersion() >= 5 // We are missing 4.1.0
|
private fun shouldHaveNewLogout() =
|
||||||
|
appSettingsService.getApiVersion() >= 5 // We are missing 4.1.0
|
||||||
|
|
||||||
suspend fun logout(): SuccessResponse =
|
suspend fun logout(): SuccessResponse =
|
||||||
if (shouldHaveNewLogout()) {
|
if (shouldHaveNewLogout()) {
|
||||||
@ -176,7 +181,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
private suspend fun maybeLogoutIfAvailable() =
|
private suspend fun maybeLogoutIfAvailable() =
|
||||||
responseOrSuccessIf404(
|
responseOrSuccessIf404(
|
||||||
client.tryToGet(url("/logout")) {
|
client.tryToGet(url("/logout")) {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -195,7 +202,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
private suspend fun doLogout() =
|
private suspend fun doLogout() =
|
||||||
maybeResponse(
|
maybeResponse(
|
||||||
client.tryToDelete(url("/api/session/current")) {
|
client.tryToDelete(url("/api/session/current")) {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -233,7 +242,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("updatedsince", updatedSince)
|
parameter("updatedsince", updatedSince)
|
||||||
parameter("items", items ?: appSettingsService.getItemsNumber())
|
parameter("items", items ?: appSettingsService.getItemsNumber())
|
||||||
parameter("offset", offset)
|
parameter("offset", offset)
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -258,7 +269,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
}
|
}
|
||||||
parameter("type", "all")
|
parameter("type", "all")
|
||||||
parameter("items", 1)
|
parameter("items", 1)
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -281,7 +294,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -304,7 +319,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -327,7 +344,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -350,7 +369,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -373,7 +394,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -396,7 +419,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -415,7 +440,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
suspend fun apiInformation(): StatusAndData<SelfossModel.ApiInformation> =
|
suspend fun apiInformation(): StatusAndData<SelfossModel.ApiInformation> =
|
||||||
bodyOrFailure(
|
bodyOrFailure(
|
||||||
client.tryToGet(url("/api/about")) {
|
client.tryToGet(url("/api/about")) {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -438,7 +465,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -461,7 +490,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -484,7 +515,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -507,7 +540,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -528,15 +563,17 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
client.tryToSubmitForm(
|
client.tryToSubmitForm(
|
||||||
url = url("/mark"),
|
url = url("/mark"),
|
||||||
formParameters =
|
formParameters =
|
||||||
Parameters.build {
|
Parameters.build {
|
||||||
if (!shouldHavePostLogin()) {
|
if (!shouldHavePostLogin()) {
|
||||||
append("username", appSettingsService.getUserName())
|
append("username", appSettingsService.getUserName())
|
||||||
append("password", appSettingsService.getPassword())
|
append("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
ids.map { append("ids[]", it) }
|
ids.map { append("ids[]", it) }
|
||||||
},
|
},
|
||||||
block = {
|
block = {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -577,18 +614,20 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
client.tryToSubmitForm(
|
client.tryToSubmitForm(
|
||||||
url = url("/source"),
|
url = url("/source"),
|
||||||
formParameters =
|
formParameters =
|
||||||
Parameters.build {
|
Parameters.build {
|
||||||
if (!shouldHavePostLogin()) {
|
if (!shouldHavePostLogin()) {
|
||||||
append("username", appSettingsService.getUserName())
|
append("username", appSettingsService.getUserName())
|
||||||
append("password", appSettingsService.getPassword())
|
append("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
append("title", title)
|
append("title", title)
|
||||||
append("url", url)
|
append("url", url)
|
||||||
append("spout", spout)
|
append("spout", spout)
|
||||||
append(tagsParamName, tags)
|
append(tagsParamName, tags)
|
||||||
},
|
},
|
||||||
block = {
|
block = {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -630,18 +669,20 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
client.tryToSubmitForm(
|
client.tryToSubmitForm(
|
||||||
url = url("/source/$id"),
|
url = url("/source/$id"),
|
||||||
formParameters =
|
formParameters =
|
||||||
Parameters.build {
|
Parameters.build {
|
||||||
if (!shouldHavePostLogin()) {
|
if (!shouldHavePostLogin()) {
|
||||||
append("username", appSettingsService.getUserName())
|
append("username", appSettingsService.getUserName())
|
||||||
append("password", appSettingsService.getPassword())
|
append("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
append("title", title)
|
append("title", title)
|
||||||
append("url", url)
|
append("url", url)
|
||||||
append("spout", spout)
|
append("spout", spout)
|
||||||
append(tagsParamName, tags)
|
append(tagsParamName, tags)
|
||||||
},
|
},
|
||||||
block = {
|
block = {
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -664,7 +705,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
parameter("username", appSettingsService.getUserName())
|
parameter("username", appSettingsService.getUserName())
|
||||||
parameter("password", appSettingsService.getPassword())
|
parameter("password", appSettingsService.getPassword())
|
||||||
}
|
}
|
||||||
if (appSettingsService.getBasicUserName().isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()) {
|
if (appSettingsService.getBasicUserName()
|
||||||
|
.isNotEmpty() && appSettingsService.getBasicPassword().isNotEmpty()
|
||||||
|
) {
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
HttpHeaders.Authorization,
|
HttpHeaders.Authorization,
|
||||||
@ -679,4 +722,4 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import kotlin.Boolean;
|
||||||
|
|
||||||
CREATE TABLE `ACTION` (
|
CREATE TABLE `ACTION` (
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
`articleid` TEXT NOT NULL,
|
`articleid` TEXT NOT NULL,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import kotlin.Boolean;
|
||||||
|
|
||||||
CREATE TABLE ITEM (
|
CREATE TABLE ITEM (
|
||||||
`id` TEXT NOT NULL,
|
`id` TEXT NOT NULL,
|
||||||
`datetime` TEXT NOT NULL,
|
`datetime` TEXT NOT NULL,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.dao
|
package bou.amine.apps.readerforselfossv2.dao
|
||||||
|
|
||||||
import com.squareup.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import com.squareup.sqldelight.drivers.native.NativeSqliteDriver
|
import app.cash.sqldelight.driver.native.NativeSqliteDriver
|
||||||
|
|
||||||
actual class DriverFactory {
|
actual class DriverFactory {
|
||||||
actual fun createDriver(): SqlDriver {
|
actual fun createDriver(): SqlDriver {
|
||||||
return NativeSqliteDriver(ReaderForSelfossDB.Schema, "ReaderForSelfossV2-IOS.db")
|
return NativeSqliteDriver(ReaderForSelfossDB.Schema, "ReaderForSelfossV2-IOS.db")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,12 +2,8 @@ package bou.amine.apps.readerforselfossv2.utils
|
|||||||
|
|
||||||
actual class DateUtils {
|
actual class DateUtils {
|
||||||
actual companion object {
|
actual companion object {
|
||||||
actual fun parseDate(dateString: String): Long {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun parseRelativeDate(dateString: String): String {
|
actual fun parseRelativeDate(dateString: String): String {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.dao
|
package bou.amine.apps.readerforselfossv2.dao
|
||||||
|
|
||||||
import com.squareup.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import com.squareup.sqldelight.drivers.native.NativeSqliteDriver
|
import app.cash.sqldelight.driver.native.NativeSqliteDriver
|
||||||
|
|
||||||
actual class DriverFactory {
|
actual class DriverFactory {
|
||||||
actual fun createDriver(): SqlDriver {
|
actual fun createDriver(): SqlDriver {
|
||||||
return NativeSqliteDriver(ReaderForSelfossDB.Schema, "ReaderForSelfossV2-IOS.db")
|
return NativeSqliteDriver(ReaderForSelfossDB.Schema, "ReaderForSelfossV2-IOS.db")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,12 +2,8 @@ package bou.amine.apps.readerforselfossv2.utils
|
|||||||
|
|
||||||
actual class DateUtils {
|
actual class DateUtils {
|
||||||
actual companion object {
|
actual companion object {
|
||||||
actual fun parseDate(dateString: String): Long {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun parseRelativeDate(dateString: String): String {
|
actual fun parseRelativeDate(dateString: String): String {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user