Compare commits

...

4 Commits

Author SHA1 Message Date
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
15 changed files with 118 additions and 72 deletions

View File

@ -203,7 +203,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> {

View File

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

View File

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

View File

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

View File

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

View File

@ -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
@ -53,7 +58,7 @@ 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"
@ -211,7 +216,7 @@ 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) { if (context != null) {
if (this@ArticleFragment.item.unread) { if (this@ArticleFragment.item.unread) {
@ -236,6 +241,7 @@ class ArticleFragment : Fragment(), DIAware {
).show() ).show()
} }
} }
else -> Unit else -> Unit
} }
} }
@ -288,7 +294,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 +326,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 +345,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 +358,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 +371,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",
@ -545,7 +550,7 @@ class ArticleFragment : Fragment(), DIAware {
private fun openInBrowserAfterFailing() { private fun openInBrowserAfterFailing() {
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
if (context != null) { if (context != null) {
requireContext().openInBrowserAsNewTask(this@ArticleFragment.item) requireContext().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
} else { } else {
Exception("openInBrowserAfterFailing context is null").sendSilentlyWithAcraWithName("openInBrowserAfterFailing > $context") Exception("openInBrowserAfterFailing context is null").sendSilentlyWithAcraWithName("openInBrowserAfterFailing > $context")
} }

View File

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

View File

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

View File

@ -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
@ -237,9 +236,8 @@ class SettingsActivity :
} }
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(
@ -250,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
} }
} }

View File

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

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.ACRA
import org.acra.ktx.sendSilentlyWithAcra import org.acra.ktx.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

@ -30,11 +30,15 @@ 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> {
try {
return if (r != null && r.status.isSuccess()) { return if (r != null && r.status.isSuccess()) {
StatusAndData.succes(r.body()) StatusAndData.succes(r.body())
} else { } else {
StatusAndData.error() StatusAndData.error()
} }
} catch (e: Throwable) {
return StatusAndData.error()
}
} }
inline fun tryToRequest( inline fun tryToRequest(

View File

@ -2,10 +2,6 @@ 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")
} }

View File

@ -2,10 +2,6 @@ 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")
} }