Compare commits
15 Commits
v172012358
...
image
Author | SHA1 | Date | |
---|---|---|---|
d0557cf653 | |||
f6999dd547 | |||
040c845c15 | |||
cb07227cb7 | |||
cda09a4e8a | |||
3de95ba6e4 | |||
47f00dc694 | |||
584c6869b5 | |||
b0c4b010a2 | |||
e08fc2604f | |||
41386adf4e | |||
59c307323f | |||
41e825bc50 | |||
0bab675560 | |||
55ced4a5fb |
@ -101,7 +101,7 @@ dependencies {
|
|||||||
implementation "androidx.vectordrawable:vectordrawable:1.1.0-beta01"
|
implementation "androidx.vectordrawable:vectordrawable:1.1.0-beta01"
|
||||||
implementation "androidx.browser:browser:$android_version"
|
implementation "androidx.browser:browser:$android_version"
|
||||||
implementation "androidx.cardview:cardview:$android_version"
|
implementation "androidx.cardview:cardview:$android_version"
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0-alpha1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha5'
|
||||||
implementation 'org.jsoup:jsoup:1.13.1'
|
implementation 'org.jsoup:jsoup:1.13.1'
|
||||||
|
|
||||||
//multidex
|
//multidex
|
||||||
@ -138,6 +138,9 @@ dependencies {
|
|||||||
// Pager
|
// Pager
|
||||||
implementation 'me.relex:circleindicator:2.0.0@aar'
|
implementation 'me.relex:circleindicator:2.0.0@aar'
|
||||||
|
|
||||||
|
//PhotoView
|
||||||
|
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.1.0-beta01'
|
implementation 'androidx.core:core-ktx:1.1.0-beta01'
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
|
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
|
||||||
@ -147,4 +150,4 @@ dependencies {
|
|||||||
kapt "androidx.room:room-compiler:$room_version"
|
kapt "androidx.room:room-compiler:$room_version"
|
||||||
|
|
||||||
implementation "android.arch.work:work-runtime-ktx:$work_version"
|
implementation "android.arch.work:work-runtime-ktx:$work_version"
|
||||||
}
|
}
|
@ -1,226 +0,0 @@
|
|||||||
{
|
|
||||||
"formatVersion": 1,
|
|
||||||
"database": {
|
|
||||||
"version": 4,
|
|
||||||
"identityHash": "9cf8b03d32f80dfd58160599a1df197d",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"tableName": "tags",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` TEXT NOT NULL, `color` TEXT NOT NULL, `unread` INTEGER NOT NULL, PRIMARY KEY(`tag`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "tag",
|
|
||||||
"columnName": "tag",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "color",
|
|
||||||
"columnName": "color",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "unread",
|
|
||||||
"columnName": "unread",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"tag"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "sources",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `title` TEXT NOT NULL, `tags` TEXT NOT NULL, `spout` TEXT NOT NULL, `error` TEXT NOT NULL, `icon` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "id",
|
|
||||||
"columnName": "id",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "title",
|
|
||||||
"columnName": "title",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "tags",
|
|
||||||
"columnName": "tags",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "spout",
|
|
||||||
"columnName": "spout",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "error",
|
|
||||||
"columnName": "error",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "icon",
|
|
||||||
"columnName": "icon",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "items",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `datetime` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `thumbnail` TEXT, `icon` TEXT, `link` TEXT NOT NULL, `sourcetitle` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "id",
|
|
||||||
"columnName": "id",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "datetime",
|
|
||||||
"columnName": "datetime",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "title",
|
|
||||||
"columnName": "title",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "content",
|
|
||||||
"columnName": "content",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "unread",
|
|
||||||
"columnName": "unread",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "starred",
|
|
||||||
"columnName": "starred",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "thumbnail",
|
|
||||||
"columnName": "thumbnail",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "icon",
|
|
||||||
"columnName": "icon",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "link",
|
|
||||||
"columnName": "link",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "sourcetitle",
|
|
||||||
"columnName": "sourcetitle",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "tags",
|
|
||||||
"columnName": "tags",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "actions",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `articleid` TEXT NOT NULL, `read` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `unstarred` INTEGER NOT NULL)",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "id",
|
|
||||||
"columnName": "id",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "articleId",
|
|
||||||
"columnName": "articleid",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "read",
|
|
||||||
"columnName": "read",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "unread",
|
|
||||||
"columnName": "unread",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "starred",
|
|
||||||
"columnName": "starred",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "unstarred",
|
|
||||||
"columnName": "unstarred",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"autoGenerate": true
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [],
|
|
||||||
"setupQueries": [
|
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"9cf8b03d32f80dfd58160599a1df197d\")"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,6 +62,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ReaderActivity">
|
android:name=".ReaderActivity">
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ImageActivity">
|
||||||
|
</activity>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="apps.amine.bou.readerforselfoss.utils.glide.SelfSignedGlideModule"
|
android:name="apps.amine.bou.readerforselfoss.utils.glide.SelfSignedGlideModule"
|
||||||
|
@ -33,7 +33,6 @@ import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
|
|||||||
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4
|
|
||||||
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
|
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
|
||||||
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
|
||||||
@ -165,7 +164,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
db = Room.databaseBuilder(
|
db = Room.databaseBuilder(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
|
||||||
|
|
||||||
|
|
||||||
customTabActivityHelper = CustomTabActivityHelper()
|
customTabActivityHelper = CustomTabActivityHelper()
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||||
|
import apps.amine.bou.readerforselfoss.fragments.ImageFragment
|
||||||
|
import kotlinx.android.synthetic.main.activity_reader.*
|
||||||
|
|
||||||
|
class ImageActivity : AppCompatActivity() {
|
||||||
|
private lateinit var allImages : ArrayList<String>
|
||||||
|
private var position : Int = 0
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_image)
|
||||||
|
|
||||||
|
setSupportActionBar(toolBar)
|
||||||
|
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
allImages = intent.getStringArrayListExtra("allImages")
|
||||||
|
position = intent.getIntExtra("position", 0)
|
||||||
|
|
||||||
|
pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager)
|
||||||
|
pager.currentItem = position
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
android.R.id.home -> {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||||
|
|
||||||
|
override fun getCount(): Int {
|
||||||
|
return allImages.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(position: Int): ImageFragment {
|
||||||
|
return ImageFragment.newInstance(allImages[position])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,6 @@ import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
|
|||||||
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4
|
|
||||||
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
|
||||||
@ -82,7 +81,7 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
db = Room.databaseBuilder(
|
db = Room.databaseBuilder(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
|
||||||
|
|
||||||
val scoop = Scoop.getInstance()
|
val scoop = Scoop.getInstance()
|
||||||
scoop.bind(this, Toppings.PRIMARY.value, toolBar)
|
scoop.bind(this, Toppings.PRIMARY.value, toolBar)
|
||||||
|
@ -5,9 +5,14 @@ import android.net.Uri
|
|||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
|
import android.webkit.URLUtil
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
import apps.amine.bou.readerforselfoss.utils.Config
|
import apps.amine.bou.readerforselfoss.utils.Config
|
||||||
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
|
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
private fun constructUrl(config: Config?, path: String, file: String?): String {
|
private fun constructUrl(config: Config?, path: String, file: String?): String {
|
||||||
@ -128,6 +133,36 @@ data class Item(
|
|||||||
return constructUrl(config, "thumbnails", thumbnail)
|
return constructUrl(config, "thumbnails", thumbnail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getImages() : ArrayList<String> {
|
||||||
|
var allImages = ArrayList<String>()
|
||||||
|
|
||||||
|
for ( image in Jsoup.parse(content).getElementsByTag("img")) {
|
||||||
|
allImages.add(image.attr("src"))
|
||||||
|
}
|
||||||
|
return allImages
|
||||||
|
}
|
||||||
|
|
||||||
|
fun preloadImages(context: Context) : Boolean {
|
||||||
|
val imageUrls = this.getImages()
|
||||||
|
|
||||||
|
val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (url in imageUrls) {
|
||||||
|
if ( URLUtil.isValidUrl(url)) {
|
||||||
|
val image = Glide.with(context).asBitmap()
|
||||||
|
.apply(glideOptions)
|
||||||
|
.load(url).submit().get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e : Error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
fun getTitleDecoded(): String {
|
fun getTitleDecoded(): String {
|
||||||
return Html.fromHtml(title).toString()
|
return Html.fromHtml(title).toString()
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
|
|||||||
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4
|
|
||||||
import apps.amine.bou.readerforselfoss.utils.Config
|
import apps.amine.bou.readerforselfoss.utils.Config
|
||||||
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
|
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
|
||||||
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
|
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
|
||||||
@ -57,7 +56,7 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con
|
|||||||
db = Room.databaseBuilder(
|
db = Room.databaseBuilder(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
|
||||||
|
|
||||||
val api = SelfossApi(
|
val api = SelfossApi(
|
||||||
this.context,
|
this.context,
|
||||||
@ -105,6 +104,7 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con
|
|||||||
notificationManager.notify(2, newItemsNotification.build())
|
notificationManager.notify(2, newItemsNotification.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
apiItems.map {it.preloadImages(context)}
|
||||||
}
|
}
|
||||||
Timer("", false).schedule(4000) {
|
Timer("", false).schedule(4000) {
|
||||||
notificationManager.cancel(1)
|
notificationManager.cancel(1)
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
package apps.amine.bou.readerforselfoss.fragments
|
package apps.amine.bou.readerforselfoss.fragments
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
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.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.view.InflateException
|
import android.view.*
|
||||||
|
import android.webkit.*
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.webkit.WebSettings
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
|
import apps.amine.bou.readerforselfoss.ImageActivity
|
||||||
import apps.amine.bou.readerforselfoss.R
|
import apps.amine.bou.readerforselfoss.R
|
||||||
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
||||||
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
|
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
|
||||||
@ -33,12 +33,12 @@ import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
|
|||||||
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
|
||||||
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4
|
|
||||||
import apps.amine.bou.readerforselfoss.themes.AppColors
|
import apps.amine.bou.readerforselfoss.themes.AppColors
|
||||||
import apps.amine.bou.readerforselfoss.utils.Config
|
import apps.amine.bou.readerforselfoss.utils.Config
|
||||||
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
|
||||||
import apps.amine.bou.readerforselfoss.utils.glide.loadMaybeBasicAuth
|
import apps.amine.bou.readerforselfoss.utils.glide.loadMaybeBasicAuth
|
||||||
|
import apps.amine.bou.readerforselfoss.utils.glide.getBitmapInputStream
|
||||||
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
|
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
|
||||||
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
|
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
|
||||||
import apps.amine.bou.readerforselfoss.utils.openItemUrl
|
import apps.amine.bou.readerforselfoss.utils.openItemUrl
|
||||||
@ -46,6 +46,7 @@ import apps.amine.bou.readerforselfoss.utils.shareLink
|
|||||||
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
||||||
import apps.amine.bou.readerforselfoss.utils.succeeded
|
import apps.amine.bou.readerforselfoss.utils.succeeded
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||||
import kotlinx.android.synthetic.main.fragment_article.view.*
|
import kotlinx.android.synthetic.main.fragment_article.view.*
|
||||||
@ -54,6 +55,8 @@ import retrofit2.Callback
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.net.MalformedURLException
|
import java.net.MalformedURLException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import java.util.concurrent.ExecutionException
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
class ArticleFragment : Fragment() {
|
class ArticleFragment : Fragment() {
|
||||||
@ -66,6 +69,7 @@ class ArticleFragment : Fragment() {
|
|||||||
private lateinit var contentSource: String
|
private lateinit var contentSource: String
|
||||||
private lateinit var contentImage: String
|
private lateinit var contentImage: String
|
||||||
private lateinit var contentTitle: String
|
private lateinit var contentTitle: String
|
||||||
|
private lateinit var allImages : ArrayList<String>
|
||||||
private lateinit var editor: SharedPreferences.Editor
|
private lateinit var editor: SharedPreferences.Editor
|
||||||
private lateinit var fab: FloatingActionButton
|
private lateinit var fab: FloatingActionButton
|
||||||
private lateinit var appColors: AppColors
|
private lateinit var appColors: AppColors
|
||||||
@ -100,7 +104,7 @@ class ArticleFragment : Fragment() {
|
|||||||
db = Room.databaseBuilder(
|
db = Room.databaseBuilder(
|
||||||
context!!,
|
context!!,
|
||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -117,6 +121,7 @@ class ArticleFragment : Fragment() {
|
|||||||
contentTitle = allItems[pageNumber.toInt()].getTitleDecoded()
|
contentTitle = allItems[pageNumber.toInt()].getTitleDecoded()
|
||||||
contentImage = allItems[pageNumber.toInt()].getThumbnail(activity!!)
|
contentImage = allItems[pageNumber.toInt()].getThumbnail(activity!!)
|
||||||
contentSource = allItems[pageNumber.toInt()].sourceAndDateText()
|
contentSource = allItems[pageNumber.toInt()].sourceAndDateText()
|
||||||
|
allImages = allItems[pageNumber.toInt()].getImages()
|
||||||
|
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(activity)
|
prefs = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
editor = prefs.edit()
|
editor = prefs.edit()
|
||||||
@ -411,6 +416,47 @@ class ArticleFragment : Fragment() {
|
|||||||
rootView!!.webcontent.settings.loadWithOverviewMode = true
|
rootView!!.webcontent.settings.loadWithOverviewMode = true
|
||||||
rootView!!.webcontent.settings.javaScriptEnabled = false
|
rootView!!.webcontent.settings.javaScriptEnabled = false
|
||||||
|
|
||||||
|
rootView!!.webcontent.webViewClient = object : WebViewClient() {
|
||||||
|
override fun shouldOverrideUrlLoading(view: WebView?, url : String): Boolean {
|
||||||
|
if (rootView!!.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||||
|
rootView!!.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldInterceptRequest(view: WebView?, url: String): WebResourceResponse? {
|
||||||
|
val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
|
||||||
|
if (url.toLowerCase().contains(".jpg") || url.toLowerCase().contains(".jpeg")) {
|
||||||
|
try {
|
||||||
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
|
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG))
|
||||||
|
}catch ( e : ExecutionException) {}
|
||||||
|
}
|
||||||
|
else if (url.toLowerCase().contains(".png")) {
|
||||||
|
try {
|
||||||
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
|
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG))
|
||||||
|
}catch ( e : ExecutionException) {}
|
||||||
|
}
|
||||||
|
else if (url.toLowerCase().contains(".webp")) {
|
||||||
|
try {
|
||||||
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
|
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP))
|
||||||
|
}catch ( e : ExecutionException) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.shouldInterceptRequest(view, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val gestureDetector = GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() {
|
||||||
|
override fun onSingleTapUp(e: MotionEvent?): Boolean {
|
||||||
|
return performClick()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
rootView!!.webcontent.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event)}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
rootView!!.webcontent.settings.layoutAlgorithm =
|
rootView!!.webcontent.settings.layoutAlgorithm =
|
||||||
WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||||
@ -526,5 +572,20 @@ class ArticleFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun performClick(): Boolean {
|
||||||
|
if (rootView!!.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
|
||||||
|
rootView!!.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||||
|
|
||||||
|
val position : Int = allImages.indexOf(rootView!!.webcontent.hitTestResult.extra)
|
||||||
|
|
||||||
|
val intent = Intent(activity, ImageActivity::class.java)
|
||||||
|
intent.putExtra("allImages", allImages)
|
||||||
|
intent.putExtra("position", position)
|
||||||
|
startActivity(intent)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.*
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import apps.amine.bou.readerforselfoss.R
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import kotlinx.android.synthetic.main.fragment_image.view.*
|
||||||
|
|
||||||
|
class ImageFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var imageUrl : String
|
||||||
|
private val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
imageUrl = arguments!!.getString("imageUrl")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
val view : View = inflater.inflate(R.layout.fragment_image, container, false)
|
||||||
|
|
||||||
|
view.photoView.visibility = View.VISIBLE
|
||||||
|
Glide.with(activity)
|
||||||
|
.asBitmap()
|
||||||
|
.apply(glideOptions)
|
||||||
|
.load(imageUrl)
|
||||||
|
.into(view.photoView)
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val ARG_IMAGE = "imageUrl"
|
||||||
|
|
||||||
|
fun newInstance(
|
||||||
|
imageUrl : String
|
||||||
|
): ImageFragment {
|
||||||
|
val fragment = ImageFragment()
|
||||||
|
val args = Bundle()
|
||||||
|
args.putString(ARG_IMAGE, imageUrl)
|
||||||
|
fragment.arguments = args
|
||||||
|
return fragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ import apps.amine.bou.readerforselfoss.persistence.entities.ItemEntity
|
|||||||
import apps.amine.bou.readerforselfoss.persistence.entities.SourceEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.SourceEntity
|
||||||
import apps.amine.bou.readerforselfoss.persistence.entities.TagEntity
|
import apps.amine.bou.readerforselfoss.persistence.entities.TagEntity
|
||||||
|
|
||||||
@Database(entities = [TagEntity::class, SourceEntity::class, ItemEntity::class, ActionEntity::class], version = 4)
|
@Database(entities = [TagEntity::class, SourceEntity::class, ItemEntity::class, ActionEntity::class], version = 3)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun drawerDataDao(): DrawerDataDao
|
abstract fun drawerDataDao(): DrawerDataDao
|
||||||
|
|
||||||
|
@ -14,21 +14,3 @@ val MIGRATION_2_3: Migration = object : Migration(2, 3) {
|
|||||||
database.execSQL("CREATE TABLE IF NOT EXISTS `actions` (`id` INTEGER NOT NULL, `articleid` TEXT NOT NULL, `read` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `unstarred` INTEGER NOT NULL, PRIMARY KEY(`id`))")
|
database.execSQL("CREATE TABLE IF NOT EXISTS `actions` (`id` INTEGER NOT NULL, `articleid` TEXT NOT NULL, `read` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `unstarred` INTEGER NOT NULL, PRIMARY KEY(`id`))")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val MIGRATION_3_4: Migration = object : Migration(3, 4) {
|
|
||||||
override fun migrate(database: SupportSQLiteDatabase) {
|
|
||||||
// @see https://stackoverflow.com/questions/57392015/how-to-migrate-not-null-table-column-into-null-in-android-room-database
|
|
||||||
// Create the new table
|
|
||||||
database.execSQL("CREATE TABLE IF NOT EXISTS `itemstmp` (`id` TEXT NOT NULL, `datetime` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `thumbnail` TEXT, `icon` TEXT, `link` TEXT NOT NULL, `sourcetitle` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`id`))")
|
|
||||||
|
|
||||||
// Copy the data
|
|
||||||
database.execSQL(
|
|
||||||
"INSERT INTO itemstmp (`id`, `datetime`, `title`, `content`, `unread`, `starred`, `thumbnail`, `icon`, `link`, `sourcetitle`, `tags`) SELECT `id`, `datetime`, `title`, `content`, `unread`, `starred`, `thumbnail`, `icon`, `link`, `sourcetitle`, `tags` FROM items")
|
|
||||||
|
|
||||||
// Remove the old table
|
|
||||||
database.execSQL("DROP TABLE items")
|
|
||||||
|
|
||||||
// Change the table name to the correct one
|
|
||||||
database.execSQL("ALTER TABLE itemstmp RENAME TO items")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -14,6 +14,9 @@ import com.bumptech.glide.load.model.GlideUrl
|
|||||||
import com.bumptech.glide.load.model.LazyHeaders
|
import com.bumptech.glide.load.model.LazyHeaders
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.bumptech.glide.request.target.BitmapImageViewTarget
|
import com.bumptech.glide.request.target.BitmapImageViewTarget
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
fun Context.bitmapCenterCrop(config: Config, url: String, iv: ImageView) =
|
fun Context.bitmapCenterCrop(config: Config, url: String, iv: ImageView) =
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
@ -56,4 +59,11 @@ fun RequestManager.loadMaybeBasicAuth(config: Config, url: String): RequestBuild
|
|||||||
}
|
}
|
||||||
val glideUrl = GlideUrl(url, builder.build())
|
val glideUrl = GlideUrl(url, builder.build())
|
||||||
return this.load(glideUrl)
|
return this.load(glideUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBitmapInputStream(bitmap:Bitmap,compressFormat: Bitmap.CompressFormat): InputStream {
|
||||||
|
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||||
|
bitmap.compress(compressFormat, 80, byteArrayOutputStream)
|
||||||
|
val bitmapData: ByteArray = byteArrayOutputStream.toByteArray()
|
||||||
|
return ByteArrayInputStream(bitmapData)
|
||||||
}
|
}
|
33
app/src/main/res/layout/activity_image.xml
Normal file
33
app/src/main/res/layout/activity_image.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appBarLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:popupTheme="?attr/toolbarPopupTheme"
|
||||||
|
app:theme="@style/ToolBarStyle" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
16
app/src/main/res/layout/fragment_image.xml
Normal file
16
app/src/main/res/layout/fragment_image.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.github.chrisbanes.photoview.PhotoView
|
||||||
|
android:id="@+id/photoView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:background="@android:color/black"
|
||||||
|
app:srcCompat="@android:drawable/screen_background_dark" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -17,7 +17,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.1'
|
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Sat Dec 12 19:38:31 CET 2020
|
#Sat Feb 01 12:14:14 CET 2020
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||||
|
Reference in New Issue
Block a user