Compare commits

..

6 Commits

Author SHA1 Message Date
99fc417109 Fixed #230. 2018-10-29 19:53:41 +01:00
dc304ef8c1 Updated gradle. 2018-10-20 09:29:09 +02:00
c5511880bc Just trying to fix fragment issues. 2018-10-19 05:27:16 +02:00
5fe76d735e Remiving items from the cache on swipe. 2018-10-17 20:19:35 +02:00
3064b3b835 Closes #228 by removing the list action bar. Action buttons are exclusively on the card view from now on. 2018-10-17 19:46:30 +02:00
70dc8af3ce New Crowdin translations (#227)
* New translations strings.xml (Spanish)

* New translations strings.xml (Galician)
2018-10-16 08:33:34 +02:00
14 changed files with 86 additions and 184 deletions

View File

@ -2,6 +2,8 @@
- Closing #1. Initial article caching. - Closing #1. Initial article caching.
- Closing #228 by removing the list action bar. Action buttons are exclusively on the card view from now on.
**1.6.x** **1.6.x**
- Handling hidden tags. - Handling hidden tags.

View File

@ -30,22 +30,6 @@
<fields>; <fields>;
} }
##Retrofit
#-keep class com.google.gson.** { *; }
#-keep class com.google.inject.** { *; }
#-keep class org.apache.http.** { *; }
#-keep class org.apache.james.mime4j.** { *; }
#-keep class javax.inject.** { *; }
#-keep class retrofit.** { *; }
#-keepclassmembernames interface * {
# @retrofit.http.* <methods>;
#}
#-keep class retrofit.** { *; }
#-keep class apps.amine.bou.readerforselfoss.api.selfoss.model.** { *; }
#-keepclassmembernames interface * {
# @retrofit.http.* <methods>;
#}
-dontwarn okio.** -dontwarn okio.**
-dontwarn retrofit2.Platform$Java8 -dontwarn retrofit2.Platform$Java8
-keep class retrofit.** { *; } -keep class retrofit.** { *; }
@ -75,4 +59,7 @@
-dontwarn javax.annotation.** -dontwarn javax.annotation.**
-keep class android.support.v7.widget.SearchView { *; } -keep class android.support.v7.widget.SearchView { *; }
# maybe remove later ?
-keep class * extends androidx.fragment.app.Fragment

View File

@ -1034,6 +1034,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
this, this,
items, items,
api, api,
db,
customTabActivityHelper, customTabActivityHelper,
internalBrowser, internalBrowser,
articleViewer, articleViewer,
@ -1050,6 +1051,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
this, this,
items, items,
api, api,
db,
customTabActivityHelper, customTabActivityHelper,
internalBrowser, internalBrowser,
articleViewer, articleViewer,

View File

