Compare commits

..

13 Commits

Author SHA1 Message Date
934c112db5 Merge pull request 'Bugfixes' (#171) from bugfixes into master
All checks were successful
Check master code / build (push) Successful in 19m51s
Create tag / build (push) Successful in 21m4s
Create tag / createTagAndChangelog (push) Successful in 50s
Create tag / release (push) Successful in 3m39s
Reviewed-on: #171
2024-12-30 22:32:11 +00:00
ad7549a89f config: crowdin
All checks were successful
Check PR code / Lint (pull_request) Successful in 54s
Check PR code / build (pull_request) Successful in 10m35s
2024-12-30 23:20:03 +01:00
fb9ceecabd chore: can links be empty ?
All checks were successful
Check PR code / Lint (pull_request) Successful in 1m3s
Check PR code / build (pull_request) Successful in 11m14s
2024-12-30 22:45:18 +01:00
61b9fd30e0 fix: Context issues in article fragment. 2024-12-30 22:37:36 +01:00
806e56e20b fix: Context issues in fragment sheet.
All checks were successful
Check PR code / Lint (pull_request) Successful in 1m7s
Check PR code / build (pull_request) Successful in 12m15s
2024-12-30 22:12:38 +01:00
cd8b7aaf9d fix: build. 2024-12-30 22:12:21 +01:00
c25ad7621e chore: compile issue fix.
All checks were successful
Check PR code / Lint (pull_request) Successful in 1m10s
Check PR code / build (pull_request) Successful in 9m57s
2024-12-30 15:07:35 +01:00
63da3b9fe7 chore: filter some bugs. 2024-12-30 15:07:18 +01:00
1d99eeb633 bugfix: catch users using something other than selfoss. 2024-12-30 13:51:45 +01:00
162a350a8f bugfix: No browser, no link. 2024-12-30 13:51:14 +01:00
27c1bba146 translations
All checks were successful
Check PR code / Lint (pull_request) Successful in 54s
Check PR code / build (pull_request) Successful in 9m26s
2024-12-30 13:49:42 +01:00
b7f3a9877a chore: remove log. 2024-12-30 12:58:34 +01:00
47f78754dc translation
Some checks failed
Check PR code / Lint (pull_request) Successful in 46s
Check PR code / build (pull_request) Failing after 3m20s
2024-12-30 12:48:42 +01:00
37 changed files with 379 additions and 191 deletions

View File

@ -3,7 +3,7 @@ on:
workflow_call:
jobs:
BuildAndTest:
BuildAndTestAndCoverage:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
@ -16,9 +16,30 @@ jobs:
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
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: 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

View File

@ -85,6 +85,7 @@ jobs:
with:
distribution: 'temurin'
java-version: '17'
cache: gradle
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Configure gradle...

View File

@ -12,8 +12,9 @@ jobs:
uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin' # See 'Supported distributions' for available options
distribution: 'temurin'
java-version: '17'
cache: gradle
- 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/
- name: Install detekt

View File

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

View File

@ -203,7 +203,7 @@ dependencies {
implementation("ch.acra:acra-http:$acraVersion")
implementation("ch.acra:acra-toast:$acraVersion")
implementation("com.google.auto.service:auto-service:1.1.1")
}
tasks.withType<Test> {

View File

@ -62,7 +62,7 @@ class LoginActivityTest {
@Test
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)).check(matches(withError(R.string.wrong_infos)))
}

View File

@ -1,7 +1,6 @@
package bou.amine.apps.readerforselfossv2.android
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.Menu
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.utils.bottombar.maybeShow
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.repository.Repository
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
@ -589,9 +589,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.issue_tracker -> {
val browserIntent =
Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl))
startActivity(browserIntent)
baseContext.openUrlInBrowser(AppSettingsService.trackerUrl)
return true
}

View File

