Merge branch 'dependency_injection' into 'master'
dependency injection See merge request pixeldroid/PixelDroid!236
This commit is contained in:
commit
ede4a2ffbf
|
@ -6,7 +6,7 @@ apply plugin: 'jacoco'
|
|||
android {
|
||||
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.3"
|
||||
buildToolsVersion '30.0.1'
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
|
@ -56,12 +56,12 @@ dependencies {
|
|||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.1'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.2.2'
|
||||
implementation 'androidx.navigation:navigation-ui:2.2.2'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
||||
implementation 'androidx.navigation:navigation-ui:2.3.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
|
||||
|
@ -78,9 +78,9 @@ dependencies {
|
|||
testImplementation "androidx.room:room-testing:$room_version"
|
||||
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
|
||||
|
||||
implementation 'info.androidhive:imagefilters:1.0.7'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.5-native'
|
||||
|
@ -97,11 +97,11 @@ dependencies {
|
|||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
testImplementation "com.github.tomakehurst:wiremock-jre8:2.26.3"
|
||||
testImplementation 'com.github.tomakehurst:wiremock-jre8:2.27.1'
|
||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||
testImplementation 'junit:junit:4.13'
|
||||
|
||||
androidTestImplementation('com.squareup.okhttp3:mockwebserver:4.7.2')
|
||||
androidTestImplementation('com.squareup.okhttp3:mockwebserver:4.8.0')
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.2.0'
|
||||
|
@ -126,24 +126,30 @@ dependencies {
|
|||
implementation "com.mikepenz:iconics-views:5.0.2"
|
||||
implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar'
|
||||
|
||||
//Dagger (dependency injection)
|
||||
implementation 'com.google.dagger:dagger-android:2.28.3'
|
||||
implementation 'com.google.dagger:dagger-android-support:2.28.3'
|
||||
// if you use the support libraries
|
||||
kapt 'com.google.dagger:dagger-android-processor:2.28.3'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.28.3'
|
||||
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.2.0'
|
||||
|
||||
def fragment_version = '1.2.4'
|
||||
def fragment_version = '1.2.5'
|
||||
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
|
||||
|
||||
// Use the most recent version of CameraX
|
||||
def camerax_version = '1.0.0-beta04'
|
||||
def camerax_version = '1.0.0-beta07'
|
||||
implementation "androidx.camera:camera-core:${camerax_version}"
|
||||
implementation "androidx.camera:camera-camera2:${camerax_version}"
|
||||
// CameraX Lifecycle library
|
||||
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
||||
|
||||
// CameraX View class
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha11'
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha14'
|
||||
|
||||
implementation 'com.karumi:dexter:6.1.2'
|
||||
implementation 'com.karumi:dexter:6.2.1'
|
||||
|
||||
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.h.pixeldroid.db.AppDatabase
|
|||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
@ -40,7 +41,7 @@ class DrawerMenuTest {
|
|||
val baseUrl = mockServer.getUrl()
|
||||
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.widget.TextView
|
|||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.swipeDown
|
||||
import androidx.test.espresso.action.ViewActions.swipeUp
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition
|
||||
|
@ -17,7 +16,7 @@ import com.google.android.material.tabs.TabLayout
|
|||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.clickChildViewWithId
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.first
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.getText
|
||||
|
@ -25,6 +24,7 @@ import com.h.pixeldroid.testUtility.CustomMatchers.Companion.second
|
|||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.slowSwipeUp
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.typeTextInViewWithId
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
@ -49,7 +49,7 @@ class HomeFeedTest {
|
|||
mockServer.start()
|
||||
val baseUrl = mockServer.getUrl()
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -26,10 +26,11 @@ import androidx.test.rule.ActivityTestRule
|
|||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.hamcrest.Matcher
|
||||
|
@ -64,7 +65,7 @@ class IntentTest {
|
|||
val baseUrl = mockServer.getUrl()
|
||||
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -13,7 +13,7 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
|||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
@ -43,7 +43,7 @@ class LoginActivityOfflineTest {
|
|||
fun before() {
|
||||
switchAirplaneMode()
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
ActivityScenario.launch(LoginActivity::class.java)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.h.pixeldroid.db.AppDatabase
|
|||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
@ -45,7 +46,7 @@ class LoginActivityOnlineTest {
|
|||
context = ApplicationProvider.getApplicationContext()
|
||||
pref = context.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE)
|
||||
pref.edit().clear().apply()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.close()
|
||||
}
|
||||
|
@ -97,7 +98,7 @@ class LoginActivityOnlineTest {
|
|||
@Test
|
||||
fun correctIntentReturnLoadsMainActivity() {
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
|
||||
db.instanceDao().insertInstance(
|
||||
|
|
|
@ -16,10 +16,11 @@ import com.google.android.material.tabs.TabLayout
|
|||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.clickChildViewWithId
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.first
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import com.h.pixeldroid.utils.PostUtils.Companion.censorColorMatrix
|
||||
import com.h.pixeldroid.utils.PostUtils.Companion.uncensorColorMatrix
|
||||
|
@ -46,7 +47,7 @@ class MockedServerTest {
|
|||
mockServer.start()
|
||||
val baseUrl = mockServer.getUrl()
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.h.pixeldroid.db.InstanceDatabaseEntity
|
|||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.testUtility.CustomMatchers
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import kotlinx.android.synthetic.main.activity_post_creation.*
|
||||
import org.hamcrest.Matchers.not
|
||||
|
@ -60,7 +61,7 @@ class PostCreationActivityTest {
|
|||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
mockServer.start()
|
||||
val baseUrl = mockServer.getUrl()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.h.pixeldroid.db.AppDatabase
|
|||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import org.hamcrest.Matcher
|
||||
|
@ -73,7 +74,7 @@ class PostFragmentUITests {
|
|||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
mockServer.start()
|
||||
val baseUrl = mockServer.getUrl()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.h.pixeldroid.objects.Status
|
|||
import com.h.pixeldroid.objects.Tag
|
||||
|
||||
import com.h.pixeldroid.testUtility.MockServer
|
||||
import com.h.pixeldroid.testUtility.initDB
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import org.hamcrest.Matcher
|
||||
import org.junit.*
|
||||
|
@ -49,7 +50,7 @@ class PostTest {
|
|||
val mockServer = MockServer()
|
||||
mockServer.start()
|
||||
val baseUrl = mockServer.getUrl()
|
||||
db = DBUtils.initDB(context)
|
||||
db = initDB(context)
|
||||
db.clearAllTables()
|
||||
db.instanceDao().insertInstance(
|
||||
InstanceDatabaseEntity(
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.h.pixeldroid.testUtility
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
|
||||
fun initDB(context: Context): AppDatabase {
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
AppDatabase::class.java, "pixeldroid"
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
|
@ -16,13 +16,14 @@
|
|||
|
||||
<application
|
||||
android:name=".Pixeldroid"
|
||||
android:allowBackup="true"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
tools:replace="android:allowBackup">
|
||||
|
||||
<activity
|
||||
android:name=".PhotoEditActivity"
|
||||
|
|
|
@ -4,6 +4,8 @@ import android.os.Bundle
|
|||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.fragments.feeds.AccountListFragment
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_ID_TAG
|
||||
|
@ -12,28 +14,32 @@ import com.h.pixeldroid.utils.DBUtils
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class FollowsActivity : AppCompatActivity() {
|
||||
private var followsFragment = AccountListFragment()
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_followers)
|
||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
|
||||
// Get account id
|
||||
val id = intent.getSerializableExtra(ACCOUNT_ID_TAG) as String?
|
||||
val following = intent.getSerializableExtra(FOLLOWING_TAG) as Boolean
|
||||
|
||||
if(id == null) {
|
||||
val db = DBUtils.initDB(applicationContext)
|
||||
|
||||
val user = db.userDao().getActiveUser()
|
||||
|
||||
val domain = user?.instance_uri.orEmpty()
|
||||
val accessToken = user?.accessToken.orEmpty()
|
||||
db.close()
|
||||
|
||||
val pixelfedAPI = PixelfedAPI.create(domain)
|
||||
val pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
|
||||
pixelfedAPI.verifyCredentials("Bearer $accessToken").enqueue(object :
|
||||
Callback<Account> {
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.ActivityNotFoundException
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
@ -13,6 +12,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Application
|
||||
import com.h.pixeldroid.objects.Instance
|
||||
|
@ -26,6 +26,7 @@ import okhttp3.HttpUrl
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
@ -38,7 +39,12 @@ class LoginActivity : AppCompatActivity() {
|
|||
private lateinit var oauthScheme: String
|
||||
private lateinit var appName: String
|
||||
private lateinit var preferences: SharedPreferences
|
||||
private lateinit var db: AppDatabase
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
private lateinit var pixelfedAPI: PixelfedAPI
|
||||
private var inputVisibility: Int = View.GONE
|
||||
|
||||
|
@ -46,11 +52,11 @@ class LoginActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_login)
|
||||
|
||||
(application as Pixeldroid).getAppComponent().inject(this)
|
||||
loadingAnimation(true)
|
||||
appName = getString(R.string.app_name)
|
||||
oauthScheme = getString(R.string.auth_scheme)
|
||||
preferences = getSharedPreferences("$PACKAGE_ID.pref", Context.MODE_PRIVATE)
|
||||
db = DBUtils.initDB(applicationContext)
|
||||
|
||||
if (Utils.hasInternet(applicationContext)) {
|
||||
connect_instance_button.setOnClickListener {
|
||||
|
@ -61,8 +67,8 @@ class LoginActivity : AppCompatActivity() {
|
|||
} else {
|
||||
login_activity_connection_required.visibility = View.VISIBLE
|
||||
login_activity_connection_required_button.setOnClickListener {
|
||||
finish();
|
||||
startActivity(intent);
|
||||
finish()
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
loadingAnimation(false)
|
||||
|
@ -113,7 +119,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
hideKeyboard()
|
||||
loadingAnimation(true)
|
||||
|
||||
PixelfedAPI.create(normalizedDomain).registerApplication(
|
||||
apiHolder.setDomain(normalizedDomain).registerApplication(
|
||||
appName,"$oauthScheme://$PACKAGE_ID", SCOPE
|
||||
).enqueue(object : Callback<Application> {
|
||||
override fun onResponse(call: Call<Application>, response: Response<Application>) {
|
||||
|
@ -185,7 +191,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
pixelfedAPI = PixelfedAPI.create(domain)
|
||||
pixelfedAPI = apiHolder.setDomain(domain)
|
||||
pixelfedAPI.obtainToken(
|
||||
clientId, clientSecret, "$oauthScheme://$PACKAGE_ID", SCOPE, code,
|
||||
"authorization_code"
|
||||
|
@ -242,7 +248,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
.enqueue(object : Callback<Account> {
|
||||
override fun onResponse(call: Call<Account>, response: Response<Account>) {
|
||||
if (response.body() != null && response.isSuccessful) {
|
||||
db.userDao().deActivateActiveUser()
|
||||
db.userDao().deActivateActiveUsers()
|
||||
val user = response.body() as Account
|
||||
DBUtils.addUser(
|
||||
db,
|
||||
|
@ -251,7 +257,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
activeUser = true,
|
||||
accessToken = accessToken
|
||||
)
|
||||
db.close()
|
||||
apiHolder.setDomainToCurrentUser(db)
|
||||
val intent = Intent(this@LoginActivity, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
startActivity(intent)
|
||||
|
|
|
@ -14,15 +14,15 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.fragments.CameraFragment
|
||||
import com.h.pixeldroid.fragments.SearchDiscoverFragment
|
||||
import com.h.pixeldroid.fragments.feeds.NotificationsFragment
|
||||
import com.h.pixeldroid.fragments.feeds.OfflineFeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.PostsFeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.PublicTimelineFragment
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.HomeTimelineFragment
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PublicTimelineFragment
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import com.h.pixeldroid.utils.Utils.Companion.hasInternet
|
||||
|
@ -39,11 +39,16 @@ import kotlinx.android.synthetic.main.activity_main.*
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private val searchDiscoverFragment: SearchDiscoverFragment = SearchDiscoverFragment()
|
||||
private lateinit var db: AppDatabase
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
private lateinit var header: AccountHeaderView
|
||||
private var user: UserDatabaseEntity? = null
|
||||
|
||||
|
@ -56,7 +61,7 @@ class MainActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
db = DBUtils.initDB(applicationContext)
|
||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
//get the currently active user
|
||||
user = db.userDao().getActiveUser()
|
||||
|
@ -67,7 +72,7 @@ class MainActivity : AppCompatActivity() {
|
|||
} else {
|
||||
setupDrawer()
|
||||
val tabs = arrayOf(
|
||||
if (hasInternet(applicationContext)) PostsFeedFragment()
|
||||
if (hasInternet(applicationContext)) HomeTimelineFragment()
|
||||
else OfflineFeedFragment(),
|
||||
searchDiscoverFragment,
|
||||
CameraFragment(),
|
||||
|
@ -163,14 +168,17 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
|
||||
}
|
||||
private fun getUpdatedAccount(){
|
||||
private fun getUpdatedAccount() {
|
||||
if (hasInternet(applicationContext)) {
|
||||
val domain = user?.instance_uri.orEmpty()
|
||||
val accessToken = user?.accessToken.orEmpty()
|
||||
val pixelfedAPI = PixelfedAPI.create(domain)
|
||||
pixelfedAPI.verifyCredentials("Bearer $accessToken")
|
||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
api.verifyCredentials("Bearer $accessToken")
|
||||
.enqueue(object : Callback<Account> {
|
||||
override fun onResponse(call: Call<Account>, response: Response<Account>) {
|
||||
override fun onResponse(
|
||||
call: Call<Account>,
|
||||
response: Response<Account>
|
||||
) {
|
||||
if (response.body() != null && response.isSuccessful) {
|
||||
val account = response.body() as Account
|
||||
DBUtils.addUser(db, account, domain, accessToken = accessToken)
|
||||
|
@ -197,9 +205,9 @@ class MainActivity : AppCompatActivity() {
|
|||
return false
|
||||
}
|
||||
|
||||
db.userDao().deActivateActiveUser()
|
||||
db.userDao().deActivateActiveUsers()
|
||||
db.userDao().activateUser(profile.identifier.toString())
|
||||
|
||||
apiHolder.setDomainToCurrentUser(db)
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
startActivity(intent)
|
||||
|
@ -271,9 +279,9 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
/**
|
||||
Launches the given activity and put it as the current one
|
||||
Setting argument firstTime to true means the task history will be reset (as if the app were launched anew into
|
||||
this activity)
|
||||
* Launches the given activity and put it as the current one
|
||||
* @param firstTime to true means the task history will be reset (as if the app were
|
||||
* launched anew into this activity)
|
||||
*/
|
||||
private fun launchActivity(activity: AppCompatActivity, firstTime: Boolean = false) {
|
||||
val intent = Intent(this, activity::class.java)
|
||||
|
@ -285,7 +293,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
/**
|
||||
Closes the drawer if it is open, when we press the back button
|
||||
* Closes the drawer if it is open, when we press the back button
|
||||
*/
|
||||
override fun onBackPressed() {
|
||||
if(drawer_layout.isDrawerOpen(GravityCompat.START)){
|
||||
|
|
|
@ -2,13 +2,29 @@ package com.h.pixeldroid
|
|||
|
||||
import android.app.Application
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.h.pixeldroid.di.*
|
||||
import com.h.pixeldroid.utils.ThemeUtils
|
||||
|
||||
|
||||
class Pixeldroid: Application() {
|
||||
|
||||
private lateinit var mApplicationComponent: ApplicationComponent
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
val sharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
ThemeUtils.setThemeFromPreferences(sharedPreferences, resources)
|
||||
mApplicationComponent = DaggerApplicationComponent
|
||||
.builder()
|
||||
.applicationModule(ApplicationModule(this))
|
||||
.databaseModule(DatabaseModule(applicationContext))
|
||||
.aPIModule(APIModule())
|
||||
.build()
|
||||
mApplicationComponent.inject(this);
|
||||
}
|
||||
|
||||
fun getAppComponent(): ApplicationComponent {
|
||||
return mApplicationComponent
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import android.util.Log
|
|||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.fragments.PostFragment
|
||||
import com.h.pixeldroid.objects.DiscoverPost
|
||||
import com.h.pixeldroid.objects.Status
|
||||
|
@ -16,25 +18,32 @@ import kotlinx.android.synthetic.main.activity_post.*
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class PostActivity : AppCompatActivity() {
|
||||
private lateinit var postFragment : PostFragment
|
||||
lateinit var domain : String
|
||||
private lateinit var accessToken : String
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_post)
|
||||
|
||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
|
||||
val status = intent.getSerializableExtra(POST_TAG) as Status?
|
||||
val discoverPost: DiscoverPost? = intent.getSerializableExtra(DISCOVER_TAG) as DiscoverPost?
|
||||
val db = DBUtils.initDB(applicationContext)
|
||||
|
||||
val user = db.userDao().getActiveUser()
|
||||
|
||||
domain = user?.instance_uri.orEmpty()
|
||||
accessToken = user?.accessToken.orEmpty()
|
||||
db.close()
|
||||
|
||||
postFragment = PostFragment()
|
||||
val arguments = Bundle()
|
||||
|
@ -52,7 +61,7 @@ class PostActivity : AppCompatActivity() {
|
|||
arguments: Bundle,
|
||||
discoverPost: DiscoverPost
|
||||
) {
|
||||
val api = PixelfedAPI.create(domain)
|
||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
val id = discoverPost.url?.substringAfterLast('/') ?: ""
|
||||
api.getStatus("Bearer $accessToken", id).enqueue(object : Callback<Status> {
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.interfaces.PostCreationListener
|
||||
import com.h.pixeldroid.objects.Attachment
|
||||
import com.h.pixeldroid.objects.Instance
|
||||
|
@ -35,6 +37,7 @@ import okhttp3.MultipartBody
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||
|
||||
|
@ -58,22 +61,28 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
|||
private var maxLength: Int = Instance.DEFAULT_MAX_TOOT_CHARS
|
||||
|
||||
private var description: String = ""
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_post_creation)
|
||||
|
||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
// load images
|
||||
posts = intent.getStringArrayListExtra("pictures_uri")!!
|
||||
|
||||
progressList = posts.map { 0 } as ArrayList<Int>
|
||||
muListOfIds = posts.map { "" }.toMutableList()
|
||||
|
||||
val db = DBUtils.initDB(applicationContext)
|
||||
user = db.userDao().getActiveUser()
|
||||
|
||||
val instances = db.instanceDao().getAll()
|
||||
db.close()
|
||||
maxLength = if (user!=null){
|
||||
val thisInstances =
|
||||
instances.filter { instanceDatabaseEntity ->
|
||||
|
@ -84,9 +93,8 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
|||
Instance.DEFAULT_MAX_TOOT_CHARS
|
||||
}
|
||||
|
||||
val domain = user?.instance_uri.orEmpty()
|
||||
accessToken = user?.accessToken.orEmpty()
|
||||
pixelfedAPI = PixelfedAPI.create(domain)
|
||||
pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
|
||||
// check if the pictures are alright
|
||||
// TODO
|
||||
|
|
|
@ -16,6 +16,8 @@ import androidx.recyclerview.widget.GridLayoutManager
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.h.pixeldroid.adapters.ProfilePostsRecyclerViewAdapter
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG
|
||||
import com.h.pixeldroid.objects.Relationship
|
||||
|
@ -26,6 +28,7 @@ import com.h.pixeldroid.utils.ImageConverter
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProfileActivity : AppCompatActivity() {
|
||||
private lateinit var pixelfedAPI : PixelfedAPI
|
||||
|
@ -34,19 +37,24 @@ class ProfileActivity : AppCompatActivity() {
|
|||
private lateinit var accessToken : String
|
||||
private lateinit var domain : String
|
||||
private var account: Account? = null
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_profile)
|
||||
|
||||
val db = DBUtils.initDB(applicationContext)
|
||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
val user = db.userDao().getActiveUser()
|
||||
|
||||
domain = user?.instance_uri.orEmpty()
|
||||
pixelfedAPI = PixelfedAPI.create(domain)
|
||||
pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
accessToken = user?.accessToken.orEmpty()
|
||||
db.close()
|
||||
|
||||
// Set posts RecyclerView as a grid with 3 columns
|
||||
recycler = findViewById(R.id.profilePostsRecyclerView)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.h.pixeldroid.api
|
||||
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.objects.*
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.MultipartBody
|
||||
|
@ -9,6 +10,8 @@ import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
|||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.*
|
||||
import retrofit2.http.Field
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
|
||||
/*
|
||||
|
@ -246,4 +249,4 @@ interface PixelfedAPI {
|
|||
fun discover(
|
||||
@Header("Authorization") authorization: String
|
||||
) : Call<DiscoverPosts>
|
||||
}
|
||||
}
|
|
@ -16,8 +16,8 @@ interface UserDao {
|
|||
@Query("SELECT * FROM users WHERE isActive=1 LIMIT 1")
|
||||
fun getActiveUser(): UserDatabaseEntity?
|
||||
|
||||
@Query("UPDATE users SET isActive=0 WHERE isActive=1")
|
||||
fun deActivateActiveUser()
|
||||
@Query("UPDATE users SET isActive=0")
|
||||
fun deActivateActiveUsers()
|
||||
|
||||
@Query("UPDATE users SET isActive=1 WHERE user_id=:id")
|
||||
fun activateUser(id: String)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.h.pixeldroid.di
|
||||
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
class APIModule{
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesAPIHolder(db: AppDatabase): PixelfedAPIHolder {
|
||||
return PixelfedAPIHolder(db.userDao().getActiveUser()?.instance_uri)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class PixelfedAPIHolder(domain: String?){
|
||||
private val intermediate: Retrofit.Builder = Retrofit.Builder()
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
||||
var api: PixelfedAPI? = if (domain != null) setDomain(domain) else null
|
||||
|
||||
fun setDomainToCurrentUser(db: AppDatabase): PixelfedAPI {
|
||||
return setDomain(db.userDao().getActiveUser()!!.instance_uri)
|
||||
}
|
||||
|
||||
fun setDomain(domain: String): PixelfedAPI {
|
||||
val newAPI = intermediate
|
||||
.baseUrl(domain)
|
||||
.build().create(PixelfedAPI::class.java)
|
||||
api = newAPI
|
||||
return newAPI
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.h.pixeldroid.di
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import com.h.pixeldroid.*
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.fragments.PostFragment
|
||||
import com.h.pixeldroid.fragments.SearchDiscoverFragment
|
||||
import com.h.pixeldroid.fragments.feeds.FeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.OfflineFeedFragment
|
||||
import dagger.Component
|
||||
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
@Component(modules = [ApplicationModule::class, DatabaseModule::class, APIModule::class])
|
||||
interface ApplicationComponent {
|
||||
fun inject(application: Pixeldroid?)
|
||||
fun inject(activity: LoginActivity?)
|
||||
fun inject(feedFragment: FeedFragment)
|
||||
fun inject(activity: FollowsActivity?)
|
||||
fun inject(activity: PostActivity?)
|
||||
fun inject(activity: PostCreationActivity?)
|
||||
fun inject(activity: ProfileActivity?)
|
||||
fun inject(mainActivity: MainActivity?)
|
||||
fun inject(fragment: PostFragment)
|
||||
fun inject(fragment: SearchDiscoverFragment)
|
||||
fun inject(fragment: OfflineFeedFragment)
|
||||
|
||||
val context: Context?
|
||||
val application: Application?
|
||||
val database: AppDatabase
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.h.pixeldroid.di
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
||||
@Module
|
||||
class ApplicationModule(app: Application) {
|
||||
private val mApplication: Application = app
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideContext(): Context {
|
||||
return mApplication
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideApplication(): Application {
|
||||
return mApplication
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.h.pixeldroid.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
class DatabaseModule(private val context: Context) {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesDatabase(): AppDatabase {
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
AppDatabase::class.java, "pixeldroid"
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
||||
}
|
|
@ -8,54 +8,67 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.h.pixeldroid.Pixeldroid
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG
|
||||
import com.h.pixeldroid.objects.Status.Companion.POST_TAG
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class PostFragment : Fragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val current_status = arguments?.getSerializable(POST_TAG) as Status?
|
||||
val currentStatus = arguments?.getSerializable(POST_TAG) as Status?
|
||||
val statusDomain = arguments?.getString(DOMAIN_TAG)!!
|
||||
val root: View = inflater.inflate(R.layout.post_fragment, container, false)
|
||||
val picRequest = Glide.with(this)
|
||||
.asDrawable().fitCenter()
|
||||
.placeholder(ColorDrawable(Color.GRAY))
|
||||
|
||||
current_status?.setupPost(root, picRequest, this, statusDomain, true)
|
||||
currentStatus?.setupPost(root, picRequest, this, statusDomain, true)
|
||||
|
||||
//Setup arguments needed for the onclicklisteners
|
||||
val holder = PostViewHolder(root, requireContext())
|
||||
val db = DBUtils.initDB(requireContext())
|
||||
val holder = PostViewHolder(
|
||||
root,
|
||||
requireContext()
|
||||
)
|
||||
|
||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
val user = db.userDao().getActiveUser()
|
||||
|
||||
val domain = user?.instance_uri.orEmpty()
|
||||
val accessToken = user?.accessToken.orEmpty()
|
||||
val api = PixelfedAPI.create(domain)
|
||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
|
||||
current_status?.setDescription(root, api, "Bearer $accessToken")
|
||||
currentStatus?.setDescription(root, api, "Bearer $accessToken")
|
||||
|
||||
//Activate onclickListeners
|
||||
current_status?.activateLiker(holder, api, "Bearer $accessToken",
|
||||
current_status.favourited ?: false
|
||||
currentStatus?.activateLiker(holder, api, "Bearer $accessToken",
|
||||
currentStatus.favourited ?: false
|
||||
)
|
||||
current_status?.activateReblogger(holder, api, "Bearer $accessToken",
|
||||
current_status.reblogged ?: false
|
||||
currentStatus?.activateReblogger(holder, api, "Bearer $accessToken",
|
||||
currentStatus.reblogged ?: false
|
||||
)
|
||||
current_status?.activateCommenter(holder, api, "Bearer $accessToken")
|
||||
current_status?.showComments(holder, api, "Bearer $accessToken")
|
||||
currentStatus?.activateCommenter(holder, api, "Bearer $accessToken")
|
||||
currentStatus?.showComments(holder, api, "Bearer $accessToken")
|
||||
|
||||
//Activate double tap liking
|
||||
current_status?.activateDoubleTapLiker(holder, api, "Bearer $accessToken")
|
||||
currentStatus?.activateDoubleTapLiker(holder, api, "Bearer $accessToken")
|
||||
return root
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,13 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.h.pixeldroid.Pixeldroid
|
||||
import com.h.pixeldroid.PostActivity
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.SearchActivity
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.objects.DiscoverPost
|
||||
import com.h.pixeldroid.objects.DiscoverPosts
|
||||
import com.h.pixeldroid.objects.Status
|
||||
|
@ -26,6 +29,7 @@ import com.h.pixeldroid.utils.ImageConverter
|
|||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* This fragment lets you search and use Pixelfed's Discover feature
|
||||
|
@ -38,6 +42,12 @@ class SearchDiscoverFragment : Fragment() {
|
|||
private lateinit var accessToken: String
|
||||
private lateinit var discoverProgressBar: ProgressBar
|
||||
private lateinit var discoverRefreshLayout: SwipeRefreshLayout
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -47,6 +57,9 @@ class SearchDiscoverFragment : Fragment() {
|
|||
val view = inflater.inflate(R.layout.fragment_search, container, false)
|
||||
val button = view.findViewById<Button>(R.id.searchButton)
|
||||
val search = view.findViewById<EditText>(R.id.searchEditText)
|
||||
|
||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
button.setOnClickListener {
|
||||
val intent = Intent(context, SearchActivity::class.java)
|
||||
intent.putExtra("searchFeed", search.text.toString())
|
||||
|
@ -64,13 +77,9 @@ class SearchDiscoverFragment : Fragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val db = DBUtils.initDB(requireContext())
|
||||
api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
|
||||
val user = db.userDao().getActiveUser()
|
||||
|
||||
val domain = user?.instance_uri.orEmpty()
|
||||
api = PixelfedAPI.create(domain)
|
||||
accessToken = user?.accessToken.orEmpty()
|
||||
accessToken = db.userDao().getActiveUser()?.accessToken.orEmpty()
|
||||
|
||||
discoverProgressBar = view.findViewById(R.id.discoverProgressBar)
|
||||
discoverRefreshLayout = view.findViewById(R.id.discoverRefreshLayout)
|
||||
|
|
|
@ -2,11 +2,13 @@ package com.h.pixeldroid.fragments.feeds
|
|||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.lifecycle.Observer
|
||||
|
@ -24,9 +26,14 @@ import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_ID_TAG
|
|||
import com.h.pixeldroid.objects.Account.Companion.FOLLOWING_TAG
|
||||
import kotlinx.android.synthetic.main.account_list_entry.view.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
open class AccountListFragment : FeedFragment<Account, AccountListFragment.FollowsRecyclerViewAdapter.ViewHolder>() {
|
||||
open class AccountListFragment : FeedFragment() {
|
||||
lateinit var profilePicRequest: RequestBuilder<Drawable>
|
||||
protected lateinit var adapter : FeedsRecyclerViewAdapter<Account, AccountsRecyclerViewAdapter.ViewHolder>
|
||||
lateinit var factory: FeedDataSourceFactory<String, Account>
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -39,13 +46,13 @@ open class AccountListFragment : FeedFragment<Account, AccountListFragment.Follo
|
|||
.asDrawable().apply(RequestOptions().circleCrop())
|
||||
.placeholder(R.drawable.ic_default_user)
|
||||
|
||||
adapter = FollowsRecyclerViewAdapter()
|
||||
adapter = AccountsRecyclerViewAdapter()
|
||||
list.adapter = adapter
|
||||
|
||||
//Make Glide be aware of the recyclerview and pre-load images
|
||||
val sizeProvider: ListPreloader.PreloadSizeProvider<Account> = ViewPreloadSizeProvider()
|
||||
val preloader: RecyclerViewPreloader<Account> = RecyclerViewPreloader(
|
||||
Glide.with(this), adapter as AccountListFragment.FollowsRecyclerViewAdapter, sizeProvider, 4
|
||||
Glide.with(this), adapter as AccountListFragment.AccountsRecyclerViewAdapter, sizeProvider, 4
|
||||
)
|
||||
list.addOnScrollListener(preloader)
|
||||
|
||||
|
@ -54,7 +61,7 @@ open class AccountListFragment : FeedFragment<Account, AccountListFragment.Follo
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
content = makeContent()
|
||||
val content = makeContent()
|
||||
|
||||
content.observe(viewLifecycleOwner,
|
||||
Observer { c ->
|
||||
|
@ -62,51 +69,86 @@ open class AccountListFragment : FeedFragment<Account, AccountListFragment.Follo
|
|||
//after a refresh is done we need to stop the pull to refresh spinner
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
})
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.liveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
internal open fun makeContent(): LiveData<PagedList<Account>> {
|
||||
val id = arguments?.getSerializable(ACCOUNT_ID_TAG) as String
|
||||
val following = arguments?.getSerializable(FOLLOWING_TAG) as Boolean
|
||||
|
||||
val (makeInitialCall, makeAfterCall)
|
||||
= makeCalls(following, id)
|
||||
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
val dataSource = FeedDataSource(makeInitialCall, makeAfterCall)
|
||||
val dataSource = AccountListDataSource(following, id)
|
||||
factory = FeedDataSourceFactory(dataSource)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
||||
private fun makeCalls(following: Boolean, id: String):
|
||||
Pair<(Int) -> Call<List<Account>>, (Int, String) -> Call<List<Account>>> {
|
||||
val makeInitialCall: (Int) -> Call<List<Account>> =
|
||||
if (following) { requestedLoadSize ->
|
||||
inner class AccountListDataSource(private val following: Boolean, private val id: String) :
|
||||
FeedDataSource<String, Account>() {
|
||||
|
||||
override fun newSource(): AccountListDataSource {
|
||||
return AccountListDataSource(following, id)
|
||||
}
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: Account): String {
|
||||
return item.id
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Account>> {
|
||||
return if (following) {
|
||||
pixelfedAPI.followers(
|
||||
id, "Bearer $accessToken",
|
||||
limit = requestedLoadSize
|
||||
)
|
||||
} else { requestedLoadSize ->
|
||||
} else {
|
||||
pixelfedAPI.following(
|
||||
id, "Bearer $accessToken",
|
||||
limit = requestedLoadSize
|
||||
)
|
||||
}
|
||||
val makeAfterCall: (Int, String) -> Call<List<Account>> =
|
||||
if (following) { requestedLoadSize, key ->
|
||||
}
|
||||
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Account>> {
|
||||
return if (following) {
|
||||
pixelfedAPI.followers(
|
||||
id, "Bearer $accessToken",
|
||||
since_id = key, limit = requestedLoadSize
|
||||
)
|
||||
} else { requestedLoadSize, key ->
|
||||
} else {
|
||||
pixelfedAPI.following(
|
||||
id, "Bearer $accessToken",
|
||||
since_id = key, limit = requestedLoadSize
|
||||
)
|
||||
}
|
||||
return Pair(makeInitialCall, makeAfterCall)
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Account>>, callback: LoadCallback<Account>){
|
||||
|
||||
call.enqueue(object : Callback<List<Account>> {
|
||||
override fun onResponse(call: Call<List<Account>>, response: Response<List<Account>>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val data = response.body()!!
|
||||
callback.onResult(data)
|
||||
} else{
|
||||
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
loadingIndicator.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<Account>>, t: Throwable) {
|
||||
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
|
||||
Log.e("AccountListFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
inner class FollowsRecyclerViewAdapter : FeedsRecyclerViewAdapter<Account,FollowsRecyclerViewAdapter.ViewHolder>(),
|
||||
inner class AccountsRecyclerViewAdapter : FeedsRecyclerViewAdapter<Account, AccountsRecyclerViewAdapter.ViewHolder>(),
|
||||
ListPreloader.PreloadModelProvider<Account> {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
|
|
|
@ -1,52 +1,45 @@
|
|||
package com.h.pixeldroid.fragments.feeds
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.paging.DataSource
|
||||
import androidx.paging.ItemKeyedDataSource
|
||||
import androidx.paging.PagedList
|
||||
import androidx.paging.PagedListAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.h.pixeldroid.MainActivity
|
||||
import com.h.pixeldroid.Pixeldroid
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||
import com.h.pixeldroid.objects.FeedContent
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import com.h.pixeldroid.utils.Utils
|
||||
import kotlinx.android.synthetic.main.fragment_feed.view.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment() {
|
||||
|
||||
lateinit var content: LiveData<PagedList<T>>
|
||||
lateinit var factory: FeedDataSourceFactory<FeedDataSource>
|
||||
open class FeedFragment: Fragment() {
|
||||
|
||||
protected var accessToken: String? = null
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
protected lateinit var pixelfedAPI: PixelfedAPI
|
||||
|
||||
protected lateinit var list : RecyclerView
|
||||
protected lateinit var adapter : FeedsRecyclerViewAdapter<T, VH>
|
||||
protected lateinit var swipeRefreshLayout: SwipeRefreshLayout
|
||||
internal lateinit var loadingIndicator: ProgressBar
|
||||
private var user: UserDatabaseEntity? = null
|
||||
private lateinit var db: AppDatabase
|
||||
var user: UserDatabaseEntity? = null
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
|
||||
|
||||
|
@ -57,101 +50,80 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
|
|||
): View? {
|
||||
val view = inflater.inflate(R.layout.fragment_feed, container, false)
|
||||
|
||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
//Initialize lateinit fields that are needed as soon as the view is created
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout)
|
||||
loadingIndicator = view.findViewById(R.id.progressBar)
|
||||
list = swipeRefreshLayout.list
|
||||
list.layoutManager = LinearLayoutManager(context)
|
||||
db = DBUtils.initDB(requireContext())
|
||||
user = db.userDao().getActiveUser()
|
||||
pixelfedAPI = PixelfedAPI.create(user?.instance_uri.orEmpty())
|
||||
|
||||
pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||
accessToken = user?.accessToken.orEmpty()
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
open inner class FeedDataSourceFactory<ObjectId, APIObject: FeedContent>(
|
||||
private val dataSource: FeedDataSource<ObjectId, APIObject>
|
||||
): DataSource.Factory<ObjectId, APIObject>() {
|
||||
internal lateinit var liveData: MutableLiveData<FeedDataSource<ObjectId, APIObject>>
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
if (Utils.hasInternet(requireContext())) {
|
||||
factory.liveData.value!!.invalidate()
|
||||
} else {
|
||||
startActivity(Intent(requireContext(), MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open inner class FeedDataSource(private val makeInitialCall: ((Int) -> Call<List<T>>)?,
|
||||
private val makeAfterCall: ((Int, String) -> Call<List<T>>)?
|
||||
): ItemKeyedDataSource<String, T>() {
|
||||
|
||||
open fun newSource(): FeedDataSource {
|
||||
return FeedDataSource(makeInitialCall, makeAfterCall)
|
||||
}
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: T): String {
|
||||
return item.id!!
|
||||
}
|
||||
//This is called to initialize the list, so we want some of the latest statuses
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<T>
|
||||
) {
|
||||
enqueueCall(makeInitialCall!!(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<T>) {
|
||||
enqueueCall(makeAfterCall!!(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
|
||||
override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<T>) {
|
||||
//do nothing here, it is expected to pull to refresh to load newer notifications
|
||||
}
|
||||
|
||||
protected open fun enqueueCall(call: Call<List<T>>, callback: LoadCallback<T>){
|
||||
|
||||
call.enqueue(object : Callback<List<T>> {
|
||||
override fun onResponse(call: Call<List<T>>, response: Response<List<T>>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val notifications = response.body()!!
|
||||
callback.onResult(notifications)
|
||||
if(this@FeedDataSource.newSource() !is PublicTimelineFragment.SearchFeedDataSource) {
|
||||
DBUtils.storePosts(db, notifications, user!!)
|
||||
}
|
||||
} else{
|
||||
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
loadingIndicator.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<T>>, t: Throwable) {
|
||||
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
|
||||
Log.e("FeedFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
open inner class FeedDataSourceFactory<DS: FeedDataSource>(
|
||||
private val dataSource: DS
|
||||
): DataSource.Factory<String, T>() {
|
||||
lateinit var liveData: MutableLiveData<DS>
|
||||
|
||||
override fun create(): DataSource<String, T> {
|
||||
override fun create(): DataSource<ObjectId, APIObject> {
|
||||
val dataSource = dataSource.newSource()
|
||||
liveData = MutableLiveData()
|
||||
liveData.postValue(dataSource as DS)
|
||||
liveData.postValue(dataSource)
|
||||
return dataSource
|
||||
}
|
||||
}
|
||||
abstract inner class FeedDataSource<ObjectId, APIObject: FeedContent>: ItemKeyedDataSource<ObjectId, APIObject>(){
|
||||
|
||||
/**
|
||||
* Used in the initial call to initialize the list [loadInitial].
|
||||
* @param requestedLoadSize number of objects requested in a call
|
||||
* @return [Call] that gets the list of [APIObject]
|
||||
*/
|
||||
abstract fun makeInitialCall(requestedLoadSize: Int): Call<List<APIObject>>
|
||||
|
||||
/**
|
||||
* Used in the subsequent calls to get more objects.
|
||||
* @param requestedLoadSize number of objects requested in a call
|
||||
* @param key of the last object we already have
|
||||
* @return [Call] that gets the list of [APIObject]
|
||||
*/
|
||||
abstract fun makeAfterCall(requestedLoadSize: Int, key: ObjectId): Call<List<APIObject>>
|
||||
|
||||
/**
|
||||
* This is called to initialize the list, so we want some of the most recent objects.
|
||||
* @param params holds the requestedLoadSize
|
||||
* @param callback to call after network request completes
|
||||
*/
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<ObjectId>,
|
||||
callback: LoadInitialCallback<APIObject>
|
||||
) {
|
||||
enqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called to when we get to the bottom of the loaded content, so we want objects
|
||||
* older than the given key (params.key).
|
||||
* @param params holds the requestedLoadSize
|
||||
* @param callback to call after network request completes
|
||||
*/
|
||||
override fun loadAfter(params: LoadParams<ObjectId>, callback: LoadCallback<APIObject>) {
|
||||
enqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing here, it is expected to pull to refresh to load newer notifications
|
||||
*/
|
||||
override fun loadBefore(params: LoadParams<ObjectId>, callback: LoadCallback<APIObject>) {}
|
||||
|
||||
abstract fun enqueueCall(call: Call<List<APIObject>>, callback: LoadCallback<APIObject>)
|
||||
|
||||
abstract fun newSource(): FeedDataSource<ObjectId, APIObject>
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +139,6 @@ abstract class FeedsRecyclerViewAdapter<T: FeedContent, VH : RecyclerView.ViewHo
|
|||
}
|
||||
}
|
||||
){
|
||||
|
||||
protected lateinit var context: Context
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
|
@ -29,14 +31,20 @@ import com.h.pixeldroid.objects.Status
|
|||
import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText
|
||||
import kotlinx.android.synthetic.main.fragment_notifications.view.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
|
||||
/**
|
||||
* A fragment representing a list of Items.
|
||||
*/
|
||||
class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.NotificationsRecyclerViewAdapter.ViewHolder>() {
|
||||
class NotificationsFragment : FeedFragment() {
|
||||
|
||||
lateinit var profilePicRequest: RequestBuilder<Drawable>
|
||||
protected lateinit var adapter : FeedsRecyclerViewAdapter<Notification, NotificationsRecyclerViewAdapter.ViewHolder>
|
||||
lateinit var factory: FeedDataSourceFactory<String, Notification>
|
||||
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -67,7 +75,7 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
content = makeContent()
|
||||
val content = makeContent()
|
||||
|
||||
content.observe(viewLifecycleOwner,
|
||||
Observer { c ->
|
||||
|
@ -75,22 +83,60 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
|
|||
//after a refresh is done we need to stop the pull to refresh spinner
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
})
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.liveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeContent(): LiveData<PagedList<Notification>> {
|
||||
fun makeInitialCall(requestedLoadSize: Int): Call<List<Notification>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
val dataSource = NotificationListDataSource()
|
||||
factory = FeedDataSourceFactory(dataSource)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
||||
inner class NotificationListDataSource: FeedDataSource<String, Notification>() {
|
||||
|
||||
override fun newSource(): NotificationListDataSource {
|
||||
return NotificationListDataSource()
|
||||
}
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: Notification): String {
|
||||
return item.id
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Notification>> {
|
||||
return pixelfedAPI
|
||||
.notifications("Bearer $accessToken", limit="$requestedLoadSize")
|
||||
}
|
||||
fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Notification>> {
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Notification>> {
|
||||
return pixelfedAPI
|
||||
.notifications("Bearer $accessToken", max_id=key, limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
val dataSource = FeedDataSource(::makeInitialCall, ::makeAfterCall)
|
||||
factory = FeedDataSourceFactory(dataSource)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
override fun enqueueCall(call: Call<List<Notification>>, callback: LoadCallback<Notification>){
|
||||
|
||||
call.enqueue(object : Callback<List<Notification>> {
|
||||
override fun onResponse(call: Call<List<Notification>>, response: Response<List<Notification>>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val data = response.body()!!
|
||||
callback.onResult(data)
|
||||
} else{
|
||||
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
loadingIndicator.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<Notification>>, t: Throwable) {
|
||||
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
|
||||
Log.e("NotificationsFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,13 +20,16 @@ import com.bumptech.glide.Glide
|
|||
import com.bumptech.glide.RequestBuilder
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.h.pixeldroid.MainActivity
|
||||
import com.h.pixeldroid.Pixeldroid
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.PostDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.ImageFragment
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.utils.*
|
||||
import kotlinx.android.synthetic.main.fragment_offline_feed.view.*
|
||||
import kotlinx.android.synthetic.main.post_fragment.view.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class OfflineFeedFragment: Fragment() {
|
||||
|
@ -35,6 +38,9 @@ class OfflineFeedFragment: Fragment() {
|
|||
private lateinit var viewAdapter: RecyclerView.Adapter<*>
|
||||
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||
lateinit var picRequest: RequestBuilder<Drawable>
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -53,7 +59,9 @@ class OfflineFeedFragment: Fragment() {
|
|||
picRequest = Glide.with(this)
|
||||
.asDrawable().fitCenter()
|
||||
.placeholder(ColorDrawable(Color.GRAY))
|
||||
val db = DBUtils.initDB(requireContext())
|
||||
|
||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||
|
||||
val user = db.userDao().getActiveUser()!!
|
||||
if (db.postDao().numberOfPosts(user.user_id, user.instance_uri) > 0) {
|
||||
val posts = db.postDao().getAll(user.user_id, user.instance_uri)
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
package com.h.pixeldroid.fragments.feeds
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import retrofit2.Call
|
||||
|
||||
class PublicTimelineFragment: PostsFeedFragment() {
|
||||
|
||||
inner class SearchFeedDataSource : FeedDataSource(null, null){
|
||||
|
||||
override fun newSource(): SearchFeedDataSource {
|
||||
return SearchFeedDataSource()
|
||||
}
|
||||
|
||||
private fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
return pixelfedAPI.timelinePublic(limit="$requestedLoadSize")
|
||||
}
|
||||
private fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
return pixelfedAPI.timelinePublic( max_id=key, limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<Status>
|
||||
) {
|
||||
enqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Status>) {
|
||||
enqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeContent(): LiveData<PagedList<Status>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = FeedFragment<Status, PostViewHolder>()
|
||||
.FeedDataSourceFactory(SearchFeedDataSource())
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.h.pixeldroid.fragments.feeds.postFeeds
|
||||
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
class HomeTimelineFragment: PostsFeedFragment() {
|
||||
|
||||
override fun makeContent(): LiveData<PagedList<Status>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
val dataSource = PostFeedDataSource()
|
||||
factory = FeedDataSourceFactory(dataSource)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
||||
|
||||
inner class PostFeedDataSource: FeedDataSource<String, Status>() {
|
||||
|
||||
override fun newSource(): PostFeedDataSource {
|
||||
return PostFeedDataSource()
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", max_id=key,
|
||||
limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
//We use the id as the key
|
||||
override fun getKey(item: Status): String {
|
||||
return item.id!!
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Status>>, callback: LoadCallback<Status>){
|
||||
|
||||
call.enqueue(object : Callback<List<Status>> {
|
||||
override fun onResponse(call: Call<List<Status>>, response: Response<List<Status>>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val notifications = response.body()!!
|
||||
callback.onResult(notifications)
|
||||
DBUtils.storePosts(db, notifications, user!!)
|
||||
} else{
|
||||
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
loadingIndicator.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<Status>>, t: Throwable) {
|
||||
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
|
||||
Log.e("PostsFeedFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.h.pixeldroid.fragments.feeds
|
||||
package com.h.pixeldroid.fragments.feeds.postFeeds
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
|
@ -10,7 +10,6 @@ import android.view.ViewGroup
|
|||
import android.widget.*
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import at.connyduck.sparkbutton.SparkButton
|
||||
|
@ -20,24 +19,23 @@ import com.bumptech.glide.RequestBuilder
|
|||
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
|
||||
import com.bumptech.glide.util.ViewPreloadSizeProvider
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.db.UserDatabaseEntity
|
||||
import com.h.pixeldroid.fragments.feeds.FeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.FeedsRecyclerViewAdapter
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.utils.DBUtils
|
||||
import retrofit2.Call
|
||||
|
||||
open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() {
|
||||
abstract class PostsFeedFragment : FeedFragment() {
|
||||
|
||||
lateinit var picRequest: RequestBuilder<Drawable>
|
||||
lateinit var domain : String
|
||||
private var user: UserDatabaseEntity? = null
|
||||
protected lateinit var adapter : FeedsRecyclerViewAdapter<Status, PostViewHolder>
|
||||
lateinit var factory: FeedDataSourceFactory<String, Status>
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||
val db = DBUtils.initDB(requireContext())
|
||||
user = db.userDao().getActiveUser()
|
||||
|
||||
domain = user?.instance_uri.orEmpty()
|
||||
//RequestBuilder that is re-used for every image
|
||||
|
@ -45,14 +43,13 @@ open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() {
|
|||
.asDrawable().fitCenter()
|
||||
.placeholder(ColorDrawable(Color.GRAY))
|
||||
|
||||
adapter = PostsFeedRecyclerViewAdapter(this)
|
||||
adapter = PostsFeedRecyclerViewAdapter()
|
||||
list.adapter = adapter
|
||||
|
||||
|
||||
//Make Glide be aware of the recyclerview and pre-load images
|
||||
val sizeProvider: ListPreloader.PreloadSizeProvider<Status> = ViewPreloadSizeProvider()
|
||||
val preloader: RecyclerViewPreloader<Status> = RecyclerViewPreloader(
|
||||
Glide.with(this), adapter as PostsFeedFragment.PostsFeedRecyclerViewAdapter, sizeProvider, 4
|
||||
Glide.with(this), adapter as PostsFeedRecyclerViewAdapter, sizeProvider, 4
|
||||
)
|
||||
list.addOnScrollListener(preloader)
|
||||
|
||||
|
@ -61,35 +58,26 @@ open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
content = makeContent()
|
||||
val content = makeContent()
|
||||
content.observe(viewLifecycleOwner,
|
||||
Observer { c ->
|
||||
adapter.submitList(c)
|
||||
//after a refresh is done we need to stop the pull to refresh spinner
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
})
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.liveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
internal open fun makeContent(): LiveData<PagedList<Status>> {
|
||||
fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", limit="$requestedLoadSize")
|
||||
}
|
||||
fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
return pixelfedAPI
|
||||
.timelineHome("Bearer $accessToken", max_id=key,
|
||||
limit="$requestedLoadSize")
|
||||
}
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
val dataSource = FeedDataSource(::makeInitialCall, ::makeAfterCall)
|
||||
factory = FeedDataSourceFactory(dataSource)
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
internal abstract fun makeContent(): LiveData<PagedList<Status>>
|
||||
|
||||
/**
|
||||
* [RecyclerView.Adapter] that can display a list of Statuses
|
||||
*/
|
||||
inner class PostsFeedRecyclerViewAdapter(private val postsFeedFragment: PostsFeedFragment)
|
||||
inner class PostsFeedRecyclerViewAdapter
|
||||
: FeedsRecyclerViewAdapter<Status, PostViewHolder>(),
|
||||
ListPreloader.PreloadModelProvider<Status> {
|
||||
private val api = pixelfedAPI
|
||||
|
@ -98,7 +86,10 @@ open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() {
|
|||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.post_fragment, parent, false)
|
||||
context = view.context
|
||||
return PostViewHolder(view, context)
|
||||
return PostViewHolder(
|
||||
view,
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,60 @@
|
|||
package com.h.pixeldroid.fragments.feeds.postFeeds
|
||||
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
class PublicTimelineFragment: PostsFeedFragment() {
|
||||
|
||||
inner class PublicFeedDataSource : FeedDataSource<String, Status>(){
|
||||
|
||||
override fun newSource(): PublicFeedDataSource {
|
||||
return PublicFeedDataSource()
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
return pixelfedAPI.timelinePublic(limit="$requestedLoadSize")
|
||||
}
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
return pixelfedAPI.timelinePublic( max_id=key, limit="$requestedLoadSize")
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Status>>, callback: LoadCallback<Status>) {
|
||||
call.enqueue(object : Callback<List<Status>> {
|
||||
override fun onResponse(call: Call<List<Status>>, response: Response<List<Status>>) {
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
val notifications = response.body()!!
|
||||
callback.onResult(notifications)
|
||||
} else{
|
||||
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
loadingIndicator.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<Status>>, t: Throwable) {
|
||||
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
|
||||
Log.e("PublicTimelineFragment", t.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun getKey(item: Status): String {
|
||||
return item.id!!
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeContent(): LiveData<PagedList<Status>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = FeedDataSourceFactory(PublicFeedDataSource())
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import com.h.pixeldroid.fragments.feeds.AccountListFragment
|
|||
import com.h.pixeldroid.fragments.feeds.FeedFragment
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Results
|
||||
import com.h.pixeldroid.objects.Tag
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
@ -34,35 +35,38 @@ class SearchAccountFragment: AccountListFragment(){
|
|||
return view
|
||||
}
|
||||
|
||||
inner class SearchAccountListDataSource: FeedDataSource(null, null){
|
||||
inner class SearchAccountListDataSource: FeedDataSource<String, Account>(){
|
||||
|
||||
override fun newSource(): FeedDataSource {
|
||||
override fun newSource(): SearchAccountListDataSource {
|
||||
return SearchAccountListDataSource()
|
||||
}
|
||||
|
||||
private fun makeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
override fun getKey(item: Account): String {
|
||||
return item.id
|
||||
}
|
||||
|
||||
private fun searchMakeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken",
|
||||
limit="$requestedLoadSize", q=query,
|
||||
type = Results.SearchType.accounts)
|
||||
}
|
||||
private fun makeAfterCall(requestedLoadSize: Int, key: String): Call<Results> {
|
||||
private fun searchMakeAfterCall(requestedLoadSize: Int, key: String): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken", max_id=key,
|
||||
limit="$requestedLoadSize", q = query,
|
||||
type = Results.SearchType.accounts)
|
||||
}
|
||||
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<Account>
|
||||
) {
|
||||
searchEnqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
searchEnqueueCall(searchMakeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Account>) {
|
||||
searchEnqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
searchEnqueueCall(searchMakeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
private fun searchEnqueueCall(call: Call<Results>, callback: LoadCallback<Account>) {
|
||||
|
||||
|
@ -86,16 +90,22 @@ class SearchAccountFragment: AccountListFragment(){
|
|||
})
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Account>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Account>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Account>>, callback: LoadCallback<Account>) {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeContent(): LiveData<PagedList<Account>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory =
|
||||
FeedFragment<Account, FollowsRecyclerViewAdapter.ViewHolder>()
|
||||
.FeedDataSourceFactory(
|
||||
SearchAccountListDataSource()
|
||||
)
|
||||
factory = FeedFragment().FeedDataSourceFactory(SearchAccountListDataSource())
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
}
|
|
@ -14,8 +14,10 @@ import androidx.paging.LivePagedListBuilder
|
|||
import androidx.paging.PagedList
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.fragments.feeds.AccountListFragment
|
||||
import com.h.pixeldroid.fragments.feeds.FeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.FeedsRecyclerViewAdapter
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Results
|
||||
import com.h.pixeldroid.objects.Tag
|
||||
import kotlinx.android.synthetic.main.fragment_tags.view.*
|
||||
|
@ -23,9 +25,13 @@ import retrofit2.Call
|
|||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
class SearchHashtagFragment: FeedFragment<Tag, SearchHashtagFragment.TagsRecyclerViewAdapter.ViewHolder>(){
|
||||
class SearchHashtagFragment: FeedFragment(){
|
||||
|
||||
private lateinit var query: String
|
||||
private lateinit var content: LiveData<PagedList<Tag>>
|
||||
protected lateinit var adapter : TagsRecyclerViewAdapter
|
||||
lateinit var factory: FeedDataSourceFactory<Int, Tag>
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -51,43 +57,45 @@ class SearchHashtagFragment: FeedFragment<Tag, SearchHashtagFragment.TagsRecycle
|
|||
//after a refresh is done we need to stop the pull to refresh spinner
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
})
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
//by invalidating data, loadInitial will be called again
|
||||
factory.liveData.value!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
inner class SearchTagsListDataSource: FeedDataSource(null, null){
|
||||
inner class SearchTagsListDataSource: FeedDataSource<Int, Tag>(){
|
||||
|
||||
override fun newSource(): FeedDataSource {
|
||||
override fun newSource(): SearchTagsListDataSource {
|
||||
return SearchTagsListDataSource()
|
||||
}
|
||||
|
||||
private fun makeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
private fun searchMakeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken",
|
||||
limit="$requestedLoadSize", q=query,
|
||||
type = Results.SearchType.hashtags)
|
||||
}
|
||||
private fun makeAfterCall(requestedLoadSize: Int, key: String): Call<Results> {
|
||||
private fun searchMakeAfterCall(requestedLoadSize: Int, key: Int): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken", offset=key.toInt(),
|
||||
.search("Bearer $accessToken", offset=key,
|
||||
limit="$requestedLoadSize", q = query,
|
||||
type = Results.SearchType.hashtags)
|
||||
}
|
||||
|
||||
override fun getKey(item: Tag): String {
|
||||
override fun getKey(item: Tag): Int {
|
||||
val value = content.value
|
||||
val count = value?.loadedCount ?: 0
|
||||
return count.toString()
|
||||
return value?.loadedCount ?: 0
|
||||
}
|
||||
override fun loadInitial(
|
||||
params: LoadInitialParams<String>,
|
||||
params: LoadInitialParams<Int>,
|
||||
callback: LoadInitialCallback<Tag>
|
||||
) {
|
||||
searchEnqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
searchEnqueueCall(searchMakeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Tag>) {
|
||||
searchEnqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Tag>) {
|
||||
searchEnqueueCall(searchMakeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
|
||||
private fun searchEnqueueCall(call: Call<Results>, callback: LoadCallback<Tag>){
|
||||
|
@ -111,12 +119,24 @@ class SearchHashtagFragment: FeedFragment<Tag, SearchHashtagFragment.TagsRecycle
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Tag>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: Int): Call<List<Tag>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Tag>>, callback: LoadCallback<Tag>) {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeContent(): LiveData<PagedList<Tag>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory =
|
||||
FeedFragment<Tag, TagsRecyclerViewAdapter.ViewHolder>()
|
||||
FeedFragment()
|
||||
.FeedDataSourceFactory(
|
||||
SearchTagsListDataSource()
|
||||
)
|
||||
|
|
|
@ -9,8 +9,7 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import com.h.pixeldroid.fragments.feeds.FeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.PostsFeedFragment
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostsFeedFragment
|
||||
import com.h.pixeldroid.objects.Results
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import retrofit2.Call
|
||||
|
@ -33,19 +32,19 @@ class SearchPostsFragment: PostsFeedFragment(){
|
|||
return view
|
||||
}
|
||||
|
||||
inner class SearchFeedDataSource : FeedDataSource(null, null){
|
||||
inner class SearchFeedDataSource : FeedDataSource<String, Status>(){
|
||||
|
||||
override fun newSource(): FeedDataSource {
|
||||
override fun newSource(): SearchFeedDataSource {
|
||||
return SearchFeedDataSource()
|
||||
}
|
||||
|
||||
private fun makeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
private fun searchMakeInitialCall(requestedLoadSize: Int): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken",
|
||||
limit="$requestedLoadSize", q=query,
|
||||
type = Results.SearchType.statuses)
|
||||
}
|
||||
private fun makeAfterCall(requestedLoadSize: Int, key: String): Call<Results> {
|
||||
private fun searchMakeAfterCall(requestedLoadSize: Int, key: String): Call<Results> {
|
||||
return pixelfedAPI
|
||||
.search("Bearer $accessToken", max_id=key,
|
||||
limit="$requestedLoadSize", q = query,
|
||||
|
@ -55,13 +54,11 @@ class SearchPostsFragment: PostsFeedFragment(){
|
|||
params: LoadInitialParams<String>,
|
||||
callback: LoadInitialCallback<Status>
|
||||
) {
|
||||
searchEnqueueCall(makeInitialCall(params.requestedLoadSize), callback)
|
||||
searchEnqueueCall(searchMakeInitialCall(params.requestedLoadSize), callback)
|
||||
}
|
||||
|
||||
//This is called to when we get to the bottom of the loaded content, so we want statuses
|
||||
//older than the given key (params.key)
|
||||
override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<Status>) {
|
||||
searchEnqueueCall(makeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
searchEnqueueCall(searchMakeAfterCall(params.requestedLoadSize, params.key), callback)
|
||||
}
|
||||
|
||||
private fun searchEnqueueCall(call: Call<Results>, callback: LoadCallback<Status>){
|
||||
|
@ -84,13 +81,28 @@ class SearchPostsFragment: PostsFeedFragment(){
|
|||
}
|
||||
})
|
||||
}
|
||||
override fun makeInitialCall(requestedLoadSize: Int): Call<List<Status>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Status>> {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun enqueueCall(call: Call<List<Status>>, callback: LoadCallback<Status>) {
|
||||
throw NotImplementedError("Should not be called, reimplemented for Search fragment")
|
||||
}
|
||||
|
||||
override fun getKey(item: Status): String {
|
||||
return item.id!!
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun makeContent(): LiveData<PagedList<Status>> {
|
||||
val config: PagedList.Config = PagedList.Config.Builder().setPageSize(10).build()
|
||||
factory = FeedFragment<Status, PostViewHolder>()
|
||||
factory = FeedFragment()
|
||||
.FeedDataSourceFactory(SearchFeedDataSource())
|
||||
return LivePagedListBuilder(factory, config).build()
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import android.view.View
|
|||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.*
|
||||
import androidx.core.text.toSpanned
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
@ -20,7 +19,7 @@ import com.google.android.material.tabs.TabLayoutMediator
|
|||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.fragments.ImageFragment
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.utils.HtmlUtils.Companion.getDomain
|
||||
import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText
|
||||
import com.h.pixeldroid.utils.ImageConverter
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.h.pixeldroid.utils
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import com.h.pixeldroid.db.AppDatabase
|
||||
import com.h.pixeldroid.db.InstanceDatabaseEntity
|
||||
import com.h.pixeldroid.db.PostDatabaseEntity
|
||||
|
@ -15,12 +13,6 @@ class DBUtils {
|
|||
companion object {
|
||||
private const val MAX_NUMBER_OF_STORED_POSTS = 200
|
||||
|
||||
fun initDB(context: Context): AppDatabase {
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
AppDatabase::class.java, "pixeldroid"
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
||||
private fun normalizeOrNot(uri: String): String{
|
||||
return if(uri.startsWith("http://localhost")){
|
||||
uri
|
||||
|
|
|
@ -8,7 +8,7 @@ import android.widget.LinearLayout
|
|||
import android.widget.Toast
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||
import com.h.pixeldroid.objects.Context
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import com.h.pixeldroid.utils.ImageConverter.Companion.setImageFromDrawable
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Mon Jun 01 23:59:23 CEST 2020
|
||||
#Sun Jul 26 16:18:03 CEST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
|
||||
|
|
Loading…
Reference in New Issue