@ -13,14 +13,18 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.room.Room
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.fragments.ArticleFragment import apps.amine.bou.readerforselfoss.fragments.ArticleFragment
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings import apps.amine.bou.readerforselfoss.themes.Toppings
import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
import apps.amine.bou.readerforselfoss.utils.succeeded import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toggleStar import apps.amine.bou.readerforselfoss.utils.toggleStar
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
@ -30,6 +34,7 @@ import org.acra.ACRA
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import kotlin.concurrent.thread
class ReaderActivity : AppCompatActivity() { class ReaderActivity : AppCompatActivity() {
@ -42,6 +47,8 @@ class ReaderActivity : AppCompatActivity() {
private lateinit var toolbarMenu: Menu private lateinit var toolbarMenu: Menu
private lateinit var db: AppDatabase
private fun showMenuItem(willAddToFavorite: Boolean) { private fun showMenuItem(willAddToFavorite: Boolean) {
toolbarMenu.findItem(R.id.save).isVisible = willAddToFavorite toolbarMenu.findItem(R.id.save).isVisible = willAddToFavorite
toolbarMenu.findItem(R.id.unsave).isVisible = !willAddToFavorite toolbarMenu.findItem(R.id.unsave).isVisible = !willAddToFavorite
@ -60,6 +67,11 @@ class ReaderActivity : AppCompatActivity() {
setContentView(R.layout.activity_reader) setContentView(R.layout.activity_reader)
db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).build()
val scoop = Scoop.getInstance() val scoop = Scoop.getInstance()
scoop.bind(this, Toppings.PRIMARY.value, toolBar) scoop.bind(this, Toppings.PRIMARY.value, toolBar)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
@ -89,7 +101,7 @@ class ReaderActivity : AppCompatActivity() {
currentItem = intent.getIntExtra("currentItem", 0) currentItem = intent.getIntExtra("currentItem", 0)
readItem(allItems[currentItem].id) readItem(allItems[currentItem])
pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity))
pager.currentItem = currentItem pager.currentItem = currentItem
@ -113,15 +125,18 @@ class ReaderActivity : AppCompatActivity() {
} else { } else {
canFavorite() canFavorite()
} }
readItem(allItems[pager.currentItem].id) readItem(allItems[pager.currentItem])
} }
} }
) )
} }
fun readItem(id: String) { fun readItem(item: Item) {
if (markOnScroll) { if (markOnScroll) {
api.markItem(id).enqueue( thread {
db.itemsDao().delete(item.toEntity())
}
api.markItem(item.id).enqueue(
object : Callback<SuccessResponse> { object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -145,6 +160,9 @@ class ReaderActivity : AppCompatActivity() {
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
t: Throwable t: Throwable
) { ) {
thread {
db.itemsDao().insertAllItems(item.toEntity())
}
if (debugReadingItems) { if (debugReadingItems) {
ACRA.getErrorReporter().maybeHandleSilentException(t, this@ReaderActivity) ACRA.getErrorReporter().maybeHandleSilentException(t, this@ReaderActivity)
} }

View File

@ -14,6 +14,7 @@ import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
@ -38,6 +39,7 @@ class ItemCardAdapter(
override val app: Activity, override val app: Activity,
override var items: ArrayList<Item>, override var items: ArrayList<Item>,
override val api: SelfossApi, override val api: SelfossApi,
override val db: AppDatabase,
private val helper: CustomTabActivityHelper, private val helper: CustomTabActivityHelper,
private val internalBrowser: Boolean, private val internalBrowser: Boolean,
private val articleViewer: Boolean, private val articleViewer: Boolean,

View File

@ -14,6 +14,7 @@ import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
@ -39,6 +40,7 @@ class ItemListAdapter(
override val app: Activity, override val app: Activity,
override var items: ArrayList<Item>, override var items: ArrayList<Item>,
override val api: SelfossApi, override val api: SelfossApi,
override val db: AppDatabase,
private val helper: CustomTabActivityHelper, private val helper: CustomTabActivityHelper,
private val internalBrowser: Boolean, private val internalBrowser: Boolean,
private val articleViewer: Boolean, private val articleViewer: Boolean,
@ -49,7 +51,6 @@ class ItemListAdapter(
) : ItemsAdapter<ItemListAdapter.ViewHolder>() { ) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
private val generator: ColorGenerator = ColorGenerator.MATERIAL private val generator: ColorGenerator = ColorGenerator.MATERIAL
private val c: Context = app.baseContext private val c: Context = app.baseContext
private val bars: ArrayList<Boolean> = ArrayList(Collections.nCopies(items.size + 1, false))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(c).inflate( val v = LayoutInflater.from(c).inflate(
@ -105,19 +106,6 @@ class ItemListAdapter(
} else { } else {
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage) c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
} }
// TODO: maybe handle this differently. It crashes when changing tab
try {
if (bars[position]) {
holder.mView.actionBar.visibility = View.VISIBLE
} else {
holder.mView.actionBar.visibility = View.GONE
}
} catch (e: IndexOutOfBoundsException) {
holder.mView.actionBar.visibility = View.GONE
}
holder.mView.favButton.isLiked = itm.starred
} }
override fun getItemCount(): Int = items.size override fun getItemCount(): Int = items.size
@ -125,76 +113,14 @@ class ItemListAdapter(
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) { inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
init { init {
handleClickListeners()
handleCustomTabActions() handleCustomTabActions()
} }
private fun handleClickListeners() {
mView.favButton.setOnLikeListener(object : OnLikeListener {
override fun liked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = false
Toast.makeText(
c,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
override fun unLiked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = true
Toast.makeText(
c,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
})
mView.shareBtn.setOnClickListener {
c.shareLink(items[adapterPosition].getLinkDecoded())
}
mView.browserBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[adapterPosition])
}
}
private fun handleCustomTabActions() { private fun handleCustomTabActions() {
val customTabsIntent = c.buildCustomTabsIntent() val customTabsIntent = c.buildCustomTabsIntent()
helper.bindCustomTabsService(app) helper.bindCustomTabsService(app)
mView.setOnClickListener { actionBarShowHide() } mView.setOnClickListener {
mView.setOnLongClickListener {
c.openItemUrl( c.openItemUrl(
items, items,
adapterPosition, adapterPosition,
@ -204,16 +130,6 @@ class ItemListAdapter(
articleViewer, articleViewer,
app app
) )
true
}
}
private fun actionBarShowHide() {
bars[adapterPosition] = true
if (mView.actionBar.visibility == View.GONE) {
mView.actionBar.visibility = View.VISIBLE
} else {
mView.actionBar.visibility = View.GONE
} }
} }
} }

View File

@ -10,17 +10,21 @@ import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
import apps.amine.bou.readerforselfoss.utils.succeeded import apps.amine.bou.readerforselfoss.utils.succeeded
import org.acra.ACRA import org.acra.ACRA
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import kotlin.concurrent.thread
abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() { abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() {
abstract var items: ArrayList<Item> abstract var items: ArrayList<Item>
abstract val api: SelfossApi abstract val api: SelfossApi
abstract val db: AppDatabase
abstract val debugReadingItems: Boolean abstract val debugReadingItems: Boolean
abstract val userIdentifier: String abstract val userIdentifier: String
abstract val app: Activity abstract val app: Activity
@ -42,6 +46,9 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
) )
.setAction(R.string.undo_string) { .setAction(R.string.undo_string) {
items.add(position, i) items.add(position, i)
thread {
db.itemsDao().insertAllItems(i.toEntity())
}
notifyItemInserted(position) notifyItemInserted(position)
updateItems(items) updateItems(items)
@ -54,6 +61,9 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) { override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
items.remove(i) items.remove(i)
thread {
db.itemsDao().delete(i.toEntity())
}
notifyItemRemoved(position) notifyItemRemoved(position)
updateItems(items) updateItems(items)
doUnmark(i, position) doUnmark(i, position)
@ -75,6 +85,12 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
notifyItemRemoved(position) notifyItemRemoved(position)
updateItems(items) updateItems(items)
// TODO: Handle network status.
// IF offline, delete from cached articles, and add to some table that will replay the calls on network activation.
thread {
db.itemsDao().delete(i.toEntity())
}
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> { api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
@ -93,6 +109,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), app) ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), app)
Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show() Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show()
} }
doUnmark(i, position) doUnmark(i, position)
} }
@ -110,6 +127,9 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
notifyItemInserted(position) notifyItemInserted(position)
updateItems(items) updateItems(items)
thread {
db.itemsDao().insertAllItems(i.toEntity())
}
} }
}) })
} }