@ -8,11 +8,11 @@ import android.widget.ImageView.ScaleType
import androidx.recyclerview.widget.RecyclerView
import bou.amine.apps.readerforselfossv2.android.R
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.acra.sendSilentlyWithAcraWithName
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.openInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.repository.Repository
@ -71,7 +71,7 @@ class ItemCardAdapter(
}
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)
}
}

View File

@ -6,8 +6,8 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import bou.amine.apps.readerforselfossv2.android.R
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.acra.sendSilentlyWithAcraWithName
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.repository.Repository
@ -73,4 +73,4 @@ class ItemListAdapter(
}
inner class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root)
}
}

View File

@ -1,16 +1,20 @@
package bou.amine.apps.readerforselfossv2.android.fragments
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.TypedArray
import android.graphics.Bitmap
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
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.WebSettings
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.toModel
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.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.model.MercuryModel
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.Dispatchers
import kotlinx.coroutines.launch
import org.acra.ktx.sendSilentlyWithAcra
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import java.net.MalformedURLException
import java.net.URL
import java.util.*
import java.util.Locale
import java.util.concurrent.ExecutionException
private const val IMAGE_JPG = "image/jpg"
@ -98,7 +104,12 @@ class ArticleFragment : Fragment(), DIAware {
try {
binding = FragmentArticleBinding.inflate(inflater, container, false)
url = item.getLinkDecoded()
try {
url = item.getLinkDecoded()
} catch (e: Exception) {
e.sendSilentlyWithAcra()
}
contentText = item.content
contentTitle = item.title.getHtmlDecoded()
contentImage = item.getThumbnail(repository.baseUrl)
@ -152,7 +163,7 @@ class ArticleFragment : Fragment(), DIAware {
)
} catch (e: InflateException) {
e.sendSilentlyWithAcraWithName("webview not available")
if (context != null) {
try {
AlertDialog.Builder(requireContext())
.setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
.setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
@ -164,6 +175,8 @@ class ArticleFragment : Fragment(), DIAware {
}
.create()
.show()
} catch (e: IllegalStateException) {
e.sendSilentlyWithAcraWithName("Context required is null")
}
}
@ -211,16 +224,16 @@ class ArticleFragment : Fragment(), DIAware {
override fun onItemClick(item: MenuItem) {
when (item.itemId) {
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 ->
if (context != null) {
try {
if (this@ArticleFragment.item.unread) {
CoroutineScope(Dispatchers.IO).launch {
repository.markAsRead(this@ArticleFragment.item)
}
this@ArticleFragment.item.unread = false
Toast.makeText(
context,
requireContext(),
R.string.marked_as_read,
Toast.LENGTH_LONG,
).show()
@ -235,7 +248,10 @@ class ArticleFragment : Fragment(), DIAware {
Toast.LENGTH_LONG,
).show()
}
} catch (e: IllegalStateException) {
e.sendSilentlyWithAcraWithName("Context required is null")
}
else -> Unit
}
}
@ -288,7 +304,7 @@ class ArticleFragment : Fragment(), DIAware {
contentText = data.content.orEmpty()
htmlToWebview()
handleLeadImage(data?.lead_image_url)
handleLeadImage(data.lead_image_url)
binding.nestedScrollView.scrollTo(0, 0)
binding.progressBar.visibility = View.GONE
@ -320,11 +336,7 @@ class ArticleFragment : Fragment(), DIAware {
url: String,
): Boolean {
return if (context != null && url.isUrlValid() && binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
try {
requireContext().startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
} catch (e: ActivityNotFoundException) {
e.sendSilentlyWithAcraWithName("activityNotFound > $url")
}
requireContext().openUrlInBrowser(url)
true
} else {
false
@ -343,7 +355,8 @@ class ArticleFragment : Fragment(), DIAware {
) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -355,7 +368,8 @@ class ArticleFragment : Fragment(), DIAware {
} else if (url.lowercase(Locale.US).contains(".png")) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -367,7 +381,8 @@ class ArticleFragment : Fragment(), DIAware {
} else if (url.lowercase(Locale.US).contains(".webp")) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -384,7 +399,7 @@ class ArticleFragment : Fragment(), DIAware {
}
private fun htmlToWebview() {
if (context != null) {
try {
val attrs: IntArray = intArrayOf(android.R.attr.fontFamily)
val a: TypedArray = requireContext().obtainStyledAttributes(resId, attrs)
@ -529,6 +544,8 @@ class ArticleFragment : Fragment(), DIAware {
"utf-8",
null,
)
} catch (e: IllegalStateException) {
e.sendSilentlyWithAcraWithName("Context required is null")
}
}
@ -544,10 +561,10 @@ class ArticleFragment : Fragment(), DIAware {
private fun openInBrowserAfterFailing() {
binding.progressBar.visibility = View.GONE
if (context != null) {
requireContext().openInBrowserAsNewTask(this@ArticleFragment.item)
} else {
Exception("openInBrowserAfterFailing context is null").sendSilentlyWithAcraWithName("openInBrowserAfterFailing > $context")
try {
requireContext().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
} catch (e: IllegalStateException) {
e.sendSilentlyWithAcraWithName("Context required is null")
}
}
@ -565,9 +582,9 @@ class ArticleFragment : Fragment(), DIAware {
fun performClick(): Boolean {
if (allImages != null && (
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
)
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
)
) {
val position: Int = allImages.indexOf(binding.webcontent.hitTestResult.extra)
@ -579,4 +596,4 @@ class ArticleFragment : Fragment(), DIAware {
}
return false
}
}
}

View File

@ -15,7 +15,7 @@ import android.view.ViewGroup
import bou.amine.apps.readerforselfossv2.android.HomeActivity
import bou.amine.apps.readerforselfossv2.android.R
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.utils.getColorHexCode
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
@ -52,19 +52,17 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
false,
)
val context: Context? = context
if (context == null) {
dismiss()
Exception("FilterSheetFragment context is null").sendSilentlyWithAcraWithName("FilterSheetFragment > onCreateView")
} else {
try {
CoroutineScope(Dispatchers.Main).launch {
handleTagChips(context)
handleSourceChips(context)
handleTagChips(requireContext())
handleSourceChips(requireContext())
binding.progressBar2.visibility = GONE
binding.filterView.visibility = VISIBLE
}
} catch (e: IllegalStateException) {
dismiss()
e.sendSilentlyWithAcraWithName("FilterSheetFragment > onCreateView")
}
binding.floatingActionButton2.setOnClickListener {
@ -192,4 +190,4 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
companion object {
const val TAG = "FilterModalBottomSheet"
}
}
}

View File

@ -2,7 +2,7 @@ package bou.amine.apps.readerforselfossv2.android.model
import android.content.Context
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.utils.getImages
import com.bumptech.glide.Glide
@ -40,4 +40,4 @@ fun String.toTextDrawableString(): String {
}
}
return textDrawable.toString()
}
}

View File

@ -1,7 +1,5 @@
package bou.amine.apps.readerforselfossv2.android.settings
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.InputFilter
@ -16,7 +14,8 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import bou.amine.apps.readerforselfossv2.android.R
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 com.mikepenz.aboutlibraries.LibsBuilder
import org.kodein.di.DIAware
@ -105,7 +104,9 @@ class SettingsActivity :
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
AppCompatDelegate.setDefaultNightMode(newValue.toString().toInt()) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
AppCompatDelegate.setDefaultNightMode(
newValue.toString().toInt()
) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
true
}
@ -129,7 +130,8 @@ class SettingsActivity :
) {
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 ->
editText.inputType = InputType.TYPE_CLASS_NUMBER
editText.filters =
@ -139,8 +141,11 @@ class SettingsActivity :
val input: Int = (dest.toString() + source.toString()).toInt()
if (input in 1..200) return@InputFilter null
} catch (nfe: NumberFormatException) {
nfe.sendSilentlyWithAcraWithName("GeneralPreferenceFragment")
Toast.makeText(activity, R.string.items_number_should_be_number, Toast.LENGTH_LONG).show()
Toast.makeText(
activity,
R.string.items_number_should_be_number,
Toast.LENGTH_LONG
).show()
}
""
},
@ -222,16 +227,17 @@ class SettingsActivity :
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
AppCompatDelegate.setDefaultNightMode(newValue.toString().toInt()) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
AppCompatDelegate.setDefaultNightMode(
newValue.toString().toInt()
) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
true
}
}
}
class LinksPreferenceFragment : PreferenceFragmentCompat() {
private fun openUrl(uri: Uri?) {
val browserIntent = Intent(Intent.ACTION_VIEW, uri)
startActivity(browserIntent)
private fun openUrl(url: String) {
context?.openUrlInBrowser(url)
}
override fun onCreatePreferences(
@ -242,19 +248,19 @@ class SettingsActivity :
preferenceManager.findPreference<Preference>("trackerLink")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.trackerUrl))
openUrl(AppSettingsService.trackerUrl)
true
}
preferenceManager.findPreference<Preference>("sourceLink")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.sourceUrl))
openUrl(AppSettingsService.sourceUrl)
false
}
preferenceManager.findPreference<Preference>("translation")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.translationUrl))
openUrl(AppSettingsService.translationUrl)
false
}
}
@ -268,4 +274,4 @@ class SettingsActivity :
setPreferencesFromResource(R.xml.pref_experimental, rootKey)
}
}
}
}

