diff --git a/app/build.gradle b/app/build.gradle index 44828c94..2b2519ee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/androidTest/java/com/h/pixeldroid/DrawerMenuTest.kt b/app/src/androidTest/java/com/h/pixeldroid/DrawerMenuTest.kt index 96e8fffb..017f1bbf 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/DrawerMenuTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/DrawerMenuTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/HomeFeedTest.kt b/app/src/androidTest/java/com/h/pixeldroid/HomeFeedTest.kt index 314ba34a..18e8d418 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/HomeFeedTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/HomeFeedTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/IntentTest.kt b/app/src/androidTest/java/com/h/pixeldroid/IntentTest.kt index f9376eba..4488d361 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/IntentTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/IntentTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOfflineTest.kt b/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOfflineTest.kt index b89cd34f..ac6b1e1a 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOfflineTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOfflineTest.kt @@ -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() - db = DBUtils.initDB(context) + db = initDB(context) db.clearAllTables() ActivityScenario.launch(LoginActivity::class.java) } diff --git a/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOnlineTest.kt b/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOnlineTest.kt index 9ce53e22..22e945ab 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOnlineTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/LoginActivityOnlineTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/MockedServerTest.kt b/app/src/androidTest/java/com/h/pixeldroid/MockedServerTest.kt index 0abb50c0..75cec742 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/MockedServerTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/MockedServerTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/PostCreationActivityTest.kt b/app/src/androidTest/java/com/h/pixeldroid/PostCreationActivityTest.kt index 1400f949..8c2a096f 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/PostCreationActivityTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/PostCreationActivityTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/PostCreationFragmentTest.kt b/app/src/androidTest/java/com/h/pixeldroid/PostCreationFragmentTest.kt index 061f4803..776c5da6 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/PostCreationFragmentTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/PostCreationFragmentTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/PostTest.kt b/app/src/androidTest/java/com/h/pixeldroid/PostTest.kt index b787a9d2..186c69bc 100644 --- a/app/src/androidTest/java/com/h/pixeldroid/PostTest.kt +++ b/app/src/androidTest/java/com/h/pixeldroid/PostTest.kt @@ -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( diff --git a/app/src/androidTest/java/com/h/pixeldroid/testUtility/DbHelpers.kt b/app/src/androidTest/java/com/h/pixeldroid/testUtility/DbHelpers.kt new file mode 100644 index 00000000..ba7a8b2e --- /dev/null +++ b/app/src/androidTest/java/com/h/pixeldroid/testUtility/DbHelpers.kt @@ -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() +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 89f7c3a1..54db9fa2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,13 +16,14 @@ + android:theme="@style/AppTheme" + tools:replace="android:allowBackup"> { diff --git a/app/src/main/java/com/h/pixeldroid/LoginActivity.kt b/app/src/main/java/com/h/pixeldroid/LoginActivity.kt index b80c83b3..29d71d53 100644 --- a/app/src/main/java/com/h/pixeldroid/LoginActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/LoginActivity.kt @@ -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 { override fun onResponse(call: Call, response: Response) { @@ -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 { override fun onResponse(call: Call, response: Response) { 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) diff --git a/app/src/main/java/com/h/pixeldroid/MainActivity.kt b/app/src/main/java/com/h/pixeldroid/MainActivity.kt index 3cf9ded2..b981fcad 100644 --- a/app/src/main/java/com/h/pixeldroid/MainActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/MainActivity.kt @@ -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 { - override fun onResponse(call: Call, response: Response) { + override fun onResponse( + call: Call, + response: Response + ) { 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)){ diff --git a/app/src/main/java/com/h/pixeldroid/Pixeldroid.kt b/app/src/main/java/com/h/pixeldroid/Pixeldroid.kt index 1bee5104..4d33f08b 100644 --- a/app/src/main/java/com/h/pixeldroid/Pixeldroid.kt +++ b/app/src/main/java/com/h/pixeldroid/Pixeldroid.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/PostActivity.kt b/app/src/main/java/com/h/pixeldroid/PostActivity.kt index 200837a2..55cf5c5e 100644 --- a/app/src/main/java/com/h/pixeldroid/PostActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/PostActivity.kt @@ -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 { diff --git a/app/src/main/java/com/h/pixeldroid/PostCreationActivity.kt b/app/src/main/java/com/h/pixeldroid/PostCreationActivity.kt index 44bf5163..a699354d 100644 --- a/app/src/main/java/com/h/pixeldroid/PostCreationActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/PostCreationActivity.kt @@ -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 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 diff --git a/app/src/main/java/com/h/pixeldroid/ProfileActivity.kt b/app/src/main/java/com/h/pixeldroid/ProfileActivity.kt index 627a8d4f..e0d808f6 100644 --- a/app/src/main/java/com/h/pixeldroid/ProfileActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/ProfileActivity.kt @@ -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) diff --git a/app/src/main/java/com/h/pixeldroid/api/PixelfedAPI.kt b/app/src/main/java/com/h/pixeldroid/api/PixelfedAPI.kt index c445f109..78759b8c 100644 --- a/app/src/main/java/com/h/pixeldroid/api/PixelfedAPI.kt +++ b/app/src/main/java/com/h/pixeldroid/api/PixelfedAPI.kt @@ -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 -} +} \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/db/UserDao.kt b/app/src/main/java/com/h/pixeldroid/db/UserDao.kt index 9a67f825..1e41e61e 100644 --- a/app/src/main/java/com/h/pixeldroid/db/UserDao.kt +++ b/app/src/main/java/com/h/pixeldroid/db/UserDao.kt @@ -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) diff --git a/app/src/main/java/com/h/pixeldroid/di/APIModule.kt b/app/src/main/java/com/h/pixeldroid/di/APIModule.kt new file mode 100644 index 00000000..462cbf1e --- /dev/null +++ b/app/src/main/java/com/h/pixeldroid/di/APIModule.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/di/ApplicationComponent.kt b/app/src/main/java/com/h/pixeldroid/di/ApplicationComponent.kt new file mode 100644 index 00000000..49ddb48c --- /dev/null +++ b/app/src/main/java/com/h/pixeldroid/di/ApplicationComponent.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/di/ApplicationModule.kt b/app/src/main/java/com/h/pixeldroid/di/ApplicationModule.kt new file mode 100644 index 00000000..3c85c01a --- /dev/null +++ b/app/src/main/java/com/h/pixeldroid/di/ApplicationModule.kt @@ -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 + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/di/DatabaseModule.kt b/app/src/main/java/com/h/pixeldroid/di/DatabaseModule.kt new file mode 100644 index 00000000..507f6d5c --- /dev/null +++ b/app/src/main/java/com/h/pixeldroid/di/DatabaseModule.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/h/pixeldroid/fragments/PostFragment.kt b/app/src/main/java/com/h/pixeldroid/fragments/PostFragment.kt index 2d3a06c6..002f90b0 100644 --- a/app/src/main/java/com/h/pixeldroid/fragments/PostFragment.kt +++ b/app/src/main/java/com/h/pixeldroid/fragments/PostFragment.kt @@ -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 } diff --git a/app/src/main/java/com/h/pixeldroid/fragments/SearchDiscoverFragment.kt b/app/src/main/java/com/h/pixeldroid/fragments/SearchDiscoverFragment.kt index 7830dcee..5fab7fec 100644 --- a/app/src/main/java/com/h/pixeldroid/fragments/SearchDiscoverFragment.kt +++ b/app/src/main/java/com/h/pixeldroid/fragments/SearchDiscoverFragment.kt @@ -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