View File

@ -1,6 +1,7 @@
package apps.amine.bou.readerforselfoss.persistence.dao package apps.amine.bou.readerforselfoss.persistence.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
@ -15,11 +16,14 @@ interface ItemsDao {
fun items(): List<ItemEntity> fun items(): List<ItemEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAllItems(vararg tags: ItemEntity) fun insertAllItems(vararg items: ItemEntity)
@Query("DELETE FROM items") @Query("DELETE FROM items")
fun deleteAllItems() fun deleteAllItems()
@Delete
fun delete(item: ItemEntity)
@Update @Update
fun updateItem(item: ItemEntity) fun updateItem(item: ItemEntity)
} }

View File

@ -69,6 +69,7 @@
app:layout_constraintLeft_toRightOf="@+id/sourceImage" app:layout_constraintLeft_toRightOf="@+id/sourceImage"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/sourceImage" app:layout_constraintTop_toTopOf="@+id/sourceImage"
android:autoLink="web"
tools:text="Titre" /> tools:text="Titre" />
<TextView <TextView

View File

@ -11,7 +11,6 @@
android:id="@+id/itemImage" android:id="@+id/itemImage"
android:layout_width="88dp" android:layout_width="88dp"
android:layout_height="88dp" android:layout_height="88dp"
app:layout_constraintBottom_toBottomOf="@+id/actionBar"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -34,85 +33,23 @@
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/itemImage" app:layout_constraintStart_toEndOf="@+id/itemImage"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:autoLink="web"
tools:text="Titre" /> tools:text="Titre" />
<TextView <TextView
android:id="@+id/sourceTitleAndDate" android:id="@+id/sourceTitleAndDate"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:gravity="start" android:gravity="start"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@+id/actionBar"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/itemImage" app:layout_constraintStart_toEndOf="@+id/itemImage"
app:layout_constraintTop_toBottomOf="@+id/title" app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Google Actualité Il y a 5h" /> tools:text="Google Actualité Il y a 5h" />
<RelativeLayout
android:id="@+id/actionBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#BBBBBB"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible">
<com.like.LikeButton
android:id="@+id/favButton"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:elevation="5dp"
android:padding="4dp"
app:icon_size="22dp"
app:icon_type="heart" />
<ImageButton
android:id="@+id/shareBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/favButton"
android:layout_toStartOf="@+id/favButton"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:backgroundTint="?android:attr/textColorPrimary"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_share_black_24dp" />
<ImageButton
android:id="@+id/browserBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/shareBtn"
android:layout_toStartOf="@+id/shareBtn"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:backgroundTint="?android:attr/textColorPrimary"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -148,8 +148,8 @@
<string name="acra_login">Habilitar el registro</string> <string name="acra_login">Habilitar el registro</string>
<string name="drawer_item_hidden_tags">Etiquetas ocultas</string> <string name="drawer_item_hidden_tags">Etiquetas ocultas</string>
<string name="unmark">Marcar artículo como no leído</string> <string name="unmark">Marcar artículo como no leído</string>
<string name="pref_header_offline">Offline and cache</string> <string name="pref_header_offline">Sin conexión y caché</string>
<string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> <string name="pref_switch_items_caching_off">Los artículos no se guardarán en la memoria del dispositivo y la aplicación no se podrá utilizar sin conexión.</string>
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Los artículos se guardarán en la memoria del dispositivo y se utilizarán para el uso sin conexión.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Guardar elementos para uso sin conexión</string>
</resources> </resources>

View File

@ -148,8 +148,8 @@
<string name="acra_login">Habilitar o rexistro</string> <string name="acra_login">Habilitar o rexistro</string>
<string name="drawer_item_hidden_tags">Etiquetas ocultas</string> <string name="drawer_item_hidden_tags">Etiquetas ocultas</string>
<string name="unmark">Marcar artículo como non lido</string> <string name="unmark">Marcar artículo como non lido</string>
<string name="pref_header_offline">Offline and cache</string> <string name="pref_header_offline">Sen conexión e caché</string>
<string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> <string name="pref_switch_items_caching_off">Os artigos non se gardaran na memoria do dispositivo e non se poderá utilizar a aplicación sen conexión.</string>
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Os artigos gardaranse na memoria do dispositivo e estarán dispoñibles sen conexión.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Gardar elementos para uso sen conexión</string>
</resources> </resources>

View File

@ -15,7 +15,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.0' classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }

View File

@ -1 +1,14 @@
include ':app' include ':app'
ext.isCiServer = !!System.getProperty("CI")
buildCache {
local {
enabled = !isCiServer
}
remote(HttpBuildCache) {
// DO NOT COMMIT !!!!!
url = 'http://amine-bou.fr:8885/cache/'
push = isCiServer
}
}