View File

@ -1,6 +1,7 @@
package bou.amine.apps.readerforselfossv2.android.utils
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -17,6 +18,7 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
fun Context.openItemUrl(
currentItem: Int,
linkDecoded: String,
@ -35,15 +37,13 @@ fun Context.openItemUrl(
intent.putExtra("currentItem", currentItem)
app.startActivity(intent)
} else {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(linkDecoded.toStringUriWithHttp())
startActivity(intent)
this.openUrlInBrowserAsNewTask(linkDecoded)
}
}
}
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 {
val baseUrl = this.toHttpUrlOrNull()
@ -56,11 +56,31 @@ fun String.isBaseUrlInvalid(): Boolean {
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)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(i.getLinkDecoded().toStringUriWithHttp())
startActivity(intent)
intent.data = Uri.parse(url)
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 {
@ -102,4 +122,4 @@ class LinkOnTouchListener : View.OnTouchListener {
}
return ret
}
}
}

View File

@ -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.ktx.sendSilentlyWithAcra
@ -6,4 +6,4 @@ import org.acra.ktx.sendSilentlyWithAcra
fun Throwable.sendSilentlyWithAcraWithName(name: String) {
ACRA.errorReporter.putCustomData("error_source", name)
this.sendSilentlyWithAcra()
}
}

