Add Dagger (#554)
* Add Dagger DI * Preemptively fix tests * Add missing licenses * DI fixes * ci fixes
This commit is contained in:
parent
f5958cd28d
commit
f43ef319d0
|
@ -44,6 +44,7 @@ android {
|
|||
}
|
||||
|
||||
ext.supportLibraryVersion = '27.1.0'
|
||||
ext.daggerVersion = '2.15'
|
||||
|
||||
dependencies {
|
||||
implementation('com.mikepenz:materialdrawer:6.0.6@aar') {
|
||||
|
@ -77,6 +78,13 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
implementation "com.google.dagger:dagger-android:$daggerVersion"
|
||||
implementation "com.google.dagger:dagger-android-support:$daggerVersion"
|
||||
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
|
||||
|
||||
testImplementation "org.robolectric:robolectric:3.7.1"
|
||||
testCompile "org.mockito:mockito-inline:2.15.0"
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
|
|
|
@ -64,3 +64,5 @@
|
|||
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
|
||||
}
|
||||
|
||||
-dontwarn com.google.errorprone.annotations.*
|
|
@ -2,6 +2,7 @@ package com.keylesspalace.tusky;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
@ -10,17 +11,24 @@ import android.view.View;
|
|||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.Account;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class AboutActivity extends BaseActivity {
|
||||
public class AboutActivity extends BaseActivity implements Injectable {
|
||||
private Button appAccountButton;
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -42,12 +50,7 @@ public class AboutActivity extends BaseActivity {
|
|||
versionTextView.setText(String.format(versionFormat, versionName));
|
||||
|
||||
appAccountButton = findViewById(R.id.tusky_profile_button);
|
||||
appAccountButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onAccountButtonClick();
|
||||
}
|
||||
});
|
||||
appAccountButton.setOnClickListener(v -> onAccountButtonClick());
|
||||
}
|
||||
|
||||
private void onAccountButtonClick() {
|
||||
|
@ -68,10 +71,10 @@ public class AboutActivity extends BaseActivity {
|
|||
private void searchForAccountThenViewIt() {
|
||||
Callback<List<Account>> callback = new Callback<List<Account>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<Account>> call, Response<List<Account>> response) {
|
||||
public void onResponse(@NonNull Call<List<Account>> call, @NonNull Response<List<Account>> response) {
|
||||
if (response.isSuccessful()) {
|
||||
List<Account> accountList = response.body();
|
||||
if (!accountList.isEmpty()) {
|
||||
if (accountList != null && !accountList.isEmpty()) {
|
||||
String id = accountList.get(0).getId();
|
||||
getPrivatePreferences().edit()
|
||||
.putString("appAccountId", id)
|
||||
|
@ -86,7 +89,7 @@ public class AboutActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<Account>> call, Throwable t) {
|
||||
public void onFailure(@NonNull Call<List<Account>> call, @NonNull Throwable t) {
|
||||
onSearchFailed();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ import android.support.design.widget.CollapsingToolbarLayout;
|
|||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
@ -51,6 +52,7 @@ import com.keylesspalace.tusky.entity.Account;
|
|||
import com.keylesspalace.tusky.entity.Relationship;
|
||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity;
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.pager.AccountPagerAdapter;
|
||||
import com.keylesspalace.tusky.receiver.TimelineReceiver;
|
||||
import com.keylesspalace.tusky.util.Assert;
|
||||
|
@ -64,11 +66,17 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public final class AccountActivity extends BaseActivity implements ActionButtonActivity {
|
||||
public final class AccountActivity extends BaseActivity implements ActionButtonActivity,
|
||||
HasSupportFragmentInjector {
|
||||
private static final String TAG = "AccountActivity"; // logging tag
|
||||
|
||||
private enum FollowState {
|
||||
|
@ -77,6 +85,11 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
|
|||
REQUESTED,
|
||||
}
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
|
||||
|
||||
private String accountId;
|
||||
private FollowState followState;
|
||||
private boolean blocking;
|
||||
|
@ -690,4 +703,8 @@ public final class AccountActivity extends BaseActivity implements ActionButtonA
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Intent;
|
|||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
@ -27,7 +28,16 @@ import android.view.MenuItem;
|
|||
|
||||
import com.keylesspalace.tusky.fragment.AccountListFragment;
|
||||
|
||||
public final class AccountListActivity extends BaseActivity {
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
|
||||
public final class AccountListActivity extends BaseActivity implements HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
|
||||
|
||||
private static final String TYPE_EXTRA = "type";
|
||||
private static final String ARG_EXTRA = "arg";
|
||||
|
@ -131,4 +141,9 @@ public final class AccountListActivity extends BaseActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,41 +25,21 @@ import android.os.Bundle;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.Spanned;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Menu;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.json.SpannedTypeAdapter;
|
||||
import com.keylesspalace.tusky.network.AuthInterceptor;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.util.OkHttpUtils;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
|
||||
import okhttp3.Dispatcher;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
|
||||
public MastodonApi mastodonApi;
|
||||
protected Dispatcher mastodonApiDispatcher;
|
||||
private AccountManager accountManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
accountManager = TuskyApplication.getInstance(this).getServiceLocator()
|
||||
.get(AccountManager.class);
|
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
/* There isn't presently a way to globally change the theme of a whole application at
|
||||
|
@ -84,19 +64,7 @@ public abstract class BaseActivity extends AppCompatActivity {
|
|||
}
|
||||
getTheme().applyStyle(style, false);
|
||||
|
||||
if (redirectIfNotLoggedIn()) {
|
||||
return;
|
||||
}
|
||||
createMastodonApi();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mastodonApiDispatcher != null) {
|
||||
mastodonApiDispatcher.cancelAll();
|
||||
}
|
||||
super.onDestroy();
|
||||
redirectIfNotLoggedIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -123,44 +91,13 @@ public abstract class BaseActivity extends AppCompatActivity {
|
|||
return getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
protected String getBaseUrl() {
|
||||
AccountEntity account = accountManager.getActiveAccount();
|
||||
if (account != null) {
|
||||
return "https://" + account.getDomain();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected void createMastodonApi() {
|
||||
mastodonApiDispatcher = new Dispatcher();
|
||||
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Spanned.class, new SpannedTypeAdapter())
|
||||
.create();
|
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
OkHttpClient.Builder okBuilder =
|
||||
OkHttpUtils.getCompatibleClientBuilder(preferences)
|
||||
.addInterceptor(new AuthInterceptor(accountManager))
|
||||
.dispatcher(mastodonApiDispatcher);
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
okBuilder.addInterceptor(
|
||||
new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC));
|
||||
}
|
||||
|
||||
Retrofit retrofit = new Retrofit.Builder().baseUrl(getBaseUrl())
|
||||
.client(okBuilder.build())
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.build();
|
||||
|
||||
mastodonApi = retrofit.create(MastodonApi.class);
|
||||
}
|
||||
|
||||
protected boolean redirectIfNotLoggedIn() {
|
||||
if (accountManager.getActiveAccount() == null) {
|
||||
// This is very ugly but we cannot inject into parent class and injecting into every
|
||||
// subclass seems inconvenient as well.
|
||||
AccountEntity account = ((TuskyApplication) getApplicationContext())
|
||||
.getServiceLocator().get(AccountManager.class)
|
||||
.getActiveAccount();
|
||||
if (account == null) {
|
||||
Intent intent = new Intent(this, LoginActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
|
|
|
@ -82,10 +82,12 @@ import com.keylesspalace.tusky.db.AccountEntity;
|
|||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.db.TootDao;
|
||||
import com.keylesspalace.tusky.db.TootEntity;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.Account;
|
||||
import com.keylesspalace.tusky.entity.Attachment;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.fragment.ComposeOptionsFragment;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.network.ProgressRequestBody;
|
||||
import com.keylesspalace.tusky.util.CountUpDownLatch;
|
||||
import com.keylesspalace.tusky.util.DownsizeImageTask;
|
||||
|
@ -115,6 +117,8 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import retrofit2.Call;
|
||||
|
@ -122,7 +126,9 @@ import retrofit2.Callback;
|
|||
import retrofit2.Response;
|
||||
|
||||
public final class ComposeActivity extends BaseActivity
|
||||
implements ComposeOptionsFragment.Listener, MentionAutoCompleteAdapter.AccountSearchProvider {
|
||||
implements ComposeOptionsFragment.Listener,
|
||||
MentionAutoCompleteAdapter.AccountSearchProvider,
|
||||
Injectable {
|
||||
private static final String TAG = "ComposeActivity"; // logging tag
|
||||
private static final int STATUS_CHARACTER_LIMIT = 500;
|
||||
private static final int STATUS_MEDIA_SIZE_LIMIT = 8388608; // 8MiB
|
||||
|
@ -145,6 +151,11 @@ public final class ComposeActivity extends BaseActivity
|
|||
|
||||
private static TootDao tootDao = TuskyApplication.getDB().tootDao();
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
@Inject
|
||||
public AccountManager accountManager;
|
||||
|
||||
private TextView replyTextView;
|
||||
private TextView replyContentTextView;
|
||||
private EditTextTyped textEditor;
|
||||
|
@ -206,11 +217,9 @@ public final class ComposeActivity extends BaseActivity
|
|||
}
|
||||
|
||||
// setup the account image
|
||||
AccountEntity activeAccount = TuskyApplication.getInstance(this).getServiceLocator()
|
||||
.get(AccountManager.class).getActiveAccount();
|
||||
final AccountEntity activeAccount = accountManager.getActiveAccount();
|
||||
|
||||
if (activeAccount != null) {
|
||||
|
||||
ImageView composeAvatar = findViewById(R.id.composeAvatar);
|
||||
|
||||
if (TextUtils.isEmpty(activeAccount.getProfilePictureUrl())) {
|
||||
|
|
|
@ -32,7 +32,9 @@ import android.util.Log
|
|||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.IOUtils
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.theartofdev.edmodo.cropper.CropImage
|
||||
|
@ -46,6 +48,7 @@ import retrofit2.Callback
|
|||
import retrofit2.Response
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val TAG = "EditProfileActivity"
|
||||
|
||||
|
@ -66,7 +69,7 @@ private const val AVATAR_SIZE = 120
|
|||
private const val HEADER_WIDTH = 700
|
||||
private const val HEADER_HEIGHT = 335
|
||||
|
||||
class EditProfileActivity : BaseActivity() {
|
||||
class EditProfileActivity : BaseActivity(), Injectable {
|
||||
|
||||
private var oldDisplayName: String? = null
|
||||
private var oldNote: String? = null
|
||||
|
@ -75,6 +78,9 @@ class EditProfileActivity : BaseActivity() {
|
|||
private var avatarChanged: Boolean = false
|
||||
private var headerChanged: Boolean = false
|
||||
|
||||
@Inject
|
||||
lateinit var mastodonApi: MastodonApi
|
||||
|
||||
private enum class PickType {
|
||||
NOTHING,
|
||||
AVATAR,
|
||||
|
@ -100,11 +106,11 @@ class EditProfileActivity : BaseActivity() {
|
|||
avatarChanged = it.getBoolean(KEY_AVATAR_CHANGED)
|
||||
headerChanged = it.getBoolean(KEY_HEADER_CHANGED)
|
||||
|
||||
if(avatarChanged) {
|
||||
if (avatarChanged) {
|
||||
val avatar = BitmapFactory.decodeFile(getCacheFileForName(AVATAR_FILE_NAME).absolutePath)
|
||||
avatarPreview.setImageBitmap(avatar)
|
||||
}
|
||||
if(headerChanged) {
|
||||
if (headerChanged) {
|
||||
val header = BitmapFactory.decodeFile(getCacheFileForName(HEADER_FILE_NAME).absolutePath)
|
||||
headerPreview.setImageBitmap(header)
|
||||
}
|
||||
|
@ -135,13 +141,13 @@ class EditProfileActivity : BaseActivity() {
|
|||
|
||||
displayNameEditText.setText(oldDisplayName)
|
||||
noteEditText.setText(oldNote)
|
||||
if(!avatarChanged) {
|
||||
if (!avatarChanged) {
|
||||
Picasso.with(avatarPreview.context)
|
||||
.load(me.avatar)
|
||||
.placeholder(R.drawable.avatar_default)
|
||||
.into(avatarPreview)
|
||||
}
|
||||
if(!headerChanged) {
|
||||
if (!headerChanged) {
|
||||
Picasso.with(headerPreview.context)
|
||||
.load(me.header)
|
||||
.placeholder(R.drawable.account_header_default)
|
||||
|
@ -253,21 +259,21 @@ class EditProfileActivity : BaseActivity() {
|
|||
RequestBody.create(MultipartBody.FORM, newNote)
|
||||
}
|
||||
|
||||
val avatar = if(avatarChanged) {
|
||||
val avatar = if (avatarChanged) {
|
||||
val avatarBody = RequestBody.create(MediaType.parse("image/png"), getCacheFileForName(AVATAR_FILE_NAME))
|
||||
MultipartBody.Part.createFormData("avatar", getFileName(), avatarBody)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val header = if(headerChanged) {
|
||||
val header = if (headerChanged) {
|
||||
val headerBody = RequestBody.create(MediaType.parse("image/png"), getCacheFileForName(HEADER_FILE_NAME))
|
||||
MultipartBody.Part.createFormData("header", getFileName(), headerBody)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
if(displayName == null && note == null && avatar == null && header == null) {
|
||||
if (displayName == null && note == null && avatar == null && header == null) {
|
||||
/** if nothing has changed, there is no need to make a network request */
|
||||
finish()
|
||||
return
|
||||
|
@ -413,11 +419,11 @@ class EditProfileActivity : BaseActivity() {
|
|||
return java.lang.Long.toHexString(Random().nextLong())
|
||||
}
|
||||
|
||||
private class ResizeImageTask (private val contentResolver: ContentResolver,
|
||||
private val resizeWidth: Int,
|
||||
private val resizeHeight: Int,
|
||||
private val cacheFile: File,
|
||||
private val listener: Listener) : AsyncTask<Uri, Void, Boolean>() {
|
||||
private class ResizeImageTask(private val contentResolver: ContentResolver,
|
||||
private val resizeWidth: Int,
|
||||
private val resizeHeight: Int,
|
||||
private val cacheFile: File,
|
||||
private val listener: Listener) : AsyncTask<Uri, Void, Boolean>() {
|
||||
private var resultBitmap: Bitmap? = null
|
||||
|
||||
override fun doInBackground(vararg uris: Uri): Boolean? {
|
||||
|
@ -445,7 +451,7 @@ class EditProfileActivity : BaseActivity() {
|
|||
|
||||
//dont upscale image if its smaller than the desired size
|
||||
val bitmap =
|
||||
if(sourceBitmap.width <= resizeWidth && sourceBitmap.height <= resizeHeight) {
|
||||
if (sourceBitmap.width <= resizeWidth && sourceBitmap.height <= resizeHeight) {
|
||||
sourceBitmap
|
||||
} else {
|
||||
Bitmap.createScaledBitmap(sourceBitmap, resizeWidth, resizeHeight, true)
|
||||
|
|
|
@ -25,7 +25,17 @@ import android.view.MenuItem;
|
|||
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment;
|
||||
|
||||
public class FavouritesActivity extends BaseActivity {
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
|
||||
public class FavouritesActivity extends BaseActivity implements HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -56,4 +66,9 @@ public class FavouritesActivity extends BaseActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,19 +12,19 @@ import android.view.LayoutInflater
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.entity.MastoList
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.varunest.sparkbutton.helpers.Utils
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import java.lang.ref.WeakReference
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by charlag on 1/4/18.
|
||||
|
@ -83,7 +83,7 @@ class ListsViewModel(private val api: MastodonApi) {
|
|||
}
|
||||
}
|
||||
|
||||
class ListsActivity : BaseActivity(), ListsView {
|
||||
class ListsActivity : BaseActivity(), ListsView, Injectable {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
@ -92,6 +92,9 @@ class ListsActivity : BaseActivity(), ListsView {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var mastodonApi: MastodonApi
|
||||
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private lateinit var progressBar: ProgressBar
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.support.annotation.Nullable;
|
|||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
@ -40,6 +41,7 @@ import com.keylesspalace.tusky.db.AccountEntity;
|
|||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.entity.Account;
|
||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.pager.TimelinePagerAdapter;
|
||||
import com.keylesspalace.tusky.receiver.TimelineReceiver;
|
||||
import com.keylesspalace.tusky.util.NotificationHelper;
|
||||
|
@ -63,11 +65,18 @@ import com.squareup.picasso.Picasso;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.AndroidSupportInjection;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class MainActivity extends BaseActivity implements ActionButtonActivity {
|
||||
public class MainActivity extends BaseActivity implements ActionButtonActivity,
|
||||
HasSupportFragmentInjector {
|
||||
private static final String TAG = "MainActivity"; // logging tag
|
||||
private static final long DRAWER_ITEM_ADD_ACCOUNT = -13;
|
||||
private static final long DRAWER_ITEM_EDIT_PROFILE = 0;
|
||||
|
@ -82,6 +91,11 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
|
|||
private static final long DRAWER_ITEM_SAVED_TOOT = 9;
|
||||
private static final long DRAWER_ITEM_LISTS = 10;
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> fragmentInjector;
|
||||
|
||||
private static int COMPOSE_RESULT = 1;
|
||||
|
||||
AccountManager accountManager;
|
||||
|
@ -93,10 +107,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
// account switching has to be done before MastodonApi is created in super.onCreate
|
||||
Intent intent = getIntent();
|
||||
|
||||
int tabPosition = 0;
|
||||
|
||||
accountManager = TuskyApplication.getInstance(this).getServiceLocator()
|
||||
|
@ -550,4 +561,9 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
|
|||
public FloatingActionButton getActionButton() {
|
||||
return composeButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return fragmentInjector;
|
||||
}
|
||||
}
|
|
@ -4,19 +4,29 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.design.widget.FloatingActionButton
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.view.MenuItem
|
||||
import android.widget.FrameLayout
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment
|
||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.DispatchingAndroidInjector
|
||||
import dagger.android.support.HasSupportFragmentInjector
|
||||
import javax.inject.Inject
|
||||
|
||||
class ModalTimelineActivity : BaseActivity(), ActionButtonActivity, HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
|
||||
|
||||
class ModalTimelineActivity : BaseActivity(), ActionButtonActivity {
|
||||
companion object {
|
||||
|
||||
private const val ARG_KIND = "kind"
|
||||
private const val ARG_ARG = "arg"
|
||||
@JvmStatic fun newIntent(context: Context, kind: TimelineFragment.Kind,
|
||||
argument: String?): Intent {
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context, kind: TimelineFragment.Kind,
|
||||
argument: String?): Intent {
|
||||
val intent = Intent(context, ModalTimelineActivity::class.java)
|
||||
intent.putExtra(ARG_KIND, kind)
|
||||
intent.putExtra(ARG_ARG, argument)
|
||||
|
@ -24,6 +34,7 @@ class ModalTimelineActivity : BaseActivity(), ActionButtonActivity {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
lateinit var contentFrame: FrameLayout
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -41,8 +52,8 @@ class ModalTimelineActivity : BaseActivity(), ActionButtonActivity {
|
|||
}
|
||||
|
||||
if (supportFragmentManager.findFragmentById(R.id.content_frame) == null) {
|
||||
val kind = intent?.getSerializableExtra(ARG_KIND) as? TimelineFragment.Kind ?:
|
||||
TimelineFragment.Kind.HOME
|
||||
val kind = intent?.getSerializableExtra(ARG_KIND) as? TimelineFragment.Kind
|
||||
?: TimelineFragment.Kind.HOME
|
||||
val argument = intent?.getStringExtra(ARG_ARG)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.content_frame, TimelineFragment.newInstance(kind, argument))
|
||||
|
@ -60,4 +71,8 @@ class ModalTimelineActivity : BaseActivity(), ActionButtonActivity {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
|
||||
return dispatchingAndroidInjector
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,23 +16,17 @@
|
|||
package com.keylesspalace.tusky;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobCreator;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.entity.Notification;
|
||||
import com.keylesspalace.tusky.json.SpannedTypeAdapter;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.util.NotificationHelper;
|
||||
import com.keylesspalace.tusky.util.OkHttpUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
@ -40,10 +34,9 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
/**
|
||||
* Created by charlag on 31/10/17.
|
||||
|
@ -55,65 +48,53 @@ public final class NotificationPullJobCreator implements JobCreator {
|
|||
|
||||
static final String NOTIFICATIONS_JOB_TAG = "notifications_job_tag";
|
||||
|
||||
private Context context;
|
||||
private final MastodonApi api;
|
||||
private final Context context;
|
||||
private final AccountManager accountManager;
|
||||
|
||||
NotificationPullJobCreator(Context context) {
|
||||
@Inject NotificationPullJobCreator(MastodonApi api, Context context,
|
||||
AccountManager accountManager) {
|
||||
this.api = api;
|
||||
this.context = context;
|
||||
this.accountManager = accountManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Job create(@NonNull String tag) {
|
||||
if (tag.equals(NOTIFICATIONS_JOB_TAG)) {
|
||||
return new NotificationPullJob(context);
|
||||
return new NotificationPullJob(context, accountManager, api);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MastodonApi createMastodonApi(String domain, Context context) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(
|
||||
context.getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
|
||||
|
||||
OkHttpClient okHttpClient = OkHttpUtils.getCompatibleClientBuilder(preferences)
|
||||
.build();
|
||||
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Spanned.class, new SpannedTypeAdapter())
|
||||
.create();
|
||||
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl("https://" + domain)
|
||||
.client(okHttpClient)
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.build();
|
||||
|
||||
return retrofit.create(MastodonApi.class);
|
||||
}
|
||||
|
||||
private final static class NotificationPullJob extends Job {
|
||||
|
||||
private Context context;
|
||||
private final Context context;
|
||||
private final AccountManager accountManager;
|
||||
private final MastodonApi mastodonApi;
|
||||
|
||||
NotificationPullJob(Context context) {
|
||||
NotificationPullJob(Context context, AccountManager accountManager,
|
||||
MastodonApi mastodonApi) {
|
||||
this.context = context;
|
||||
this.accountManager = accountManager;
|
||||
this.mastodonApi = mastodonApi;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Result onRunJob(@NonNull Params params) {
|
||||
|
||||
AccountManager accountManager = TuskyApplication.getInstance(context).getServiceLocator()
|
||||
.get(AccountManager.class);
|
||||
List<AccountEntity> accountList = new ArrayList<>(accountManager.getAllAccountsOrderedByActive());
|
||||
|
||||
for (AccountEntity account : accountList) {
|
||||
|
||||
if (account.getNotificationsEnabled()) {
|
||||
MastodonApi api = createMastodonApi(account.getDomain(), context);
|
||||
try {
|
||||
Log.d(TAG, "getting Notifications for " + account.getFullName());
|
||||
Response<List<Notification>> notifications =
|
||||
api.notificationsWithAuth(String.format("Bearer %s", account.getAccessToken())).execute();
|
||||
mastodonApi.notificationsWithAuth(
|
||||
String.format("Bearer %s", account.getAccessToken()),
|
||||
account.getDomain()
|
||||
)
|
||||
.execute();
|
||||
if (notifications.isSuccessful()) {
|
||||
onNotificationsReceived(account, notifications.body());
|
||||
} else {
|
||||
|
@ -127,22 +108,15 @@ public final class NotificationPullJobCreator implements JobCreator {
|
|||
}
|
||||
|
||||
return Result.SUCCESS;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void onNotificationsReceived(AccountEntity account, List<Notification> notificationList) {
|
||||
|
||||
Collections.reverse(notificationList);
|
||||
|
||||
BigInteger newId = new BigInteger(account.getLastNotificationId());
|
||||
|
||||
BigInteger newestId = BigInteger.ZERO;
|
||||
|
||||
for (Notification notification : notificationList) {
|
||||
|
||||
BigInteger currentId = new BigInteger(notification.getId());
|
||||
|
||||
if (isBiggerThan(currentId, newestId)) {
|
||||
newestId = currentId;
|
||||
}
|
||||
|
@ -153,12 +127,10 @@ public final class NotificationPullJobCreator implements JobCreator {
|
|||
}
|
||||
|
||||
account.setLastNotificationId(newestId.toString());
|
||||
TuskyApplication.getInstance(context).getServiceLocator()
|
||||
.get(AccountManager.class).saveAccount(account);
|
||||
accountManager.saveAccount(account);
|
||||
}
|
||||
|
||||
private boolean isBiggerThan(BigInteger newId, BigInteger lastShownNotificationId) {
|
||||
|
||||
return lastShownNotificationId.compareTo(newId) == -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@ import android.view.View;
|
|||
import android.widget.EditText;
|
||||
|
||||
import com.keylesspalace.tusky.adapter.ReportAdapter;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.util.HtmlUtils;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
|
||||
|
@ -40,14 +42,19 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class ReportActivity extends BaseActivity {
|
||||
public class ReportActivity extends BaseActivity implements Injectable {
|
||||
private static final String TAG = "ReportActivity"; // logging tag
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
|
||||
private View anyView; // what Snackbar will use to find the root view
|
||||
private ReportAdapter adapter;
|
||||
private boolean reportAlreadyInFlight;
|
||||
|
@ -118,7 +125,7 @@ public class ReportActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
private void sendReport(final String accountId, final String[] statusIds,
|
||||
final String comment) {
|
||||
final String comment) {
|
||||
Callback<ResponseBody> callback = new Callback<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
|
||||
|
@ -145,7 +152,7 @@ public class ReportActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
private void onSendFailure(final String accountId, final String[] statusIds,
|
||||
final String comment) {
|
||||
final String comment) {
|
||||
Snackbar.make(anyView, R.string.error_generic, Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.action_retry, new View.OnClickListener() {
|
||||
@Override
|
||||
|
|
|
@ -35,17 +35,24 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.keylesspalace.tusky.adapter.SearchResultsAdapter;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.SearchResults;
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class SearchActivity extends BaseActivity implements SearchView.OnQueryTextListener,
|
||||
LinkListener {
|
||||
LinkListener, Injectable {
|
||||
private static final String TAG = "SearchActivity"; // logging tag
|
||||
|
||||
@Inject
|
||||
public MastodonApi mastodonApi;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private TextView messageNoResults;
|
||||
private SearchResultsAdapter adapter;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
package com.keylesspalace.tusky;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.app.UiModeManager;
|
||||
import android.arch.persistence.room.Room;
|
||||
|
@ -28,15 +29,26 @@ import com.evernote.android.job.JobManager;
|
|||
import com.jakewharton.picasso.OkHttp3Downloader;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.db.AppDatabase;
|
||||
import com.keylesspalace.tusky.di.AppInjector;
|
||||
import com.keylesspalace.tusky.util.OkHttpUtils;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
public class TuskyApplication extends Application {
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.HasActivityInjector;
|
||||
|
||||
public class TuskyApplication extends Application implements HasActivityInjector {
|
||||
public static final String APP_THEME_DEFAULT = ThemeUtils.THEME_NIGHT;
|
||||
|
||||
private static AppDatabase db;
|
||||
private AccountManager accountManager;
|
||||
@Inject
|
||||
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
|
||||
@Inject
|
||||
NotificationPullJobCreator notificationPullJobCreator;
|
||||
|
||||
public static AppDatabase getDB() {
|
||||
return db;
|
||||
|
@ -58,8 +70,12 @@ public class TuskyApplication extends Application {
|
|||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
initPicasso();
|
||||
|
||||
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "tuskyDB")
|
||||
.allowMainThreadQueries()
|
||||
.addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5)
|
||||
.build();
|
||||
accountManager = new AccountManager(db);
|
||||
serviceLocator = new ServiceLocator() {
|
||||
@Override
|
||||
public <T> T get(Class<T> clazz) {
|
||||
|
@ -72,19 +88,14 @@ public class TuskyApplication extends Application {
|
|||
}
|
||||
};
|
||||
|
||||
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "tuskyDB")
|
||||
.allowMainThreadQueries()
|
||||
.addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5)
|
||||
.build();
|
||||
|
||||
JobManager.create(this).addJobCreator(new NotificationPullJobCreator(this));
|
||||
AppInjector.INSTANCE.init(this);
|
||||
initPicasso();
|
||||
|
||||
JobManager.create(this).addJobCreator(notificationPullJobCreator);
|
||||
uiModeManager = (UiModeManager) getSystemService(Context.UI_MODE_SERVICE);
|
||||
|
||||
//necessary for Android < APi 21
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
||||
|
||||
accountManager = new AccountManager();
|
||||
}
|
||||
|
||||
protected void initPicasso() {
|
||||
|
@ -106,6 +117,11 @@ public class TuskyApplication extends Application {
|
|||
return serviceLocator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Activity> activityInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
|
||||
public interface ServiceLocator {
|
||||
<T> T get(Class<T> clazz);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,17 @@ import android.view.MenuItem;
|
|||
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment;
|
||||
|
||||
public class ViewTagActivity extends BaseActivity {
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
|
||||
public class ViewTagActivity extends BaseActivity implements HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -59,4 +69,9 @@ public class ViewTagActivity extends BaseActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,17 @@ import android.view.MenuItem;
|
|||
import com.keylesspalace.tusky.fragment.ViewThreadFragment;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
|
||||
public class ViewThreadActivity extends BaseActivity {
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DispatchingAndroidInjector;
|
||||
import dagger.android.support.HasSupportFragmentInjector;
|
||||
|
||||
public class ViewThreadActivity extends BaseActivity implements HasSupportFragmentInjector {
|
||||
|
||||
@Inject
|
||||
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -69,4 +79,9 @@ public class ViewThreadActivity extends BaseActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||
return dispatchingAndroidInjector;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
package com.keylesspalace.tusky.db
|
||||
|
||||
import android.arch.persistence.room.Database
|
||||
import android.util.Log
|
||||
import com.keylesspalace.tusky.TuskyApplication
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
|
@ -26,12 +27,13 @@ import com.keylesspalace.tusky.entity.Account
|
|||
|
||||
private const val TAG = "AccountManager"
|
||||
|
||||
class AccountManager {
|
||||
class AccountManager(db: AppDatabase) {
|
||||
|
||||
@Volatile var activeAccount: AccountEntity? = null
|
||||
@Volatile
|
||||
var activeAccount: AccountEntity? = null
|
||||
|
||||
private var accounts: MutableList<AccountEntity> = mutableListOf()
|
||||
private val accountDao: AccountDao = TuskyApplication.getDB().accountDao()
|
||||
private val accountDao: AccountDao = db.accountDao()
|
||||
|
||||
init {
|
||||
accounts = accountDao.loadAll().toMutableList()
|
||||
|
@ -50,9 +52,9 @@ class AccountManager {
|
|||
*/
|
||||
fun addAccount(accessToken: String, domain: String) {
|
||||
|
||||
activeAccount?.let{
|
||||
activeAccount?.let {
|
||||
it.isActive = false
|
||||
Log.d(TAG, "addAccount: saving account with id "+it.id)
|
||||
Log.d(TAG, "addAccount: saving account with id " + it.id)
|
||||
|
||||
accountDao.insertOrReplace(it)
|
||||
}
|
||||
|
@ -67,8 +69,8 @@ class AccountManager {
|
|||
* @param account the account to save
|
||||
*/
|
||||
fun saveAccount(account: AccountEntity) {
|
||||
if(account.id != 0L) {
|
||||
Log.d(TAG, "saveAccount: saving account with id "+account.id)
|
||||
if (account.id != 0L) {
|
||||
Log.d(TAG, "saveAccount: saving account with id " + account.id)
|
||||
accountDao.insertOrReplace(account)
|
||||
}
|
||||
|
||||
|
@ -78,18 +80,18 @@ class AccountManager {
|
|||
* Logs the current account out by deleting all data of the account.
|
||||
* @return the new active account, or null if no other account was found
|
||||
*/
|
||||
fun logActiveAccountOut() : AccountEntity? {
|
||||
fun logActiveAccountOut(): AccountEntity? {
|
||||
|
||||
if(activeAccount == null) {
|
||||
if (activeAccount == null) {
|
||||
return null
|
||||
} else {
|
||||
accounts.remove(activeAccount!!)
|
||||
accountDao.delete(activeAccount!!)
|
||||
|
||||
if(accounts.size > 0) {
|
||||
if (accounts.size > 0) {
|
||||
accounts[0].isActive = true
|
||||
activeAccount = accounts[0]
|
||||
Log.d(TAG, "logActiveAccountOut: saving account with id "+accounts[0].id)
|
||||
Log.d(TAG, "logActiveAccountOut: saving account with id " + accounts[0].id)
|
||||
accountDao.insertOrReplace(accounts[0])
|
||||
} else {
|
||||
activeAccount = null
|
||||
|
@ -106,18 +108,18 @@ class AccountManager {
|
|||
* @param account the [Account] object returned from the api
|
||||
*/
|
||||
fun updateActiveAccount(account: Account) {
|
||||
activeAccount?.let{
|
||||
activeAccount?.let {
|
||||
it.accountId = account.id
|
||||
it.username = account.username
|
||||
it.displayName = account.name
|
||||
it.profilePictureUrl = account.avatar
|
||||
|
||||
Log.d(TAG, "updateActiveAccount: saving account with id "+it.id)
|
||||
Log.d(TAG, "updateActiveAccount: saving account with id " + it.id)
|
||||
it.id = accountDao.insertOrReplace(it)
|
||||
|
||||
val accountIndex = accounts.indexOf(it)
|
||||
|
||||
if(accountIndex != -1) {
|
||||
if (accountIndex != -1) {
|
||||
//in case the user was already logged in with this account, remove the old information
|
||||
accounts.removeAt(accountIndex)
|
||||
accounts.add(accountIndex, it)
|
||||
|
@ -134,8 +136,8 @@ class AccountManager {
|
|||
*/
|
||||
fun setActiveAccount(accountId: Long) {
|
||||
|
||||
activeAccount?.let{
|
||||
Log.d(TAG, "setActiveAccount: saving account with id "+it.id)
|
||||
activeAccount?.let {
|
||||
Log.d(TAG, "setActiveAccount: saving account with id " + it.id)
|
||||
it.isActive = false
|
||||
saveAccount(it)
|
||||
}
|
||||
|
@ -144,7 +146,7 @@ class AccountManager {
|
|||
acc.id == accountId
|
||||
}
|
||||
|
||||
activeAccount?.let{
|
||||
activeAccount?.let {
|
||||
it.isActive = true
|
||||
accountDao.insertOrReplace(it)
|
||||
}
|
||||
|
@ -154,7 +156,7 @@ class AccountManager {
|
|||
* @return an immutable list of all accounts in the database with the active account first
|
||||
*/
|
||||
fun getAllAccountsOrderedByActive(): List<AccountEntity> {
|
||||
accounts.sortWith (Comparator { l, r ->
|
||||
accounts.sortWith(Comparator { l, r ->
|
||||
when {
|
||||
l.isActive && !r.isActive -> -1
|
||||
r.isActive && !l.isActive -> 1
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* Copyright 2018 charlag
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.di
|
||||
|
||||
import com.keylesspalace.tusky.*
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||