Compare commits
	
		
			14 Commits
		
	
	
		
			7d6e24f1fd
			...
			v172202040
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 288970483b | |||
| 5b540dbc38 | |||
| def75b6431 | |||
| 4826ed0355 | |||
| 3b47a4a2f0 | |||
| 9693dec807 | |||
| ca5186d20a | |||
| 78d5744139 | |||
| b2609554e6 | |||
| 5db312bbb8 | |||
| 7592ab512b | |||
| 000b346529 | |||
| 1bb975c584 | |||
| 69aaa323e2 | 
| @@ -44,8 +44,12 @@ | |||||||
|  |  | ||||||
| - Closing #236. New sources can be added in Selfoss 2.19. | - Closing #236. New sources can be added in Selfoss 2.19. | ||||||
|  |  | ||||||
|  | - Closing #397 and #355. Tag and Sources filters are now exclusive. | ||||||
|  |  | ||||||
| - Dropped support for android 4, the last version supporting it is v1721030811 | - Dropped support for android 4, the last version supporting it is v1721030811 | ||||||
|  |  | ||||||
|  | - Added ability to scroll articles up and down using the volume keys #400 | ||||||
|  |  | ||||||
| **1.6.x** | **1.6.x** | ||||||
|  |  | ||||||
| - Handling hidden tags. | - Handling hidden tags. | ||||||
|   | |||||||
| @@ -104,18 +104,18 @@ dependencies { | |||||||
|     // Espresso-intents for validation and stubbing of Intents |     // Espresso-intents for validation and stubbing of Intents | ||||||
|     androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0-alpha02' |     androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0-alpha02' | ||||||
|     implementation fileTree(include: ['*.jar'], dir: 'libs') |     implementation fileTree(include: ['*.jar'], dir: 'libs') | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |  | ||||||
|     // Android Support |     // Android Support | ||||||
|     implementation "androidx.appcompat:appcompat:1.4.0-beta01" |     implementation 'androidx.appcompat:appcompat:1.4.1' | ||||||
|     implementation 'com.google.android.material:material:1.5.0-alpha04' |     implementation 'com.google.android.material:material:1.5.0' | ||||||
|     implementation 'androidx.recyclerview:recyclerview:1.3.0-alpha01' |     implementation 'androidx.recyclerview:recyclerview:1.3.0-alpha01' | ||||||
|     implementation "androidx.legacy:legacy-support-v4:$android_version" |     implementation "androidx.legacy:legacy-support-v4:$android_version" | ||||||
|     implementation 'androidx.vectordrawable:vectordrawable:1.2.0-alpha02' |     implementation 'androidx.vectordrawable:vectordrawable:1.2.0-alpha02' | ||||||
|     implementation "androidx.browser:browser:1.3.0" |     implementation 'androidx.browser:browser:1.4.0' | ||||||
|     implementation "androidx.cardview:cardview:$android_version" |     implementation "androidx.cardview:cardview:$android_version" | ||||||
|     implementation "androidx.annotation:annotation:1.2.0" |     implementation 'androidx.annotation:annotation:1.3.0' | ||||||
|     implementation 'androidx.work:work-runtime-ktx:2.7.0' |     implementation 'androidx.work:work-runtime-ktx:2.7.1' | ||||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.1.1' |     implementation 'androidx.constraintlayout:constraintlayout:2.1.3' | ||||||
|     implementation 'org.jsoup:jsoup:1.14.3' |     implementation 'org.jsoup:jsoup:1.14.3' | ||||||
|  |  | ||||||
|     coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") |     coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") | ||||||
| @@ -129,11 +129,11 @@ dependencies { | |||||||
|     implementation "com.mikepenz:aboutlibraries-definitions:8.9.4" |     implementation "com.mikepenz:aboutlibraries-definitions:8.9.4" | ||||||
|  |  | ||||||
|     // Async |     // Async | ||||||
|     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2' |     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0' | ||||||
|  |  | ||||||
|     // Retrofit + http logging + okhttp |     // Retrofit + http logging + okhttp | ||||||
|     implementation 'com.squareup.retrofit2:retrofit:2.9.0' |     implementation 'com.squareup.retrofit2:retrofit:2.9.0' | ||||||
|     implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' |     implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.3' | ||||||
|     implementation 'com.squareup.retrofit2:converter-gson:2.9.0' |     implementation 'com.squareup.retrofit2:converter-gson:2.9.0' | ||||||
|     implementation 'com.burgstaller:okhttp-digest:2.5' |     implementation 'com.burgstaller:okhttp-digest:2.5' | ||||||
|  |  | ||||||
| @@ -146,7 +146,7 @@ dependencies { | |||||||
|     implementation 'com.github.bumptech.glide:okhttp3-integration:4.1.1' |     implementation 'com.github.bumptech.glide:okhttp3-integration:4.1.1' | ||||||
|  |  | ||||||
|     // Drawer |     // Drawer | ||||||
|     implementation 'com.mikepenz:materialdrawer:8.4.4' |     implementation 'com.mikepenz:materialdrawer:8.4.5' | ||||||
|  |  | ||||||
|     // Themes |     // Themes | ||||||
|     implementation 'com.52inc:scoops:1.0.0' |     implementation 'com.52inc:scoops:1.0.0' | ||||||
| @@ -155,14 +155,15 @@ dependencies { | |||||||
|  |  | ||||||
|     // Pager |     // Pager | ||||||
|     implementation 'me.relex:circleindicator:2.1.6' |     implementation 'me.relex:circleindicator:2.1.6' | ||||||
|  |     implementation "androidx.viewpager2:viewpager2:1.1.0-beta01" | ||||||
|  |  | ||||||
|     //PhotoView |     //PhotoView | ||||||
|     implementation 'com.github.chrisbanes:PhotoView:2.3.0' |     implementation 'com.github.chrisbanes:PhotoView:2.3.0' | ||||||
|  |  | ||||||
|     implementation 'androidx.core:core-ktx:1.7.0-rc01' |     implementation 'androidx.core:core-ktx:1.7.0' | ||||||
|  |  | ||||||
|     implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0-rc01" |     implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0' | ||||||
|     implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0-rc01" |     implementation 'androidx.lifecycle:lifecycle-common-java8:2.4.0' | ||||||
|  |  | ||||||
|     implementation "androidx.room:room-ktx:2.4.0-beta01" |     implementation "androidx.room:room-ktx:2.4.0-beta01" | ||||||
|     kapt "androidx.room:room-compiler:2.4.0-beta01" |     kapt "androidx.room:room-compiler:2.4.0-beta01" | ||||||
|   | |||||||
| @@ -7,23 +7,20 @@ import androidx.test.espresso.Espresso.onView | |||||||
| import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu | import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu | ||||||
| import androidx.test.espresso.action.ViewActions.click | import androidx.test.espresso.action.ViewActions.click | ||||||
| import androidx.test.espresso.action.ViewActions.closeSoftKeyboard | import androidx.test.espresso.action.ViewActions.closeSoftKeyboard | ||||||
| import androidx.test.espresso.action.ViewActions.pressBack |  | ||||||
| import androidx.test.espresso.action.ViewActions.pressKey | import androidx.test.espresso.action.ViewActions.pressKey | ||||||
| import androidx.test.espresso.action.ViewActions.typeText | import androidx.test.espresso.action.ViewActions.typeText | ||||||
| import androidx.test.espresso.assertion.ViewAssertions.matches | import androidx.test.espresso.assertion.ViewAssertions.matches | ||||||
| import androidx.test.espresso.contrib.DrawerActions |  | ||||||
| import androidx.test.espresso.intent.Intents | import androidx.test.espresso.intent.Intents | ||||||
| import androidx.test.espresso.intent.Intents.intended | import androidx.test.espresso.intent.Intents.intended | ||||||
| import androidx.test.espresso.intent.Intents.times |  | ||||||
| import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent | import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent | ||||||
| import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | ||||||
| import androidx.test.espresso.matcher.ViewMatchers.isRoot |  | ||||||
| import androidx.test.espresso.matcher.ViewMatchers.withContentDescription | import androidx.test.espresso.matcher.ViewMatchers.withContentDescription | ||||||
| import androidx.test.espresso.matcher.ViewMatchers.withId | import androidx.test.espresso.matcher.ViewMatchers.withId | ||||||
| import androidx.test.espresso.matcher.ViewMatchers.withText | import androidx.test.espresso.matcher.ViewMatchers.withText | ||||||
| import androidx.test.rule.ActivityTestRule | import androidx.test.rule.ActivityTestRule | ||||||
| import androidx.test.runner.AndroidJUnit4 | import androidx.test.runner.AndroidJUnit4 | ||||||
| import android.view.KeyEvent | import android.view.KeyEvent | ||||||
|  | import androidx.test.espresso.matcher.RootMatchers.isDialog | ||||||
| import apps.amine.bou.readerforselfoss.utils.Config | import apps.amine.bou.readerforselfoss.utils.Config | ||||||
| import org.junit.After | import org.junit.After | ||||||
| import org.junit.Before | import org.junit.Before | ||||||
| @@ -84,11 +81,14 @@ class HomeActivityEspressoTest { | |||||||
|         onView(withMenu(id = R.id.refresh, titleId = R.string.menu_home_refresh)) |         onView(withMenu(id = R.id.refresh, titleId = R.string.menu_home_refresh)) | ||||||
|                 .perform(click()) |                 .perform(click()) | ||||||
|  |  | ||||||
|  |         onView(withText(android.R.string.ok)) | ||||||
|  |             .inRoot(isDialog()).check(matches(isDisplayed())).perform(click()) | ||||||
|  |  | ||||||
|         openActionBarOverflowOrOptionsMenu(context) |         openActionBarOverflowOrOptionsMenu(context) | ||||||
|  |  | ||||||
|         onView(withText(R.string.action_disconnect)).perform(click()) |         onView(withText(R.string.action_disconnect)).perform(click()) | ||||||
|  |  | ||||||
|         intended(hasComponent(LoginActivity::class.java.name), times(1)) |         intended(hasComponent(LoginActivity::class.java.name)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO: test articles opening and actions for cards and lists |     // TODO: test articles opening and actions for cards and lists | ||||||
|   | |||||||
| @@ -85,7 +85,7 @@ class LoginActivityEspressoTest { | |||||||
|  |  | ||||||
|         onView(withId(R.id.signInButton)).perform(click()) |         onView(withId(R.id.signInButton)).perform(click()) | ||||||
|  |  | ||||||
|         onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.urlView)).check(matches(isHintOrErrorEnabled())) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO: Add tests for multiple false urls with dialog |     // TODO: Add tests for multiple false urls with dialog | ||||||
| @@ -101,19 +101,19 @@ class LoginActivityEspressoTest { | |||||||
|  |  | ||||||
|         onView(withId(R.id.signInButton)).perform(click()) |         onView(withId(R.id.signInButton)).perform(click()) | ||||||
|  |  | ||||||
|         onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.loginView)).check(matches(isHintOrErrorEnabled())) | ||||||
|         onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) | ||||||
|  |  | ||||||
|         onView(withId(R.id.loginView)).perform(click()).perform( |         onView(withId(R.id.loginView)).perform(click()).perform( | ||||||
|                 typeText(username), |                 typeText(username), | ||||||
|                 closeSoftKeyboard() |                 closeSoftKeyboard() | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) | ||||||
|  |  | ||||||
|         onView(withId(R.id.signInButton)).perform(click()) |         onView(withId(R.id.signInButton)).perform(click()) | ||||||
|  |  | ||||||
|         onView(withId(R.id.passwordLayout)).check( |         onView(withId(R.id.passwordView)).check( | ||||||
|                 matches( |                 matches( | ||||||
|                         isHintOrErrorEnabled() |                         isHintOrErrorEnabled() | ||||||
|                 ) |                 ) | ||||||
| @@ -141,9 +141,9 @@ class LoginActivityEspressoTest { | |||||||
|  |  | ||||||
|         onView(withId(R.id.signInButton)).perform(click()) |         onView(withId(R.id.signInButton)).perform(click()) | ||||||
|  |  | ||||||
|         onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.urlView)).check(matches(isHintOrErrorEnabled())) | ||||||
|         onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.loginView)).check(matches(isHintOrErrorEnabled())) | ||||||
|         onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled())) |         onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -167,6 +167,7 @@ class LoginActivityEspressoTest { | |||||||
|  |  | ||||||
|         onView(withId(R.id.signInButton)).perform(click()) |         onView(withId(R.id.signInButton)).perform(click()) | ||||||
|  |  | ||||||
|  |         Thread.sleep(2000) | ||||||
|         intended(hasComponent(HomeActivity::class.java.name)) |         intended(hasComponent(HomeActivity::class.java.name)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package apps.amine.bou.readerforselfoss | package apps.amine.bou.readerforselfoss | ||||||
|  |  | ||||||
|  | import android.content.Context | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
| import android.content.SharedPreferences | import android.content.SharedPreferences | ||||||
| import android.preference.PreferenceManager | import android.preference.PreferenceManager | ||||||
| @@ -10,6 +11,7 @@ import androidx.test.espresso.intent.Intents.times | |||||||
| import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent | import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent | ||||||
| import androidx.test.rule.ActivityTestRule | import androidx.test.rule.ActivityTestRule | ||||||
| import androidx.test.runner.AndroidJUnit4 | import androidx.test.runner.AndroidJUnit4 | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.Config | ||||||
| import org.junit.After | import org.junit.After | ||||||
|  |  | ||||||
| import org.junit.Before | import org.junit.Before | ||||||
| @@ -22,6 +24,9 @@ class MainActivityEspressoTest { | |||||||
|  |  | ||||||
|     lateinit var intent: Intent |     lateinit var intent: Intent | ||||||
|     lateinit var preferencesEditor: SharedPreferences.Editor |     lateinit var preferencesEditor: SharedPreferences.Editor | ||||||
|  |     private lateinit var url: String | ||||||
|  |     private lateinit var username: String | ||||||
|  |     private lateinit var password: String | ||||||
|  |  | ||||||
|     @Rule @JvmField |     @Rule @JvmField | ||||||
|     val rule = ActivityTestRule(MainActivity::class.java, true, false) |     val rule = ActivityTestRule(MainActivity::class.java, true, false) | ||||||
| @@ -32,31 +37,39 @@ class MainActivityEspressoTest { | |||||||
|         val context = getInstrumentation().targetContext |         val context = getInstrumentation().targetContext | ||||||
|  |  | ||||||
|         // create a SharedPreferences editor |         // create a SharedPreferences editor | ||||||
|         preferencesEditor = PreferenceManager.getDefaultSharedPreferences(context).edit() |         preferencesEditor = context.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE).edit() | ||||||
|  |  | ||||||
|  |         url = BuildConfig.LOGIN_URL | ||||||
|  |         username = BuildConfig.LOGIN_USERNAME | ||||||
|  |         password = BuildConfig.LOGIN_PASSWORD | ||||||
|  |  | ||||||
|         Intents.init() |         Intents.init() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     fun checkFirstOpenLaunchesIntro() { |     fun checkFirstOpenLaunchesIntro() { | ||||||
|         preferencesEditor.putBoolean("firstStart", true) |         preferencesEditor.putString("url", "") | ||||||
|  |         preferencesEditor.putString("password", "") | ||||||
|  |         preferencesEditor.putString("login", "") | ||||||
|         preferencesEditor.commit() |         preferencesEditor.commit() | ||||||
|  |  | ||||||
|         rule.launchActivity(intent) |         rule.launchActivity(intent) | ||||||
|  |  | ||||||
|         intended(hasComponent(MainActivity::class.java.name)) |         intended(hasComponent(LoginActivity::class.java.name)) | ||||||
|         intended(hasComponent(LoginActivity::class.java.name), times(0)) |         intended(hasComponent(HomeActivity::class.java.name), times(0)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     fun checkNotFirstOpenLaunchesLogin() { |     fun checkNotFirstOpenLaunchesLogin() { | ||||||
|         preferencesEditor.putBoolean("firstStart", false) |         preferencesEditor.putString("url", url) | ||||||
|  |         preferencesEditor.putString("password", password) | ||||||
|  |         preferencesEditor.putString("login", username) | ||||||
|         preferencesEditor.commit() |         preferencesEditor.commit() | ||||||
|  |  | ||||||
|         rule.launchActivity(intent) |         rule.launchActivity(intent) | ||||||
|  |  | ||||||
|         intended(hasComponent(MainActivity::class.java.name)) |         intended(hasComponent(MainActivity::class.java.name)) | ||||||
|         intended(hasComponent(LoginActivity::class.java.name)) |         intended(hasComponent(HomeActivity::class.java.name)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @After |     @After | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| package apps.amine.bou.readerforselfoss | package apps.amine.bou.readerforselfoss | ||||||
|  |  | ||||||
| import com.google.android.material.textfield.TextInputLayout |  | ||||||
| import androidx.test.espresso.matcher.ViewMatchers | import androidx.test.espresso.matcher.ViewMatchers | ||||||
| import android.view.View | import android.view.View | ||||||
|  | import android.widget.EditText | ||||||
| import org.hamcrest.Description | import org.hamcrest.Description | ||||||
| import org.hamcrest.Matcher | import org.hamcrest.Matcher | ||||||
| import org.hamcrest.Matchers | import org.hamcrest.Matchers | ||||||
| @@ -14,11 +14,11 @@ fun isHintOrErrorEnabled(): Matcher<View> = | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             override fun matchesSafely(item: View?): Boolean { |             override fun matchesSafely(item: View?): Boolean { | ||||||
|                 if (item !is TextInputLayout) { |                 if (item !is EditText) { | ||||||
|                     return false |                     return false | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 return item.isHintEnabled || item.isErrorEnabled |                 return item.error.isNotEmpty() | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| package apps.amine.bou.readerforselfoss | package apps.amine.bou.readerforselfoss.utils | ||||||
| 
 | 
 | ||||||
| import apps.amine.bou.readerforselfoss.utils.Config |  | ||||||
| import apps.amine.bou.readerforselfoss.utils.parseDate |  | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| 
 | 
 | ||||||
| class DateUtilsTest { | class DateUtilsTest { | ||||||
| @@ -52,19 +52,19 @@ class AddSourceActivity : AppCompatActivity() { | |||||||
|         scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value) |         scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value) | ||||||
|  |  | ||||||
|         val drawable = binding.nameInput.background |         val drawable = binding.nameInput.background | ||||||
|         drawable.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP) |         drawable.setTint(appColors.colorAccent) | ||||||
|  |  | ||||||
|  |  | ||||||
|         // TODO: clean |         // TODO: clean | ||||||
|         binding.nameInput.background = drawable |         binding.nameInput.background = drawable | ||||||
|  |  | ||||||
|         val drawable1 = binding.sourceUri.background |         val drawable1 = binding.sourceUri.background | ||||||
|         drawable1.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP) |         drawable1.setTint(appColors.colorAccent) | ||||||
|  |  | ||||||
|         binding.sourceUri.background = drawable1 |         binding.sourceUri.background = drawable1 | ||||||
|  |  | ||||||
|         val drawable2 = binding.tags.background |         val drawable2 = binding.tags.background | ||||||
|         drawable2.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP) |         drawable2.setTint(appColors.colorAccent) | ||||||
|  |  | ||||||
|         binding.tags.background = drawable2 |         binding.tags.background = drawable2 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,6 @@ import androidx.appcompat.app.ActionBarDrawerToggle | |||||||
| import androidx.appcompat.app.AlertDialog | import androidx.appcompat.app.AlertDialog | ||||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||||
| import androidx.appcompat.widget.SearchView | import androidx.appcompat.widget.SearchView | ||||||
| import androidx.core.view.MenuItemCompat |  | ||||||
| import androidx.core.view.doOnNextLayout | import androidx.core.view.doOnNextLayout | ||||||
| import androidx.drawerlayout.widget.DrawerLayout | import androidx.drawerlayout.widget.DrawerLayout | ||||||
| import androidx.recyclerview.widget.* | import androidx.recyclerview.widget.* | ||||||
| @@ -100,10 +99,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|     private var displayAllCount = false |     private var displayAllCount = false | ||||||
|     private var fullHeightCards: Boolean = false |     private var fullHeightCards: Boolean = false | ||||||
|     private var itemsNumber: Int = 200 |     private var itemsNumber: Int = 200 | ||||||
|     private var elementsShown: Int = 0 |     private var elementsShown: Int = 1 | ||||||
|     private var maybeTagFilter: Tag? = null |  | ||||||
|     private var maybeSourceFilter: Source? = null |  | ||||||
|     private var maybeSearchFilter: String? = null |  | ||||||
|     private var userIdentifier: String = "" |     private var userIdentifier: String = "" | ||||||
|     private var displayAccountHeader: Boolean = false |     private var displayAccountHeader: Boolean = false | ||||||
|     private var infiniteScroll: Boolean = false |     private var infiniteScroll: Boolean = false | ||||||
| @@ -220,7 +216,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|             lastFetchDone = false |             lastFetchDone = false | ||||||
|             handleDrawerItems() |             handleDrawerItems() | ||||||
|             CoroutineScope(Dispatchers.Main).launch { |             CoroutineScope(Dispatchers.Main).launch { | ||||||
|                 refreshFocusedItems(applicationContext, api, db) |                 refreshFocusedItems(applicationContext, api, db, itemsNumber) | ||||||
|                 getElementsAccordingToTab() |                 getElementsAccordingToTab() | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = false |                 binding.swipeRefreshLayout.isRefreshing = false | ||||||
|             } |             } | ||||||
| @@ -251,7 +247,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                 ): Boolean = false |                 ): Boolean = false | ||||||
|  |  | ||||||
|                 override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) { |                 override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) { | ||||||
|                     val position = viewHolder.adapterPosition |                     val position = viewHolder.bindingAdapterPosition | ||||||
|                     val i = items.elementAtOrNull(position) |                     val i = items.elementAtOrNull(position) | ||||||
|  |  | ||||||
|                     if (i != null) { |                     if (i != null) { | ||||||
| @@ -563,8 +559,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                                         color = ColorHolder.fromColor(appColors.colorAccent) } |                                         color = ColorHolder.fromColor(appColors.colorAccent) } | ||||||
|                                     onDrawerItemClickListener = { _,_,_ -> |                                     onDrawerItemClickListener = { _,_,_ -> | ||||||
|                                         allItems = ArrayList() |                                         allItems = ArrayList() | ||||||
|                                         maybeTagFilter = it |  | ||||||
|                                         SharedItems.tagFilter = it.tag |                                         SharedItems.tagFilter = it.tag | ||||||
|  |                                         SharedItems.sourceFilter = null | ||||||
|  |                                         SharedItems.sourceIDFilter = null | ||||||
|                                         getElementsAccordingToTab() |                                         getElementsAccordingToTab() | ||||||
|                                         fetchOnEmptyList() |                                         fetchOnEmptyList() | ||||||
|                                         false |                                         false | ||||||
| @@ -615,8 +612,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                                     color = ColorHolder.fromColor(appColors.colorAccent) } |                                     color = ColorHolder.fromColor(appColors.colorAccent) } | ||||||
|                                 onDrawerItemClickListener = { _,_,_ -> |                                 onDrawerItemClickListener = { _,_,_ -> | ||||||
|                                     allItems = ArrayList() |                                     allItems = ArrayList() | ||||||
|                                     maybeTagFilter = it |  | ||||||
|                                     SharedItems.tagFilter = it.tag |                                     SharedItems.tagFilter = it.tag | ||||||
|  |                                     SharedItems.sourceFilter = null | ||||||
|  |                                     SharedItems.sourceIDFilter = null | ||||||
|                                     getElementsAccordingToTab() |                                     getElementsAccordingToTab() | ||||||
|                                     fetchOnEmptyList() |                                     fetchOnEmptyList() | ||||||
|                                     false |                                     false | ||||||
| @@ -650,9 +648,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                             iconUrl = source.getIcon(this@HomeActivity) |                             iconUrl = source.getIcon(this@HomeActivity) | ||||||
|                             onDrawerItemClickListener = { _,_,_ -> |                             onDrawerItemClickListener = { _,_,_ -> | ||||||
|                                 allItems = ArrayList() |                                 allItems = ArrayList() | ||||||
|                                 maybeSourceFilter = source |  | ||||||
|                                 SharedItems.sourceIDFilter = source.id.toLong() |                                 SharedItems.sourceIDFilter = source.id.toLong() | ||||||
|                                 SharedItems.sourceFilter = source.title |                                 SharedItems.sourceFilter = source.title | ||||||
|  |                                 SharedItems.tagFilter = null | ||||||
|                                 getElementsAccordingToTab() |                                 getElementsAccordingToTab() | ||||||
|                                 fetchOnEmptyList() |                                 fetchOnEmptyList() | ||||||
|                                 false |                                 false | ||||||
| @@ -673,11 +671,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                         badgeRes = R.string.drawer_action_clear |                         badgeRes = R.string.drawer_action_clear | ||||||
|                         onDrawerItemClickListener = { _,_,_ -> |                         onDrawerItemClickListener = { _,_,_ -> | ||||||
|                             allItems = ArrayList() |                             allItems = ArrayList() | ||||||
|                             maybeSourceFilter = null |  | ||||||
|                             SharedItems.sourceFilter = null |                             SharedItems.sourceFilter = null | ||||||
|                             SharedItems.sourceIDFilter = null |                             SharedItems.sourceIDFilter = null | ||||||
|                             maybeTagFilter = null |  | ||||||
|                             SharedItems.tagFilter = null |                             SharedItems.tagFilter = null | ||||||
|  |                             binding.mainDrawer.setSelectionAtPosition(-1) | ||||||
|                             getElementsAccordingToTab() |                             getElementsAccordingToTab() | ||||||
|                             fetchOnEmptyList() |                             fetchOnEmptyList() | ||||||
|                             false |                             false | ||||||
| @@ -984,7 +981,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|         CoroutineScope(Dispatchers.Main).launch { |         CoroutineScope(Dispatchers.Main).launch { | ||||||
|             if (appendResults || !SharedItems.fetchedUnread) { |             if (appendResults || !SharedItems.fetchedUnread) { | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = true |                 binding.swipeRefreshLayout.isRefreshing = true | ||||||
|                 getUnreadItems(applicationContext, api, db, offset) |                 getUnreadItems(applicationContext, api, db, itemsNumber, offset) | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = false |                 binding.swipeRefreshLayout.isRefreshing = false | ||||||
|             } |             } | ||||||
|             SharedItems.getUnRead() |             SharedItems.getUnRead() | ||||||
| @@ -997,7 +994,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|         CoroutineScope(Dispatchers.Main).launch { |         CoroutineScope(Dispatchers.Main).launch { | ||||||
|             if (appendResults || !SharedItems.fetchedAll) { |             if (appendResults || !SharedItems.fetchedAll) { | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = true |                 binding.swipeRefreshLayout.isRefreshing = true | ||||||
|                 getReadItems(applicationContext, api, db, offset) |                 getReadItems(applicationContext, api, db, itemsNumber, offset) | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = false |                 binding.swipeRefreshLayout.isRefreshing = false | ||||||
|             } |             } | ||||||
|             SharedItems.getAll() |             SharedItems.getAll() | ||||||
| @@ -1010,7 +1007,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|         CoroutineScope(Dispatchers.Main).launch { |         CoroutineScope(Dispatchers.Main).launch { | ||||||
|             if (appendResults || !SharedItems.fetchedStarred) { |             if (appendResults || !SharedItems.fetchedStarred) { | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = true |                 binding.swipeRefreshLayout.isRefreshing = true | ||||||
|                 getStarredItems(applicationContext, api, db, offset) |                 getStarredItems(applicationContext, api, db, itemsNumber, offset) | ||||||
|                 binding.swipeRefreshLayout.isRefreshing = false |                 binding.swipeRefreshLayout.isRefreshing = false | ||||||
|             } |             } | ||||||
|             SharedItems.getStarred() |             SharedItems.getStarred() | ||||||
| @@ -1122,7 +1119,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|  |  | ||||||
|     override fun onQueryTextChange(p0: String?): Boolean { |     override fun onQueryTextChange(p0: String?): Boolean { | ||||||
|         if (p0.isNullOrBlank()) { |         if (p0.isNullOrBlank()) { | ||||||
|             maybeSearchFilter = null |  | ||||||
|             SharedItems.searchFilter = null |             SharedItems.searchFilter = null | ||||||
|             getElementsAccordingToTab() |             getElementsAccordingToTab() | ||||||
|             fetchOnEmptyList() |             fetchOnEmptyList() | ||||||
| @@ -1131,29 +1127,18 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onQueryTextSubmit(p0: String?): Boolean { |     override fun onQueryTextSubmit(p0: String?): Boolean { | ||||||
|         maybeSearchFilter = p0 |  | ||||||
|         SharedItems.searchFilter = p0 |         SharedItems.searchFilter = p0 | ||||||
|         getElementsAccordingToTab() |         getElementsAccordingToTab() | ||||||
|         fetchOnEmptyList() |         fetchOnEmptyList() | ||||||
|         return false |         return false | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onActivityResult(req: Int, result: Int, data: Intent?) { |  | ||||||
|         when (req) { |  | ||||||
|             MENU_PREFERENCES -> { |  | ||||||
|                 //drawer.closeDrawer() |  | ||||||
|                 recreate() |  | ||||||
|             } |  | ||||||
|             else -> super.onActivityResult(req, result, data) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override fun onCreateOptionsMenu(menu: Menu): Boolean { |     override fun onCreateOptionsMenu(menu: Menu): Boolean { | ||||||
|         val inflater = menuInflater |         val inflater = menuInflater | ||||||
|         inflater.inflate(R.menu.home_menu, menu) |         inflater.inflate(R.menu.home_menu, menu) | ||||||
|  |  | ||||||
|         val searchItem = menu.findItem(R.id.action_search) |         val searchItem = menu.findItem(R.id.action_search) | ||||||
|         val searchView = MenuItemCompat.getActionView(searchItem) as SearchView |         val searchView = searchItem.getActionView() as SearchView | ||||||
|         searchView.setOnQueryTextListener(this) |         searchView.setOnQueryTextListener(this) | ||||||
|  |  | ||||||
|         return true |         return true | ||||||
| @@ -1268,8 +1253,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                     .addTag("selfoss-loading") |                     .addTag("selfoss-loading") | ||||||
|                     .build() |                     .build() | ||||||
|  |  | ||||||
|  |             WorkManager.getInstance(baseContext).enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork) | ||||||
|             WorkManager.getInstance().enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork) |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,8 +3,9 @@ package apps.amine.bou.readerforselfoss | |||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.view.MenuItem | import android.view.MenuItem | ||||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||||
| import androidx.fragment.app.FragmentManager | import androidx.fragment.app.Fragment | ||||||
| import androidx.fragment.app.FragmentStatePagerAdapter | import androidx.fragment.app.FragmentActivity | ||||||
|  | import androidx.viewpager2.adapter.FragmentStateAdapter | ||||||
| import apps.amine.bou.readerforselfoss.databinding.ActivityImageBinding | import apps.amine.bou.readerforselfoss.databinding.ActivityImageBinding | ||||||
| import apps.amine.bou.readerforselfoss.fragments.ImageFragment | import apps.amine.bou.readerforselfoss.fragments.ImageFragment | ||||||
|  |  | ||||||
| @@ -28,8 +29,8 @@ class ImageActivity : AppCompatActivity() { | |||||||
|         allImages = intent.getStringArrayListExtra("allImages") as ArrayList<String> |         allImages = intent.getStringArrayListExtra("allImages") as ArrayList<String> | ||||||
|         position = intent.getIntExtra("position", 0) |         position = intent.getIntExtra("position", 0) | ||||||
|  |  | ||||||
|         binding.pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager) |         binding.pager.adapter = ScreenSlidePagerAdapter(this) | ||||||
|         binding.pager.currentItem = position |         binding.pager.setCurrentItem(position, false) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onOptionsItemSelected(item: MenuItem): Boolean { |     override fun onOptionsItemSelected(item: MenuItem): Boolean { | ||||||
| @@ -43,14 +44,10 @@ class ImageActivity : AppCompatActivity() { | |||||||
|         return super.onOptionsItemSelected(item) |         return super.onOptionsItemSelected(item) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { |     private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { | ||||||
|  |  | ||||||
|         override fun getCount(): Int { |         override fun getItemCount(): Int = allImages.size | ||||||
|             return allImages.size |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         override fun getItem(position: Int): ImageFragment { |         override fun createFragment(position: Int): Fragment = ImageFragment.newInstance(allImages[position]) | ||||||
|             return ImageFragment.newInstance(allImages[position]) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -14,11 +14,11 @@ import android.view.MenuItem | |||||||
| import android.view.View | import android.view.View | ||||||
| import android.view.inputmethod.EditorInfo | import android.view.inputmethod.EditorInfo | ||||||
| import android.widget.TextView | import android.widget.TextView | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| 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.databinding.ActivityLoginBinding | import apps.amine.bou.readerforselfoss.databinding.ActivityLoginBinding | ||||||
| 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.isBaseUrlValid | import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid | ||||||
| import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible | import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible | ||||||
| import com.mikepenz.aboutlibraries.LibsBuilder | import com.mikepenz.aboutlibraries.LibsBuilder | ||||||
| @@ -52,7 +52,7 @@ class LoginActivity : AppCompatActivity() { | |||||||
|  |  | ||||||
|         handleBaseUrlFail() |         handleBaseUrlFail() | ||||||
|  |  | ||||||
|         settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) |         settings = PreferenceManager.getDefaultSharedPreferences(applicationContext) | ||||||
|         userIdentifier = settings.getString("unique_id", "")!! |         userIdentifier = settings.getString("unique_id", "")!! | ||||||
|  |  | ||||||
|         editor = settings.edit() |         editor = settings.edit() | ||||||
|   | |||||||
| @@ -61,14 +61,14 @@ class MyApp : MultiDexApplication() { | |||||||
|     private fun initDrawerImageLoader() { |     private fun initDrawerImageLoader() { | ||||||
|         DrawerImageLoader.init(object : AbstractDrawerImageLoader() { |         DrawerImageLoader.init(object : AbstractDrawerImageLoader() { | ||||||
|             override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) { |             override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) { | ||||||
|                 Glide.with(imageView?.context) |                 Glide.with(imageView.context) | ||||||
|                     .loadMaybeBasicAuth(config, uri.toString()) |                     .loadMaybeBasicAuth(config, uri.toString()) | ||||||
|                     .apply(RequestOptions.fitCenterTransform().placeholder(placeholder)) |                     .apply(RequestOptions.fitCenterTransform().placeholder(placeholder)) | ||||||
|                     .into(imageView) |                     .into(imageView) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             override fun cancel(imageView: ImageView) { |             override fun cancel(imageView: ImageView) { | ||||||
|                 Glide.with(imageView?.context).clear(imageView) |                 Glide.with(imageView.context).clear(imageView) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             override fun placeholder(ctx: Context, tag: String?): Drawable { |             override fun placeholder(ctx: Context, tag: String?): Drawable { | ||||||
|   | |||||||
| @@ -3,21 +3,17 @@ package apps.amine.bou.readerforselfoss | |||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.SharedPreferences | import android.content.SharedPreferences | ||||||
| import android.graphics.Color | import android.graphics.Color | ||||||
| import android.graphics.PorterDuff |  | ||||||
| import android.graphics.PorterDuffColorFilter |  | ||||||
| import android.graphics.drawable.ColorDrawable |  | ||||||
| import android.os.Build |  | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
|  | import android.view.KeyEvent | ||||||
| import androidx.preference.PreferenceManager | import androidx.preference.PreferenceManager | ||||||
| import androidx.fragment.app.FragmentManager |  | ||||||
| import androidx.fragment.app.FragmentStatePagerAdapter |  | ||||||
| import androidx.core.content.ContextCompat |  | ||||||
| import androidx.viewpager.widget.ViewPager |  | ||||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||||
| import android.view.Menu | import android.view.Menu | ||||||
| import android.view.MenuItem | import android.view.MenuItem | ||||||
| import android.view.ViewGroup | import androidx.fragment.app.Fragment | ||||||
|  | import androidx.fragment.app.FragmentActivity | ||||||
| import androidx.room.Room | import androidx.room.Room | ||||||
|  | import androidx.viewpager2.adapter.FragmentStateAdapter | ||||||
|  | import androidx.viewpager2.widget.ViewPager2 | ||||||
| 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.databinding.ActivityReaderBinding | import apps.amine.bou.readerforselfoss.databinding.ActivityReaderBinding | ||||||
| @@ -28,18 +24,17 @@ 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.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.utils.Config | import apps.amine.bou.readerforselfoss.utils.Config | ||||||
| import apps.amine.bou.readerforselfoss.utils.SharedItems | import apps.amine.bou.readerforselfoss.utils.SharedItems | ||||||
| import apps.amine.bou.readerforselfoss.utils.toggleStar | import apps.amine.bou.readerforselfoss.utils.toggleStar | ||||||
| import com.ftinc.scoop.Scoop | import com.ftinc.scoop.Scoop | ||||||
| import me.relex.circleindicator.CircleIndicator |  | ||||||
|  |  | ||||||
| class ReaderActivity : AppCompatActivity() { | class ReaderActivity : AppCompatActivity() { | ||||||
|  |  | ||||||
|     private var markOnScroll: Boolean = false |     private var markOnScroll: Boolean = false | ||||||
|     private var currentItem: Int = 0 |     private var currentItem: Int = 0 | ||||||
|     private lateinit var userIdentifier: String |     private lateinit var userIdentifier: String | ||||||
|  |     private lateinit var appColors: AppColors | ||||||
|  |  | ||||||
|     private lateinit var api: SelfossApi |     private lateinit var api: SelfossApi | ||||||
|  |  | ||||||
| @@ -50,14 +45,14 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|     private lateinit var binding: ActivityReaderBinding |     private lateinit var binding: ActivityReaderBinding | ||||||
|  |  | ||||||
|     private var activeAlignment: Int = 1 |     private var activeAlignment: Int = 1 | ||||||
|     val JUSTIFY = 1 |     private val JUSTIFY = 1 | ||||||
|     val ALIGN_LEFT = 2 |     private val ALIGN_LEFT = 2 | ||||||
|  |  | ||||||
|     private fun showMenuItem(willAddToFavorite: Boolean) { |     private fun showMenuItem(willAddToFavorite: Boolean) { | ||||||
|         if (willAddToFavorite) { |         if (willAddToFavorite) { | ||||||
|             toolbarMenu.findItem(R.id.star).icon.colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP) |             toolbarMenu.findItem(R.id.star).icon.setTint(Color.WHITE) | ||||||
|         } else { |         } else { | ||||||
|             toolbarMenu.findItem(R.id.star).icon.colorFilter = PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP) |             toolbarMenu.findItem(R.id.star).icon.setTint(Color.RED) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -73,6 +68,7 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|  |  | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|  |         appColors = AppColors(this) | ||||||
|         binding = ActivityReaderBinding.inflate(layoutInflater) |         binding = ActivityReaderBinding.inflate(layoutInflater) | ||||||
|         val view = binding.root |         val view = binding.root | ||||||
|  |  | ||||||
| @@ -116,33 +112,14 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|  |  | ||||||
|         readItem(allItems[currentItem]) |         readItem(allItems[currentItem]) | ||||||
|  |  | ||||||
|         binding.pager.adapter = |         binding.pager.adapter = ScreenSlidePagerAdapter(this) | ||||||
|                 ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) |         binding.pager.setCurrentItem(currentItem, false) | ||||||
|         binding.pager.currentItem = currentItem |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onResume() { |     override fun onResume() { | ||||||
|         super.onResume() |         super.onResume() | ||||||
|  |  | ||||||
|         notifyAdapter() |         binding.indicator.setViewPager(binding.pager) | ||||||
|  |  | ||||||
|         binding.pager.setPageTransformer(true, DepthPageTransformer()) |  | ||||||
|         (binding.indicator as CircleIndicator).setViewPager(binding.pager) |  | ||||||
|  |  | ||||||
|         binding.pager.addOnPageChangeListener( |  | ||||||
|             object : ViewPager.SimpleOnPageChangeListener() { |  | ||||||
|  |  | ||||||
|                 override fun onPageSelected(position: Int) { |  | ||||||
|  |  | ||||||
|                     if (allItems[position].starred) { |  | ||||||
|                         canRemoveFromFavorite() |  | ||||||
|                     } else { |  | ||||||
|                         canFavorite() |  | ||||||
|                     } |  | ||||||
|                     readItem(allItems[position]) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun readItem(item: Item) { |     private fun readItem(item: Item) { | ||||||
| @@ -151,46 +128,39 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|             } |             } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun notifyAdapter() { |  | ||||||
|         (binding.pager.adapter as ScreenSlidePagerAdapter).notifyDataSetChanged() |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override fun onPause() { |  | ||||||
|         super.onPause() |  | ||||||
|         if (markOnScroll) { |  | ||||||
|             binding.pager.clearOnPageChangeListeners() |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override fun onSaveInstanceState(oldInstanceState: Bundle) { |     override fun onSaveInstanceState(oldInstanceState: Bundle) { | ||||||
|         super.onSaveInstanceState(oldInstanceState) |         super.onSaveInstanceState(oldInstanceState) | ||||||
|         oldInstanceState.clear() |         oldInstanceState.clear() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private inner class ScreenSlidePagerAdapter(fm: FragmentManager, val appColors: AppColors) : |     private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : | ||||||
|         FragmentStatePagerAdapter(fm) { |         FragmentStateAdapter(fa) { | ||||||
|  |  | ||||||
|         override fun getCount(): Int { |         override fun getItemCount(): Int = allItems.size | ||||||
|             return allItems.size |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         override fun getItem(position: Int): ArticleFragment { |         override fun createFragment(position: Int): Fragment = ArticleFragment.newInstance(allItems[position]) | ||||||
|             return ArticleFragment.newInstance(position, allItems) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         override fun startUpdate(container: ViewGroup) { |     } | ||||||
|             super.startUpdate(container) |  | ||||||
|  |  | ||||||
|             container.background = ColorDrawable( |     override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { | ||||||
|                 ContextCompat.getColor( |         return when (keyCode) { | ||||||
|                     this@ReaderActivity, |             KeyEvent.KEYCODE_VOLUME_DOWN -> { | ||||||
|                     appColors.colorBackground |                 val currentFragment = supportFragmentManager.findFragmentByTag("f" + binding.pager.currentItem) as ArticleFragment | ||||||
|                 ) |                 currentFragment.scrollDown() | ||||||
|             ) |                 true | ||||||
|  |             } | ||||||
|  |             KeyEvent.KEYCODE_VOLUME_UP -> { | ||||||
|  |                 val currentFragment = supportFragmentManager.findFragmentByTag("f" + binding.pager.currentItem) as ArticleFragment | ||||||
|  |                 currentFragment.scrollUp() | ||||||
|  |                 true | ||||||
|  |             } | ||||||
|  |             else -> { | ||||||
|  |                 super.onKeyDown(keyCode, event) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun alignmentMenu(showJustify: Boolean) { |     private fun alignmentMenu(showJustify: Boolean) { | ||||||
|         toolbarMenu.findItem(R.id.align_left).isVisible = !showJustify |         toolbarMenu.findItem(R.id.align_left).isVisible = !showJustify | ||||||
|         toolbarMenu.findItem(R.id.align_justify).isVisible = showJustify |         toolbarMenu.findItem(R.id.align_justify).isVisible = showJustify | ||||||
|     } |     } | ||||||
| @@ -200,7 +170,7 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|         inflater.inflate(R.menu.reader_menu, menu) |         inflater.inflate(R.menu.reader_menu, menu) | ||||||
|         toolbarMenu = menu |         toolbarMenu = menu | ||||||
|  |  | ||||||
|         if (!allItems.isEmpty() && allItems[currentItem].starred) { |         if (allItems.isNotEmpty() && allItems[currentItem].starred) { | ||||||
|             canRemoveFromFavorite() |             canRemoveFromFavorite() | ||||||
|         } else { |         } else { | ||||||
|             canFavorite() |             canFavorite() | ||||||
| @@ -211,6 +181,22 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|             alignmentMenu(true) |             alignmentMenu(true) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         binding.pager.registerOnPageChangeCallback( | ||||||
|  |                 object : ViewPager2.OnPageChangeCallback() { | ||||||
|  |  | ||||||
|  |                     override fun onPageSelected(position: Int) { | ||||||
|  |                         super.onPageSelected(position) | ||||||
|  |  | ||||||
|  |                         if (allItems[position].starred) { | ||||||
|  |                             canRemoveFromFavorite() | ||||||
|  |                         } else { | ||||||
|  |                             canFavorite() | ||||||
|  |                         } | ||||||
|  |                         readItem(allItems[position]) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |         ) | ||||||
|  |  | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -218,13 +204,11 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|         fun afterSave() { |         fun afterSave() { | ||||||
|             allItems[binding.pager.currentItem] = |             allItems[binding.pager.currentItem] = | ||||||
|                     allItems[binding.pager.currentItem].toggleStar() |                     allItems[binding.pager.currentItem].toggleStar() | ||||||
|             notifyAdapter() |  | ||||||
|             canRemoveFromFavorite() |             canRemoveFromFavorite() | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         fun afterUnsave() { |         fun afterUnsave() { | ||||||
|             allItems[binding.pager.currentItem] = allItems[binding.pager.currentItem].toggleStar() |             allItems[binding.pager.currentItem] = allItems[binding.pager.currentItem].toggleStar() | ||||||
|             notifyAdapter() |  | ||||||
|             canFavorite() |             canFavorite() | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,14 +28,14 @@ class SourcesActivity : AppCompatActivity() { | |||||||
|  |  | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         appColors = AppColors(this@SourcesActivity) |         appColors = AppColors(this@SourcesActivity) | ||||||
|  |         binding = ActivitySourcesBinding.inflate(layoutInflater) | ||||||
|  |         val view = binding.root | ||||||
|  |  | ||||||
|         val scoop = Scoop.getInstance() |         val scoop = Scoop.getInstance() | ||||||
|         scoop.bind(this, Toppings.PRIMARY.value, binding.toolbar) |         scoop.bind(this, Toppings.PRIMARY.value, binding.toolbar) | ||||||
|         scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value) |         scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value) | ||||||
|  |  | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|         binding = ActivitySourcesBinding.inflate(layoutInflater) |  | ||||||
|         val view = binding.root |  | ||||||
|  |  | ||||||
|         setContentView(view) |         setContentView(view) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,13 +39,13 @@ suspend fun updateItems(context: Context, api: SelfossApi, db: AppDatabase) = co | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDatabase) = withContext(Dispatchers.IO) { | suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int) = withContext(Dispatchers.IO) { | ||||||
|     if (isNetworkAvailable(context)) { |     if (isNetworkAvailable(context)) { | ||||||
|         val response = when (SharedItems.displayedItems) { |         val response = when (SharedItems.displayedItems) { | ||||||
|             "read" -> api.readItems(200, 0) |             "read" -> api.readItems(itemsNumber, 0) | ||||||
|             "unread" -> api.newItems(200, 0) |             "unread" -> api.newItems(itemsNumber, 0) | ||||||
|             "starred" -> api.starredItems(200, 0) |             "starred" -> api.starredItems(itemsNumber, 0) | ||||||
|             else -> api.readItems(200, 0) |             else -> api.readItems(itemsNumber, 0) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (response.isSuccessful) { |         if (response.isSuccessful) { | ||||||
| @@ -55,33 +55,33 @@ suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDataba | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend fun getReadItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) { | suspend fun getReadItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) { | ||||||
|     if (isNetworkAvailable(context)) { |     if (isNetworkAvailable(context)) { | ||||||
|             try { |             try { | ||||||
|                 enqueueArticles(api.readItems( 200, offset), db, false) |                 enqueueArticles(api.readItems( itemsNumber, offset), db, false) | ||||||
|                 SharedItems.fetchedAll = true |                 SharedItems.fetchedAll = true | ||||||
|                 SharedItems.updateDatabase(db) |                 SharedItems.updateDatabase(db) | ||||||
|             } catch (e: Throwable) {} |             } catch (e: Throwable) {} | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend fun getUnreadItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) { | suspend fun getUnreadItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) { | ||||||
|     if (isNetworkAvailable(context)) { |     if (isNetworkAvailable(context)) { | ||||||
|         try { |         try { | ||||||
|             if (!SharedItems.fetchedUnread) { |             if (!SharedItems.fetchedUnread) { | ||||||
|                 SharedItems.clearDBItems(db) |                 SharedItems.clearDBItems(db) | ||||||
|             } |             } | ||||||
|             enqueueArticles(api.newItems(200, offset), db, false) |             enqueueArticles(api.newItems(itemsNumber, offset), db, false) | ||||||
|             SharedItems.fetchedUnread = true |             SharedItems.fetchedUnread = true | ||||||
|         } catch (e: Throwable) {} |         } catch (e: Throwable) {} | ||||||
|     } |     } | ||||||
|     SharedItems.updateDatabase(db) |     SharedItems.updateDatabase(db) | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend fun getStarredItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) { | suspend fun getStarredItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) { | ||||||
|     if (isNetworkAvailable(context)) { |     if (isNetworkAvailable(context)) { | ||||||
|         try { |         try { | ||||||
|             enqueueArticles(api.starredItems(200, offset), db, false) |             enqueueArticles(api.starredItems(itemsNumber, offset), db, false) | ||||||
|             SharedItems.fetchedStarred = true |             SharedItems.fetchedStarred = true | ||||||
|             SharedItems.updateDatabase(db) |             SharedItems.updateDatabase(db) | ||||||
|         } catch (e: Throwable) { |         } catch (e: Throwable) { | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ import com.bumptech.glide.Glide | |||||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | import com.bumptech.glide.load.engine.DiskCacheStrategy | ||||||
| import com.bumptech.glide.request.RequestOptions | import com.bumptech.glide.request.RequestOptions | ||||||
| import com.google.gson.annotations.SerializedName | import com.google.gson.annotations.SerializedName | ||||||
|  | import java.util.* | ||||||
|  | import kotlin.collections.ArrayList | ||||||
|  |  | ||||||
| private fun constructUrl(config: Config?, path: String, file: String?): String { | private fun constructUrl(config: Config?, path: String, file: String?): String { | ||||||
|     return if (file.isEmptyOrNullOrNullString()) { |     return if (file.isEmptyOrNullOrNullString()) { | ||||||
| @@ -155,14 +157,14 @@ data class Item( | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun getImages() : ArrayList<String> { |     fun getImages() : ArrayList<String> { | ||||||
|         var allImages = ArrayList<String>() |         val allImages = ArrayList<String>() | ||||||
|  |  | ||||||
|         for ( image in Jsoup.parse(content).getElementsByTag("img")) { |         for ( image in Jsoup.parse(content).getElementsByTag("img")) { | ||||||
|             val url = image.attr("src") |             val url = image.attr("src") | ||||||
|             if (url.toLowerCase().contains(".jpg") || |             if (url.lowercase(Locale.US).contains(".jpg") || | ||||||
|                     url.toLowerCase().contains(".jpeg") || |                     url.lowercase(Locale.US).contains(".jpeg") || | ||||||
|                     url.toLowerCase().contains(".png") || |                     url.lowercase(Locale.US).contains(".png") || | ||||||
|                     url.toLowerCase().contains(".webp")) |                     url.lowercase(Locale.US).contains(".webp")) | ||||||
|             { |             { | ||||||
|                 allImages.add(url) |                 allImages.add(url) | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -14,12 +14,11 @@ import androidx.preference.PreferenceManager | |||||||
| import android.view.* | import android.view.* | ||||||
| import android.webkit.* | import android.webkit.* | ||||||
| import android.widget.Toast | import android.widget.Toast | ||||||
| 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.widget.NestedScrollView | import androidx.core.widget.NestedScrollView | ||||||
| import androidx.appcompat.app.AlertDialog | import androidx.appcompat.app.AlertDialog | ||||||
|  | import androidx.browser.customtabs.CustomTabsIntent | ||||||
| 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.ImageActivity | ||||||
| @@ -48,14 +47,14 @@ 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.* | ||||||
| import java.util.concurrent.ExecutionException | import java.util.concurrent.ExecutionException | ||||||
| import kotlin.collections.ArrayList | import kotlin.collections.ArrayList | ||||||
|  |  | ||||||
| class ArticleFragment : Fragment() { | class ArticleFragment : Fragment() { | ||||||
|     private lateinit var pageNumber: Number |  | ||||||
|     private var fontSize: Int = 16 |     private var fontSize: Int = 16 | ||||||
|     private lateinit var allItems: ArrayList<Item> |     private lateinit var item: Item | ||||||
|     private var mCustomTabActivityHelper: CustomTabActivityHelper? = null; |     private var mCustomTabActivityHelper: CustomTabActivityHelper? = null | ||||||
|     private lateinit var url: String |     private lateinit var url: String | ||||||
|     private lateinit var contentText: String |     private lateinit var contentText: String | ||||||
|     private lateinit var contentSource: String |     private lateinit var contentSource: String | ||||||
| @@ -91,8 +90,7 @@ class ArticleFragment : Fragment() { | |||||||
|  |  | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|  |  | ||||||
|         pageNumber = requireArguments().getInt(ARG_POSITION) |         item = requireArguments().getParcelable(ARG_ITEMS)!! | ||||||
|         allItems = requireArguments().getParcelableArrayList<Item>(ARG_ITEMS) as ArrayList<Item> |  | ||||||
|  |  | ||||||
|         db = Room.databaseBuilder( |         db = Room.databaseBuilder( | ||||||
|             requireContext(), |             requireContext(), | ||||||
| @@ -104,16 +102,16 @@ class ArticleFragment : Fragment() { | |||||||
|         inflater: LayoutInflater, |         inflater: LayoutInflater, | ||||||
|         container: ViewGroup?, |         container: ViewGroup?, | ||||||
|         savedInstanceState: Bundle? |         savedInstanceState: Bundle? | ||||||
|     ): View? { |     ): View { | ||||||
|         try { |         try { | ||||||
|             _binding = FragmentArticleBinding.inflate(inflater, container, false) |             _binding = FragmentArticleBinding.inflate(inflater, container, false) | ||||||
|  |  | ||||||
|             url = allItems[pageNumber.toInt()].getLinkDecoded() |             url = item.getLinkDecoded() | ||||||
|             contentText = allItems[pageNumber.toInt()].content |             contentText = item.content | ||||||
|             contentTitle = allItems[pageNumber.toInt()].getTitleDecoded() |             contentTitle = item.getTitleDecoded() | ||||||
|             contentImage = allItems[pageNumber.toInt()].getThumbnail(requireActivity()) |             contentImage = item.getThumbnail(requireActivity()) | ||||||
|             contentSource = allItems[pageNumber.toInt()].sourceAndDateText() |             contentSource = item.sourceAndDateText() | ||||||
|             allImages = allItems[pageNumber.toInt()].getImages() |             allImages = item.getImages() | ||||||
|  |  | ||||||
|             prefs = PreferenceManager.getDefaultSharedPreferences(activity) |             prefs = PreferenceManager.getDefaultSharedPreferences(activity) | ||||||
|             editor = prefs.edit() |             editor = prefs.edit() | ||||||
| @@ -163,26 +161,18 @@ class ArticleFragment : Fragment() { | |||||||
|                 object : FloatingToolbar.ItemClickListener { |                 object : FloatingToolbar.ItemClickListener { | ||||||
|                     override fun onItemClick(item: MenuItem) { |                     override fun onItemClick(item: MenuItem) { | ||||||
|                         when (item.itemId) { |                         when (item.itemId) { | ||||||
|                             R.id.more_action -> getContentFromMercury(customTabsIntent, prefs) |                             R.id.more_action -> getContentFromMercury(customTabsIntent) | ||||||
|                             R.id.share_action -> requireActivity().shareLink(url, contentTitle) |                             R.id.share_action -> requireActivity().shareLink(url, contentTitle) | ||||||
|                             R.id.open_action -> requireActivity().openItemUrl( |                             R.id.open_action -> requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item) | ||||||
|                                 allItems, |  | ||||||
|                                 pageNumber.toInt(), |  | ||||||
|                                 url, |  | ||||||
|                                 customTabsIntent, |  | ||||||
|                                 false, |  | ||||||
|                                 false, |  | ||||||
|                                 requireActivity() |  | ||||||
|                             ) |  | ||||||
|                             R.id.unread_action -> if (context != null) { |                             R.id.unread_action -> if (context != null) { | ||||||
|                                 if (allItems[pageNumber.toInt()].unread) { |                                 if (this@ArticleFragment.item.unread) { | ||||||
|                                     SharedItems.readItem( |                                     SharedItems.readItem( | ||||||
|                                         context!!, |                                         context!!, | ||||||
|                                         api, |                                         api, | ||||||
|                                         db, |                                         db, | ||||||
|                                         allItems[pageNumber.toInt()] |                                             this@ArticleFragment.item | ||||||
|                                     ) |                                     ) | ||||||
|                                     allItems[pageNumber.toInt()].unread = false |                                     this@ArticleFragment.item.unread = false | ||||||
|                                     Toast.makeText( |                                     Toast.makeText( | ||||||
|                                         context, |                                         context, | ||||||
|                                         R.string.marked_as_read, |                                         R.string.marked_as_read, | ||||||
| @@ -193,9 +183,9 @@ class ArticleFragment : Fragment() { | |||||||
|                                         context!!, |                                         context!!, | ||||||
|                                         api, |                                         api, | ||||||
|                                         db, |                                         db, | ||||||
|                                         allItems[pageNumber.toInt()] |                                             this@ArticleFragment.item | ||||||
|                                     ) |                                     ) | ||||||
|                                     allItems[pageNumber.toInt()].unread = true |                                     this@ArticleFragment.item.unread = true | ||||||
|                                     Toast.makeText( |                                     Toast.makeText( | ||||||
|                                         context, |                                         context, | ||||||
|                                         R.string.marked_as_unread, |                                         R.string.marked_as_unread, | ||||||
| @@ -223,7 +213,7 @@ class ArticleFragment : Fragment() { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (contentText.isEmptyOrNullOrNullString()) { |             if (contentText.isEmptyOrNullOrNullString()) { | ||||||
|                 getContentFromMercury(customTabsIntent, prefs) |                 getContentFromMercury(customTabsIntent) | ||||||
|             } else { |             } else { | ||||||
|                 binding.titleView.text = contentTitle |                 binding.titleView.text = contentTitle | ||||||
|                 if (typeface != null) { |                 if (typeface != null) { | ||||||
| @@ -265,11 +255,11 @@ class ArticleFragment : Fragment() { | |||||||
|                 .setMessage(requireContext().getString(R.string.webview_dialog_issue_message)) |                 .setMessage(requireContext().getString(R.string.webview_dialog_issue_message)) | ||||||
|                 .setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) |                 .setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) | ||||||
|                 .setPositiveButton(android.R.string.ok |                 .setPositiveButton(android.R.string.ok | ||||||
|                 ) { dialog, which -> |                 ) { _, _ -> | ||||||
|                     val sharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext()) |                     val sharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|                     val editor = sharedPref.edit() |                     val editor = sharedPref.edit() | ||||||
|                     editor.putBoolean("prefer_article_viewer", false) |                     editor.putBoolean("prefer_article_viewer", false) | ||||||
|                     editor.commit() |                     editor.apply() | ||||||
|                     requireActivity().finish() |                     requireActivity().finish() | ||||||
|                 } |                 } | ||||||
|                 .create() |                 .create() | ||||||
| @@ -292,10 +282,7 @@ class ArticleFragment : Fragment() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun getContentFromMercury( |     private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) { | ||||||
|         customTabsIntent: CustomTabsIntent, |  | ||||||
|         prefs: SharedPreferences |  | ||||||
|     ) { |  | ||||||
|         if ((context != null && requireContext().isNetworkAccessible(null)) || context == null) { |         if ((context != null && requireContext().isNetworkAccessible(null)) || context == null) { | ||||||
|             binding.progressBar.visibility = View.VISIBLE |             binding.progressBar.visibility = View.VISIBLE | ||||||
|             val parser = MercuryApi() |             val parser = MercuryApi() | ||||||
| @@ -390,30 +377,12 @@ class ArticleFragment : Fragment() { | |||||||
|  |  | ||||||
|         binding.webcontent.settings.standardFontFamily = a.getString(0) |         binding.webcontent.settings.standardFontFamily = a.getString(0) | ||||||
|         binding.webcontent.visibility = View.VISIBLE |         binding.webcontent.visibility = View.VISIBLE | ||||||
|         val (textColor, backgroundColor) = if (appColors.isDarkTheme) { |  | ||||||
|             if (context != null) { |  | ||||||
|                 Pair(ContextCompat.getColor(requireContext(), R.color.dark_webview_text), ContextCompat.getColor(requireContext(), R.color.dark_webview)) |  | ||||||
|             } else { |  | ||||||
|                 Pair(null, null) |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             if (context != null) { |  | ||||||
|                 Pair(ContextCompat.getColor(requireContext(), R.color.light_webview_text), ContextCompat.getColor(requireContext(), R.color.light_webview)) |  | ||||||
|             } else { |  | ||||||
|                 Pair(null, null) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         val stringTextColor: String = if (textColor != null) { |         // TODO: Set the color strings programmatically | ||||||
|             String.format("#%06X", 0xFFFFFF and textColor) |         val (stringTextColor, stringBackgroundColor) = if (appColors.isDarkTheme) { | ||||||
|  |             Pair("#FFFFFF", "#303030") | ||||||
|         } else { |         } else { | ||||||
|             "#000000" |             Pair("#212121", "#FAFAFA") | ||||||
|         } |  | ||||||
|  |  | ||||||
|         val stringBackgroundColor = if (backgroundColor != null) { |  | ||||||
|             String.format("#%06X", 0xFFFFFF and backgroundColor) |  | ||||||
|         } else { |  | ||||||
|             "#FFFFFF" |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         binding.webcontent.settings.useWideViewPort = true |         binding.webcontent.settings.useWideViewPort = true | ||||||
| @@ -430,19 +399,19 @@ class ArticleFragment : Fragment() { | |||||||
|  |  | ||||||
|             override fun shouldInterceptRequest(view: WebView?, url: String): WebResourceResponse? { |             override fun shouldInterceptRequest(view: WebView?, url: String): WebResourceResponse? { | ||||||
|                 val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL) |                 val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL) | ||||||
|                 if (url.toLowerCase().contains(".jpg") || url.toLowerCase().contains(".jpeg")) { |                 if (url.lowercase(Locale.US).contains(".jpg") || url.lowercase(Locale.US).contains(".jpeg")) { | ||||||
|                     try { |                     try { | ||||||
|                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() |                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() | ||||||
|                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG)) |                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG)) | ||||||
|                     }catch ( e : ExecutionException) {} |                     }catch ( e : ExecutionException) {} | ||||||
|                 } |                 } | ||||||
|                 else if (url.toLowerCase().contains(".png")) { |                 else if (url.lowercase(Locale.US).contains(".png")) { | ||||||
|                     try { |                     try { | ||||||
|                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() |                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() | ||||||
|                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG)) |                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG)) | ||||||
|                     }catch ( e : ExecutionException) {} |                     }catch ( e : ExecutionException) {} | ||||||
|                 } |                 } | ||||||
|                 else if (url.toLowerCase().contains(".webp")) { |                 else if (url.lowercase(Locale.US).contains(".webp")) { | ||||||
|                     try { |                     try { | ||||||
|                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() |                         val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get() | ||||||
|                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP)) |                         return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP)) | ||||||
| @@ -542,31 +511,34 @@ class ArticleFragment : Fragment() { | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun scrollDown() { | ||||||
|  |         val height = binding.nestedScrollView.measuredHeight | ||||||
|  |         binding.nestedScrollView.smoothScrollBy(0, height/2) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun scrollUp() { | ||||||
|  |         val height = binding.nestedScrollView.measuredHeight | ||||||
|  |         binding.nestedScrollView.smoothScrollBy(0, -height/2) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) { |     private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) { | ||||||
|         binding.progressBar.visibility = View.GONE |         binding.progressBar.visibility = View.GONE | ||||||
|         requireActivity().openItemUrl( |         requireActivity().openItemUrlInternalBrowser( | ||||||
|             allItems, |                 url, | ||||||
|             pageNumber.toInt(), |                 customTabsIntent, | ||||||
|             url, |                 requireActivity() | ||||||
|             customTabsIntent, |  | ||||||
|             true, |  | ||||||
|             false, |  | ||||||
|             requireActivity() |  | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
|         private const val ARG_POSITION = "position" |  | ||||||
|         private const val ARG_ITEMS = "items" |         private const val ARG_ITEMS = "items" | ||||||
|  |  | ||||||
|         fun newInstance( |         fun newInstance( | ||||||
|             position: Int, |                 item: Item | ||||||
|             allItems: ArrayList<Item> |  | ||||||
|         ): ArticleFragment { |         ): ArticleFragment { | ||||||
|             val fragment = ArticleFragment() |             val fragment = ArticleFragment() | ||||||
|             val args = Bundle() |             val args = Bundle() | ||||||
|             args.putInt(ARG_POSITION, position) |             args.putParcelable(ARG_ITEMS, item) | ||||||
|             args.putParcelableArrayList(ARG_ITEMS, allItems) |  | ||||||
|             fragment.arguments = args |             fragment.arguments = args | ||||||
|             return fragment |             return fragment | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ class AppColors(a: Activity) { | |||||||
|             R.color.darkBackground |             R.color.darkBackground | ||||||
|         } else { |         } else { | ||||||
|             a.setTheme(R.style.NoBar) |             a.setTheme(R.style.NoBar) | ||||||
|             android.R.color.background_light |             R.color.grey_50 | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         textColor = if (isDarkTheme) { |         textColor = if (isDarkTheme) { | ||||||
|   | |||||||
| @@ -1,43 +0,0 @@ | |||||||
| package apps.amine.bou.readerforselfoss.transformers |  | ||||||
|  |  | ||||||
| import androidx.viewpager.widget.ViewPager |  | ||||||
| import android.view.View |  | ||||||
|  |  | ||||||
| class DepthPageTransformer : ViewPager.PageTransformer { |  | ||||||
|  |  | ||||||
|     override fun transformPage(view: View, position: Float) { |  | ||||||
|         val pageWidth = view.width |  | ||||||
|  |  | ||||||
|         when { |  | ||||||
|             position < -1 -> // [-Infinity,-1) |  | ||||||
|                 // This page is way off-screen to the left. |  | ||||||
|                 view.alpha = 0F |  | ||||||
|             position <= 0 -> { // [-1,0] |  | ||||||
|                 // Use the default slide transition when moving to the left page |  | ||||||
|                 view.alpha = 1F |  | ||||||
|                 view.translationX = 0F |  | ||||||
|                 view.scaleX = 1F |  | ||||||
|                 view.scaleY = 1F |  | ||||||
|             } |  | ||||||
|             position <= 1 -> { // (0,1] |  | ||||||
|                 // Fade the page out. |  | ||||||
|                 view.alpha = 1 - position |  | ||||||
|  |  | ||||||
|                 // Counteract the default slide transition |  | ||||||
|                 view.translationX = pageWidth * -position |  | ||||||
|  |  | ||||||
|                 // Scale the page down (between MIN_SCALE and 1) |  | ||||||
|                 val scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)) |  | ||||||
|                 view.scaleX = scaleFactor |  | ||||||
|                 view.scaleY = scaleFactor |  | ||||||
|             } |  | ||||||
|             else -> // (1,+Infinity] |  | ||||||
|                 // This page is way off-screen to the right. |  | ||||||
|                 view.alpha = 0F |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     companion object { |  | ||||||
|         private val MIN_SCALE = 0.75f |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -13,7 +13,7 @@ fun String.longHash(): Long { | |||||||
|     val chars = this.toCharArray() |     val chars = this.toCharArray() | ||||||
|  |  | ||||||
|     for (i in 0 until l) { |     for (i in 0 until l) { | ||||||
|         h = 31 * h + chars[i].toLong() |         h = 31 * h + chars[i].code.toLong() | ||||||
|     } |     } | ||||||
|     return h |     return h | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,11 +4,12 @@ import android.app.Activity | |||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
| import android.content.SharedPreferences | import android.content.SharedPreferences | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| import apps.amine.bou.readerforselfoss.LoginActivity | import apps.amine.bou.readerforselfoss.LoginActivity | ||||||
|  |  | ||||||
| class Config(c: Context) { | class Config(c: Context) { | ||||||
|  |  | ||||||
|     val settings: SharedPreferences = c.getSharedPreferences(settingsName, Context.MODE_PRIVATE) |     val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(c) | ||||||
|  |  | ||||||
|     val baseUrl: String |     val baseUrl: String | ||||||
|         get() = settings.getString("url", "")!! |         get() = settings.getString("url", "")!! | ||||||
| @@ -42,17 +43,15 @@ class Config(c: Context) { | |||||||
|  |  | ||||||
|         var apiVersion = 0 |         var apiVersion = 0 | ||||||
|  |  | ||||||
|  |         /* Execute logout and clear all settings to default */ | ||||||
|         fun logoutAndRedirect( |         fun logoutAndRedirect( | ||||||
|             c: Context, |             c: Context, | ||||||
|             callingActivity: Activity, |             callingActivity: Activity, | ||||||
|             editor: SharedPreferences.Editor, |             editor: SharedPreferences.Editor, | ||||||
|             baseUrlFail: Boolean = false |             baseUrlFail: Boolean = false | ||||||
|         ): Boolean { |         ): Boolean { | ||||||
|             editor.remove("url") |             val settings = PreferenceManager.getDefaultSharedPreferences(c) | ||||||
|             editor.remove("login") |             settings.edit().clear().commit() | ||||||
|             editor.remove("password") |  | ||||||
|             editor.remove("apiVersionMajor") |  | ||||||
|             editor.apply() |  | ||||||
|             val intent = Intent(c, LoginActivity::class.java) |             val intent = Intent(c, LoginActivity::class.java) | ||||||
|             if (baseUrlFail) { |             if (baseUrlFail) { | ||||||
|                 intent.putExtra("baseUrlFail", baseUrlFail) |                 intent.putExtra("baseUrlFail", baseUrlFail) | ||||||
|   | |||||||
| @@ -86,19 +86,30 @@ fun Context.openItemUrlInternally( | |||||||
|         intent.putExtra("currentItem", currentItem) |         intent.putExtra("currentItem", currentItem) | ||||||
|         app.startActivity(intent) |         app.startActivity(intent) | ||||||
|     } else { |     } else { | ||||||
|         try { |         this.openItemUrlInternalBrowser( | ||||||
|             CustomTabActivityHelper.openCustomTab( |                 linkDecoded, | ||||||
|  |                 customTabsIntent, | ||||||
|  |                 app) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fun Context.openItemUrlInternalBrowser( | ||||||
|  |         linkDecoded: String, | ||||||
|  |         customTabsIntent: CustomTabsIntent, | ||||||
|  |         app: Activity | ||||||
|  | ) { | ||||||
|  |     try { | ||||||
|  |         CustomTabActivityHelper.openCustomTab( | ||||||
|                 app, |                 app, | ||||||
|                 customTabsIntent, |                 customTabsIntent, | ||||||
|                 Uri.parse(linkDecoded) |                 Uri.parse(linkDecoded) | ||||||
|             ) { _, uri -> |         ) { _, uri -> | ||||||
|                 val intent = Intent(Intent.ACTION_VIEW, uri) |             val intent = Intent(Intent.ACTION_VIEW, uri) | ||||||
|                 intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK |             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK | ||||||
|                 startActivity(intent) |             startActivity(intent) | ||||||
|             } |  | ||||||
|         } catch (e: Exception) { |  | ||||||
|             openInBrowser(linkDecoded, app) |  | ||||||
|         } |         } | ||||||
|  |     } catch (e: Exception) { | ||||||
|  |         openInBrowser(linkDecoded, app) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -121,7 +132,7 @@ fun Context.openItemUrl( | |||||||
|     } else { |     } else { | ||||||
|         if (!internalBrowser) { |         if (!internalBrowser) { | ||||||
|             openInBrowser(linkDecoded, app) |             openInBrowser(linkDecoded, app) | ||||||
|         } else { |         } else if (articleViewer) { | ||||||
|             this.openItemUrlInternally( |             this.openItemUrlInternally( | ||||||
|                 allItems, |                 allItems, | ||||||
|                 currentItem, |                 currentItem, | ||||||
| @@ -130,6 +141,12 @@ fun Context.openItemUrl( | |||||||
|                 articleViewer, |                 articleViewer, | ||||||
|                 app |                 app | ||||||
|             ) |             ) | ||||||
|  |         } else { | ||||||
|  |             this.openItemUrlInternalBrowser( | ||||||
|  |                     linkDecoded, | ||||||
|  |                     customTabsIntent, | ||||||
|  |                     app | ||||||
|  |             ) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ | |||||||
|  |  | ||||||
|     </com.google.android.material.appbar.AppBarLayout> |     </com.google.android.material.appbar.AppBarLayout> | ||||||
|  |  | ||||||
|     <androidx.viewpager.widget.ViewPager |     <androidx.viewpager2.widget.ViewPager2 | ||||||
|         android:id="@+id/pager" |         android:id="@+id/pager" | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="0dp" |         android:layout_height="0dp" | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
|  |  | ||||||
|     </com.google.android.material.appbar.AppBarLayout> |     </com.google.android.material.appbar.AppBarLayout> | ||||||
|  |  | ||||||
|     <androidx.viewpager.widget.ViewPager |     <androidx.viewpager2.widget.ViewPager2 | ||||||
|         android:id="@+id/pager" |         android:id="@+id/pager" | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="0dp" |         android:layout_height="0dp" | ||||||
| @@ -33,7 +33,7 @@ | |||||||
|         app:layout_constraintTop_toBottomOf="@+id/appBarLayout" /> |         app:layout_constraintTop_toBottomOf="@+id/appBarLayout" /> | ||||||
|  |  | ||||||
|  |  | ||||||
|     <me.relex.circleindicator.CircleIndicator |     <me.relex.circleindicator.CircleIndicator3 | ||||||
|         android:id="@+id/indicator" |         android:id="@+id/indicator" | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="20dp" |         android:layout_height="20dp" | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
|     xmlns:tools="http://schemas.android.com/tools" |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|     android:layout_width="match_parent" |     android:layout_width="match_parent" | ||||||
|     android:layout_height="match_parent" |     android:layout_height="match_parent" | ||||||
|  |     android:background="?android:colorBackground" | ||||||
|     android:descendantFocusability="blocksDescendants"> |     android:descendantFocusability="blocksDescendants"> | ||||||
|  |  | ||||||
|     <androidx.core.widget.NestedScrollView |     <androidx.core.widget.NestedScrollView | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|     <color name="colorAccent">#FFff5722</color> |     <color name="colorAccent">#FFff5722</color> | ||||||
|     <color name="colorAccentDark">#FFbf360c</color> |     <color name="colorAccentDark">#FFbf360c</color> | ||||||
|     <color name="pink">#FFe91e63</color> |     <color name="pink">#FFe91e63</color> | ||||||
|     <color name="white">#FFFFFFFF</color> |     <color name="white">#FFFFFF</color> | ||||||
|     <color name="black">#FF000000</color> |     <color name="black">#FF000000</color> | ||||||
|     <color name="red">#FF0000</color> |     <color name="red">#FF0000</color> | ||||||
|     <color name="refresh_progress_1">@color/colorAccentDark</color> |     <color name="refresh_progress_1">@color/colorAccentDark</color> | ||||||
| @@ -20,5 +20,5 @@ | |||||||
|  |  | ||||||
|     <color name="cardBackgroundColor">#FFFFFFFF</color> |     <color name="cardBackgroundColor">#FFFFFFFF</color> | ||||||
|     <color name="materialDrawerHeaderSelectionText">#212121</color> |     <color name="materialDrawerHeaderSelectionText">#212121</color> | ||||||
|     <color name="darkBackground">#FF303030</color> |     <color name="darkBackground">#303030</color> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ | |||||||
|         <item name="cardBackgroundColor">@color/grey_800</item> |         <item name="cardBackgroundColor">@color/grey_800</item> | ||||||
|         <item name="android:colorBackground">@color/darkBackground</item> |         <item name="android:colorBackground">@color/darkBackground</item> | ||||||
|         <item name="colorSurface">@color/darkBackground</item> |         <item name="colorSurface">@color/darkBackground</item> | ||||||
|  |         <item name="alertDialogTheme">@style/AlertDialogDark</item> | ||||||
|         <item name="bnbBackgroundColor">@color/grey_900</item> |         <item name="bnbBackgroundColor">@color/grey_900</item> | ||||||
|         <item name="android:textColorPrimary">@color/white</item> |         <item name="android:textColorPrimary">@color/white</item> | ||||||
|         <item name="android:textColorSecondary">@color/grey_600</item> |         <item name="android:textColorSecondary">@color/grey_600</item> | ||||||
| @@ -63,4 +64,10 @@ | |||||||
|         <item name="android:textColor">?android:textColorPrimary</item> |         <item name="android:textColor">?android:textColorPrimary</item> | ||||||
|     </style> |     </style> | ||||||
|  |  | ||||||
|  |     <!-- Alert dialog Theme --> | ||||||
|  |  | ||||||
|  |     <style name="AlertDialogDark" parent="Theme.MaterialComponents.Dialog"> | ||||||
|  |         <item name="android:background">@color/darkBackground</item> | ||||||
|  |     </style> | ||||||
|  |  | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| buildscript { | buildscript { | ||||||
|     ext { |     ext { | ||||||
|         kotlin_version = '1.5.31' |         kotlin_version = '1.6.10' | ||||||
|         android_version = '1.0.0' |         android_version = '1.0.0' | ||||||
|         androidx_version = '1.1.0-alpha05' |         androidx_version = '1.1.0-alpha05' | ||||||
|         lifecycle_version = '2.2.0-alpha01' |         lifecycle_version = '2.2.0-alpha01' | ||||||
| @@ -15,7 +15,7 @@ buildscript { | |||||||
|         maven { url "https://www.jitpack.io" } |         maven { url "https://www.jitpack.io" } | ||||||
|     } |     } | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.android.tools.build:gradle:7.0.3' |         classpath 'com.android.tools.build:gradle:7.0.4' | ||||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -23,9 +23,9 @@ buildscript { | |||||||
| allprojects { | allprojects { | ||||||
|     repositories { |     repositories { | ||||||
|         google() |         google() | ||||||
|  |         mavenCentral() | ||||||
|         jcenter() |         jcenter() | ||||||
|         maven { url "https://www.jitpack.io" } |         maven { url "https://www.jitpack.io" } | ||||||
|         mavenCentral() |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user