View File

@ -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
}
override fun shouldSendReport(
context: Context,
config: CoreConfiguration,
crashReportData: CrashReportData
): Boolean {
return crashReportData.get("BRAND") != "redroid"
}
}

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"La contrasenya és massa curta"</string>
<string name="error_field_required">"Camp necessari"</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="login_url_problem">"Pot ser que falti una \"/\" al final de l'url."</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_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="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="pref_switch_periodic_refresh">Sincronitza els articles</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Passwort ist nicht lang genug"</string>
<string name="error_field_required">"Pflichtfeld"</string>
<string name="prompt_url">"URL"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Quelle aktualisieren</string>
<string name="confirm_disconnect_title">Verbindung trennen?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"La contraseña no es suficientemente larga"</string>
<string name="error_field_required">"Campo requerido"</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="login_url_problem">"Oops. Puede que necesite añadir un \"/\" al final de la url."</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_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="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="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>
@ -116,12 +117,19 @@
<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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Mot de passe trop court"</string>
<string name="error_field_required">"Champ requis"</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="login_url_problem">"Petit souci. Il manque peut-être un / à la fin ?"</string>
<string name="prompt_login">"Utilisateur"</string>
@ -24,7 +25,7 @@
<string name="all_posts_read">"Tous les posts sont lus"</string>
<string name="undo_string">"Annuler"</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_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>
@ -35,13 +36,13 @@
<string name="warning_wrong_url">"ATTENTION"</string>
<string name="pref_switch_card_view_title">"Vue en carte"</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="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="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_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_displaying">"Affichage"</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="menu_home_search">Rechercher</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_selfoss_category">Api Selfoss</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="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="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="unmark">Marquer l\'article comme non lu</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_retrieved">"Connexion réseau de nouveau disponible"</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_on">Articles seront périodiquement synchronisées</string>
<string name="pref_periodic_refresh_minutes_title"><![CDATA[Interval de synchronisation ( >= 15 minutes)]]></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és</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="loading_notification_title">Chargement …</string>
<string name="loading_notification_text">Selfoss synchronise vos articles</string>
@ -100,7 +101,7 @@
<string name="shortcut_offline">Hors ligne</string>
<string name="pref_api_timeout">Timeout de l\'api</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="reader_text_align_left">Aligner à gauche</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_system">Utiliser les paramètres système</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_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_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="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="menu_home_filter">Filtres</string>
@ -123,5 +124,12 @@
<string name="update_source">Mise à jour des sources</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="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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"O contrasinal non é suficientemente longo"</string>
<string name="error_field_required">"Campo requirido"</string>
<string name="prompt_url">"URL"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Kata sandinya tidak cukup panjang"</string>
<string name="error_field_required">"Kolom wajib diisi"</string>
<string name="prompt_url">"URL"</string>
<string name="disable_ssl">"Disable SSL"</string>
<string name="withLoginSwitch">"Harus masuk?"</string>
<string name="login_url_problem">"Ups. Anda mungkin harus menambahkan \"/\" di akhir url."</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"La password non è sufficientemente lunga"</string>
<string name="error_field_required">"Campo obbligatorio"</string>
<string name="prompt_url">"URL"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"패스워드가 짧습니다."</string>
<string name="error_field_required">"필수 항목"</string>
<string name="prompt_url">"Url"</string>
<string name="disable_ssl">"Disable SSL"</string>
<string name="withLoginSwitch">"로그인이 필요합니까?"</string>
<string name="login_url_problem">"죄송합니다. Url의 끝에 \"/\"를 추가할 필요가 있습니다."</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Wachtwoord niet lang genoeg"</string>
<string name="error_field_required">"Dit veld is verplicht"</string>
<string name="prompt_url">"Selfoss server"</string>
<string name="disable_ssl">"Disable SSL"</string>
<string name="withLoginSwitch">"Authenticatie vereist?"</string>
<string name="login_url_problem">"Oeps, ben je soms de \"/\" vergeten aan het eind?"</string>
<string name="prompt_login">"Gebruikersnaam"</string>
@ -22,7 +23,6 @@
<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_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="cant_get_sources">"Kan de lijst met bronnen niet ophalen"</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Senha muito pequena"</string>
<string name="error_field_required">"Campo obrigatório"</string>
<string name="prompt_url">"Url"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Senha não é longa o suficiente"</string>
<string name="error_field_required">"Campo obrigatório"</string>
<string name="prompt_url">"Url"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="disable_ssl">"Disable SSL"</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="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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"Parola yeterince uzun değil"</string>
<string name="error_field_required">"Alan gereklidir"</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="login_url_problem">"Oops. Url'nin sonuna \"/\" eklemek gerekebilir."</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"密码不够长"</string>
<string name="error_field_required">"必填字段"</string>
<string name="prompt_url">"网址"</string>
<string name="disable_ssl">"Disable SSL"</string>
<string name="withLoginSwitch">"需要登录?"</string>
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</string>
<string name="prompt_login">"用户名"</string>
@ -116,12 +117,19 @@
<string name="gdpr_dialog_title">该应用不分享任何关于您的个人数据。</string>
<string name="gdpr_dialog_message"><![CDATA[崩溃报告发送现已启用。 可以从设置页面禁用它。 请记住,崩溃报告对于应用程序开发是必需的。]]></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="application_selfoss_only">此应用只适用于 Selfoss 实例,不适用于其他 RSS 。</string>
<string name="menu_home_sources"></string>
<string name="update_source">更新源</string>
<string name="confirm_disconnect_title">断开连接?</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>

View File

@ -7,6 +7,7 @@
<string name="error_invalid_password">"密码不够长"</string>
<string name="error_field_required">"欄位必填"</string>
<string name="prompt_url">"网址"</string>
<string name="disable_ssl">"Disable SSL"</string>
<string name="withLoginSwitch">"需要登入?"</string>
<string name="login_url_problem">"哎呀。您可能需要在网址的末尾添加一个 \"/\"。"</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_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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -119,11 +119,19 @@
<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="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="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="update_source">Update source</string>
<string name="confirm_disconnect_title">Disconnect ?</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>

View File

@ -3,3 +3,4 @@ files:
translation: /androidApp/src/main/res/values-%android_code%/%original_file_name%
translate_attributes: '0'
content_segmentation: '0'
preserve_hierarchy: true

View File

@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.model
import bou.amine.apps.readerforselfossv2.utils.DateUtils
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
@ -10,7 +11,12 @@ import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
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 {
@Serializable
@ -134,6 +140,10 @@ class SelfossModel {
stringUrl = "http:$stringUrl"
}
if (stringUrl.isEmptyOrNullOrNullString()) {
throw Exception("Link ${link} was translated to ${stringUrl}, but was empty. Handle this.")
}
return stringUrl
}
@ -176,7 +186,10 @@ class SelfossModel {
encoder: Encoder,
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
get() = PrimitiveSerialDescriptor("BooleanOrIntForSomeSelfossVersions", PrimitiveKind.BOOLEAN)
get() = PrimitiveSerialDescriptor(
"BooleanOrIntForSomeSelfossVersions",
PrimitiveKind.BOOLEAN
)
override fun serialize(
encoder: Encoder,
@ -200,4 +216,4 @@ class SelfossModel {
TODO("Not yet implemented")
}
}
}
}

View File

@ -30,10 +30,14 @@ suspend fun maybeResponse(r: HttpResponse?): SuccessResponse {
}
suspend inline fun <reified T> bodyOrFailure(r: HttpResponse?): StatusAndData<T> {
return if (r != null && r.status.isSuccess()) {
StatusAndData.succes(r.body())
} else {
StatusAndData.error()
try {
return if (r != null && r.status.isSuccess()) {
StatusAndData.succes(r.body())
} else {
StatusAndData.error()
}
} catch (e: Throwable) {
return StatusAndData.error()
}
}
@ -94,4 +98,4 @@ suspend fun HttpClient.tryToSubmitForm(
url(url)
block()
}
}
}

View File

@ -2,12 +2,8 @@ package bou.amine.apps.readerforselfossv2.utils
actual class DateUtils {
actual companion object {
actual fun parseDate(dateString: String): Long {
TODO("Not yet implemented")
}
actual fun parseRelativeDate(dateString: String): String {
TODO("Not yet implemented")
}
}
}
}

View File

@ -2,12 +2,8 @@ package bou.amine.apps.readerforselfossv2.utils
actual class DateUtils {
actual companion object {
actual fun parseDate(dateString: String): Long {
TODO("Not yet implemented")
}
actual fun parseRelativeDate(dateString: String): String {
TODO("Not yet implemented")
}
}
}
}