mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-01-30 16:35:00 +01:00
fixed user fragment banner flashing
This commit is contained in:
parent
36f92bda17
commit
95354b3e5c
@ -82,8 +82,6 @@ public interface IntentConstants {
|
||||
String BROADCAST_USER_LIST_MEMBERS_ADDED = INTENT_PACKAGE_PREFIX + "USER_LIST_MEMBER_ADDED";
|
||||
String BROADCAST_USER_LIST_SUBSCRIBED = INTENT_PACKAGE_PREFIX + "USER_LIST_SUBSRCIBED";
|
||||
String BROADCAST_USER_LIST_UNSUBSCRIBED = INTENT_PACKAGE_PREFIX + "USER_LIST_UNSUBSCRIBED";
|
||||
String BROADCAST_USER_LIST_CREATED = INTENT_PACKAGE_PREFIX + "USER_LIST_CREATED";
|
||||
String BROADCAST_USER_LIST_DELETED = INTENT_PACKAGE_PREFIX + "USER_LIST_DELETED";
|
||||
String BROADCAST_FILTERS_UPDATED = INTENT_PACKAGE_PREFIX + "FILTERS_UPDATED";
|
||||
String BROADCAST_REFRESH_HOME_TIMELINE = INTENT_PACKAGE_PREFIX + "REFRESH_HOME_TIMELINE";
|
||||
String BROADCAST_REFRESH_NOTIFICATIONS = INTENT_PACKAGE_PREFIX + "REFRESH_NOTIFICATIONS";
|
||||
|
@ -47,10 +47,13 @@ import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
@CursorObject(valuesCreator = true)
|
||||
public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
|
||||
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_id")
|
||||
public long account_id;
|
||||
|
||||
@ParcelableThisPlease
|
||||
public int account_color;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "id")
|
||||
@CursorField(CachedUsers.USER_ID)
|
||||
@ -205,13 +208,6 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
|
||||
is_basic = true;
|
||||
}
|
||||
|
||||
public ParcelableUser(final Cursor cursor, ParcelableUserCursorIndices indices, final long accountId) {
|
||||
indices.callBeforeCreated(this);
|
||||
indices.parseFields(this, cursor);
|
||||
indices.callAfterCreated(this);
|
||||
this.account_id = accountId;
|
||||
}
|
||||
|
||||
@AfterCursorObjectCreated
|
||||
void afterCursorObjectCreated() {
|
||||
is_cache = true;
|
||||
|
@ -63,6 +63,8 @@ public class TwitterContentUtils {
|
||||
|
||||
public static final int TWITTER_BULK_QUERY_COUNT = 100;
|
||||
private static final Pattern PATTERN_TWITTER_STATUS_LINK = Pattern.compile("https?://twitter\\.com/(?:#!/)?(\\w+)/status(es)?/(\\d+)");
|
||||
private static final CharSequenceTranslator UNESCAPE_TWITTER_RAW_TEXT = new LookupTranslator(EntityArrays.BASIC_UNESCAPE());
|
||||
private static final CharSequenceTranslator ESCAPE_TWITTER_RAW_TEXT = new LookupTranslator(EntityArrays.BASIC_ESCAPE());
|
||||
|
||||
public static String formatDirectMessageText(final DirectMessage message) {
|
||||
if (message == null) return null;
|
||||
@ -176,9 +178,6 @@ public class TwitterContentUtils {
|
||||
return ConsumerKeyType.UNKNOWN;
|
||||
}
|
||||
|
||||
private static final CharSequenceTranslator UNESCAPE_TWITTER_RAW_TEXT = new LookupTranslator(EntityArrays.BASIC_UNESCAPE());
|
||||
private static final CharSequenceTranslator ESCAPE_TWITTER_RAW_TEXT = new LookupTranslator(EntityArrays.BASIC_ESCAPE());
|
||||
|
||||
public static String unescapeTwitterStatusText(final CharSequence text) {
|
||||
if (text == null) return null;
|
||||
return UNESCAPE_TWITTER_RAW_TEXT.translate(text);
|
||||
|
5
twidere/src/main/assets/blackberry/apk2bar.prefs
Normal file
5
twidere/src/main/assets/blackberry/apk2bar.prefs
Normal file
@ -0,0 +1,5 @@
|
||||
#Mon Feb 01 00:57:24 CST 2016
|
||||
minimal.os.version=
|
||||
application.category=
|
||||
custom.manifest=false
|
||||
manifest.additions=true
|
@ -131,8 +131,10 @@ import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.TwidereViewUtils;
|
||||
import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
import org.mariotaku.twidere.view.ActionIconView;
|
||||
import org.mariotaku.twidere.view.BadgeView;
|
||||
import org.mariotaku.twidere.view.CheckableLinearLayout;
|
||||
import org.mariotaku.twidere.view.ComposeEditText;
|
||||
import org.mariotaku.twidere.view.ShapedImageView;
|
||||
import org.mariotaku.twidere.view.StatusTextCountView;
|
||||
@ -151,6 +153,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class ComposeActivity extends ThemedFragmentActivity implements OnMenuItemClickListener,
|
||||
OnClickListener, OnLongClickListener, Callback {
|
||||
|
||||
@ -163,13 +167,15 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
private static final String DISCARD_STATUS_DIALOG_FRAGMENT_TAG = "discard_status";
|
||||
|
||||
// Utility classes
|
||||
private final Extractor mExtractor = new Extractor();
|
||||
private TwidereValidator mValidator;
|
||||
@Inject
|
||||
Extractor mExtractor;
|
||||
@Inject
|
||||
TwidereValidator mValidator;
|
||||
private LocationManager mLocationManager;
|
||||
private ContentResolver mResolver;
|
||||
private AsyncTask<Object, Object, ?> mTask;
|
||||
private SupportMenuInflater mMenuInflater;
|
||||
private ItemTouchHelper mItemTouchHelper;
|
||||
private SetProgressVisibleRunnable mSetProgressVisibleRunnable;
|
||||
|
||||
// Views
|
||||
private RecyclerView mAttachedMediaPreview;
|
||||
@ -201,12 +207,11 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
private boolean mImageUploaderUsed, mStatusShortenerUsed;
|
||||
private boolean mNavigateBackPressed;
|
||||
private boolean mTextChanged;
|
||||
private SetProgressVisibleRunnable mSetProgressVisibleRunnable;
|
||||
private boolean mFragmentResumed;
|
||||
private int mKeyMetaState;
|
||||
|
||||
// Listeners
|
||||
private final LocationListener mLocationListener = new ComposeLocationListener(this);
|
||||
private LocationListener mLocationListener;
|
||||
|
||||
@Override
|
||||
public int getThemeColor() {
|
||||
@ -317,8 +322,12 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
protected void onStop() {
|
||||
saveAccountSelection();
|
||||
try {
|
||||
mLocationManager.removeUpdates(mLocationListener);
|
||||
if (mLocationListener != null) {
|
||||
mLocationManager.removeUpdates(mLocationListener);
|
||||
mLocationListener = null;
|
||||
}
|
||||
} catch (SecurityException ignore) {
|
||||
// That should not happen
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
@ -580,7 +589,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
builder.media(getMedia());
|
||||
}
|
||||
final ContentValues values = ContentValuesCreator.createStatusDraft(builder.build());
|
||||
final Uri draftUri = mResolver.insert(Drafts.CONTENT_URI, values);
|
||||
final Uri draftUri = getContentResolver().insert(Drafts.CONTENT_URI, values);
|
||||
displayNewDraftNotification(text, draftUri);
|
||||
}
|
||||
|
||||
@ -608,19 +617,19 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
GeneralComponentHelper.build(this).inject(this);
|
||||
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
mResolver = getContentResolver();
|
||||
mValidator = new TwidereValidator(this);
|
||||
setContentView(R.layout.activity_compose);
|
||||
setFinishOnTouchOutside(false);
|
||||
final long[] defaultAccountIds = DataStoreUtils.getAccountIds(this);
|
||||
if (defaultAccountIds.length <= 0) {
|
||||
final ParcelableCredentials[] accounts = ParcelableCredentials.getCredentialsArray(this, false, false);
|
||||
if (accounts.length <= 0) {
|
||||
final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
|
||||
intent.setClass(this, SignInActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
final long[] defaultAccountIds = ParcelableAccount.getAccountIds(accounts);
|
||||
mMenuBar.setOnMenuItemClickListener(this);
|
||||
setupEditText();
|
||||
mAccountSelectorContainer.setOnClickListener(this);
|
||||
@ -635,15 +644,10 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
mAccountSelector.setItemAnimator(new DefaultItemAnimator());
|
||||
mAccountsAdapter = new AccountIconsAdapter(this);
|
||||
mAccountSelector.setAdapter(mAccountsAdapter);
|
||||
mAccountsAdapter.setAccounts(ParcelableCredentials.getCredentialsArray(this, false, false));
|
||||
mAccountsAdapter.setAccounts(accounts);
|
||||
|
||||
|
||||
mMediaPreviewAdapter = new MediaPreviewAdapter(this, new SimpleItemTouchHelperCallback.OnStartDragListener() {
|
||||
@Override
|
||||
public void onStartDrag(ViewHolder viewHolder) {
|
||||
mItemTouchHelper.startDrag(viewHolder);
|
||||
}
|
||||
});
|
||||
mMediaPreviewAdapter = new MediaPreviewAdapter(this, new PreviewGridOnStartDragListener(mItemTouchHelper));
|
||||
mItemTouchHelper = new ItemTouchHelper(new AttachedMediaItemTouchHelperCallback(mMediaPreviewAdapter));
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
@ -651,12 +655,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
mAttachedMediaPreview.setAdapter(mMediaPreviewAdapter);
|
||||
mItemTouchHelper.attachToRecyclerView(mAttachedMediaPreview);
|
||||
final int previewGridSpacing = getResources().getDimensionPixelSize(R.dimen.element_spacing_small);
|
||||
mAttachedMediaPreview.addItemDecoration(new ItemDecoration() {
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
|
||||
outRect.left = outRect.right = previewGridSpacing;
|
||||
}
|
||||
});
|
||||
mAttachedMediaPreview.addItemDecoration(new PreviewGridItemDecoration(previewGridSpacing));
|
||||
|
||||
final Intent intent = getIntent();
|
||||
|
||||
@ -685,8 +684,8 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
if (!handleIntent(intent)) {
|
||||
handleDefaultIntent(intent);
|
||||
}
|
||||
final long[] accountIds = mAccountsAdapter.getSelectedAccountIds();
|
||||
if (accountIds.length == 0) {
|
||||
final long[] selectedAccountIds = mAccountsAdapter.getSelectedAccountIds();
|
||||
if (selectedAccountIds.length == 0) {
|
||||
final long[] idsInPrefs = TwidereArrayUtils.parseLongArray(
|
||||
mPreferences.getString(KEY_COMPOSE_ACCOUNTS, null), ',');
|
||||
final long[] intersection = TwidereArrayUtils.intersection(idsInPrefs, defaultAccountIds);
|
||||
@ -736,18 +735,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
private void setupEditText() {
|
||||
final boolean sendByEnter = mPreferences.getBoolean(KEY_QUICK_SEND);
|
||||
EditTextEnterHandler.attach(mEditText, new EnterListener() {
|
||||
@Override
|
||||
public boolean shouldCallListener() {
|
||||
return mKeyMetaState == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHitEnter() {
|
||||
confirmAndUpdateStatus();
|
||||
return true;
|
||||
}
|
||||
}, sendByEnter);
|
||||
EditTextEnterHandler.attach(mEditText, new ComposeEnterListener(this), sendByEnter);
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
@ -1146,6 +1134,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
}
|
||||
|
||||
private void setProgressVisible(final boolean visible) {
|
||||
if (isFinishing()) return;
|
||||
mSetProgressVisibleRunnable = new SetProgressVisibleRunnable(this, visible);
|
||||
if (mFragmentResumed) {
|
||||
runOnUiThread(mSetProgressVisibleRunnable);
|
||||
@ -1174,7 +1163,11 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (PermissionUtils.getPermission(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
|
||||
PermissionUtils.getPermission(permissions, grantResults, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||
startLocationUpdateIfEnabled();
|
||||
try {
|
||||
startLocationUpdateIfEnabled();
|
||||
} catch (SecurityException e) {
|
||||
// That should not happen
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, R.string.cannot_get_location, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
@ -1194,29 +1187,22 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
* the best provider of data (GPS, WiFi/cell phone tower lookup, some other
|
||||
* mechanism) and finds the last known location.
|
||||
*/
|
||||
private boolean startLocationUpdateIfEnabled() {
|
||||
final LocationManager lm = mLocationManager;
|
||||
try {
|
||||
lm.removeUpdates(mLocationListener);
|
||||
} catch (SecurityException ignore) {
|
||||
}
|
||||
private boolean startLocationUpdateIfEnabled() throws SecurityException {
|
||||
if (mLocationListener != null) return true;
|
||||
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION);
|
||||
if (!attachLocation) {
|
||||
return false;
|
||||
}
|
||||
final Criteria criteria = new Criteria();
|
||||
criteria.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
final String provider = lm.getBestProvider(criteria, true);
|
||||
final String provider = mLocationManager.getBestProvider(criteria, true);
|
||||
if (provider != null) {
|
||||
try {
|
||||
mLocationText.setText(R.string.getting_location);
|
||||
lm.requestLocationUpdates(provider, 0, 0, mLocationListener);
|
||||
final Location location = Utils.getCachedLocation(this);
|
||||
if (location != null) {
|
||||
mLocationListener.onLocationChanged(location);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
return false;
|
||||
mLocationText.setText(R.string.getting_location);
|
||||
mLocationListener = new ComposeLocationListener(this);
|
||||
mLocationManager.requestLocationUpdates(provider, 0, 0, mLocationListener);
|
||||
final Location location = Utils.getCachedLocation(this);
|
||||
if (location != null) {
|
||||
mLocationListener.onLocationChanged(location);
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, R.string.cannot_get_location, Toast.LENGTH_SHORT).show();
|
||||
@ -1351,16 +1337,18 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
static class SetProgressVisibleRunnable implements Runnable {
|
||||
|
||||
final ComposeActivity activity;
|
||||
final WeakReference<ComposeActivity> activityRef;
|
||||
final boolean visible;
|
||||
|
||||
SetProgressVisibleRunnable(ComposeActivity activity, boolean visible) {
|
||||
this.activity = activity;
|
||||
this.activityRef = new WeakReference<>(activity);
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final ComposeActivity activity = activityRef.get();
|
||||
if (activity == null) return;
|
||||
final FragmentManager fm = activity.getSupportFragmentManager();
|
||||
final Fragment f = fm.findFragmentByTag(DISCARD_STATUS_DIALOG_FRAGMENT_TAG);
|
||||
if (!visible && f instanceof DialogFragment) {
|
||||
@ -1389,6 +1377,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
public void showAccount(AccountIconsAdapter adapter, ParcelableAccount account, boolean isSelected) {
|
||||
itemView.setAlpha(isSelected ? 1 : 0.33f);
|
||||
((CheckableLinearLayout) itemView).setChecked(isSelected);
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
if (ObjectUtils.notEqual(account.profile_image_url, iconView.getTag()) || iconView.getDrawable() == null) {
|
||||
loader.displayProfileImage(iconView, account.profile_image_url);
|
||||
@ -1400,6 +1389,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
((CheckableLinearLayout) itemView).toggle();
|
||||
adapter.toggleSelection(getAdapterPosition());
|
||||
}
|
||||
|
||||
@ -1660,11 +1650,11 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
static class DiscardTweetTask extends AsyncTask<Object, Object, Object> {
|
||||
|
||||
final ComposeActivity activity;
|
||||
final WeakReference<ComposeActivity> activityRef;
|
||||
private final List<ParcelableMediaUpdate> media;
|
||||
|
||||
DiscardTweetTask(final ComposeActivity activity) {
|
||||
this.activity = activity;
|
||||
this.activityRef = new WeakReference<>(activity);
|
||||
this.media = activity.getMediaList();
|
||||
}
|
||||
|
||||
@ -1684,17 +1674,21 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Object result) {
|
||||
final ComposeActivity activity = activityRef.get();
|
||||
if (activity == null) return;
|
||||
activity.setProgressVisible(false);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
final ComposeActivity activity = activityRef.get();
|
||||
if (activity == null) return;
|
||||
activity.setProgressVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MediaPreviewAdapter extends ArrayRecyclerAdapter<ParcelableMediaUpdate, MediaPreviewViewHolder>
|
||||
static class MediaPreviewAdapter extends ArrayRecyclerAdapter<ParcelableMediaUpdate, MediaPreviewViewHolder>
|
||||
implements SimpleItemTouchHelperCallback.ItemTouchHelperAdapter {
|
||||
|
||||
final LayoutInflater mInflater;
|
||||
@ -1884,4 +1878,54 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
|
||||
viewHolder.itemView.setAlpha(ALPHA_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreviewGridItemDecoration extends ItemDecoration {
|
||||
private final int mPreviewGridSpacing;
|
||||
|
||||
public PreviewGridItemDecoration(int previewGridSpacing) {
|
||||
mPreviewGridSpacing = previewGridSpacing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
|
||||
outRect.left = outRect.right = mPreviewGridSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreviewGridOnStartDragListener implements SimpleItemTouchHelperCallback.OnStartDragListener {
|
||||
private final WeakReference<ItemTouchHelper> helperRef;
|
||||
|
||||
public PreviewGridOnStartDragListener(ItemTouchHelper helper) {
|
||||
helperRef = new WeakReference<>(helper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartDrag(ViewHolder viewHolder) {
|
||||
final ItemTouchHelper helper = helperRef.get();
|
||||
if (helper == null) return;
|
||||
helper.startDrag(viewHolder);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ComposeEnterListener implements EnterListener {
|
||||
private final WeakReference<ComposeActivity> activityRef;
|
||||
|
||||
public ComposeEnterListener(ComposeActivity activity) {
|
||||
activityRef = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCallListener() {
|
||||
final ComposeActivity activity = activityRef.get();
|
||||
return activity != null && activity.mKeyMetaState == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHitEnter() {
|
||||
final ComposeActivity activity = activityRef.get();
|
||||
if (activity == null) return false;
|
||||
activity.confirmAndUpdateStatus();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +104,11 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected ViewPager findViewPager() {
|
||||
return (ViewPager) findViewById(R.id.view_pager);
|
||||
final ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
|
||||
if (viewPager == null) throw new NullPointerException();
|
||||
return viewPager;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,6 +31,8 @@ import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
@ -66,6 +68,8 @@ public abstract class ThemedFragmentActivity extends FragmentActivity implements
|
||||
protected UserColorNameManager mUserColorNameManager;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
protected Bus mBus;
|
||||
|
||||
// Data fields
|
||||
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;
|
||||
|
@ -19,10 +19,7 @@
|
||||
|
||||
package org.mariotaku.twidere.activity.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
@ -36,6 +33,8 @@ import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter;
|
||||
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
|
||||
@ -55,6 +54,7 @@ import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.message.UserListCreatedEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -72,16 +72,6 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
|
||||
|
||||
private String mScreenName;
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_USER_LIST_CREATED.equals(action)) {
|
||||
getUserLists(mScreenName);
|
||||
}
|
||||
}
|
||||
};
|
||||
private Runnable mResumeFragmentRunnable;
|
||||
private boolean mFragmentsResumed;
|
||||
|
||||
@ -196,16 +186,20 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_USER_LIST_CREATED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
mBus.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
mBus.unregister(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
void onUserListCreated(UserListCreatedEvent event) {
|
||||
getUserLists(mScreenName);
|
||||
}
|
||||
|
||||
private long getAccountId() {
|
||||
return getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.DebugModeUtils;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
|
||||
@ -45,6 +46,8 @@ public class BaseSupportDialogFragment extends DialogFragment implements Constan
|
||||
protected UserColorNameManager mUserColorNameManager;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
protected TwidereValidator mValidator;
|
||||
|
||||
public TwidereApplication getApplication() {
|
||||
final Activity activity = getActivity();
|
||||
|
@ -24,7 +24,6 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
@ -53,6 +52,7 @@ import org.mariotaku.twidere.util.NotificationManagerWrapper;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.ThemedLayoutInflaterFactory;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
|
||||
@ -83,6 +83,8 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
|
||||
protected BidiFormatter mBidiFormatter;
|
||||
@Inject
|
||||
protected ErrorInfoStore mErrorInfoStore;
|
||||
@Inject
|
||||
TwidereValidator mValidator;
|
||||
|
||||
public BaseSupportFragment() {
|
||||
|
||||
@ -107,19 +109,6 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
|
||||
return null;
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences(final String name, final int mode) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSharedPreferences(name, mode);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getSystemService(final String name) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSystemService(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void invalidateOptionsMenu() {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
|
@ -104,7 +104,6 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.TakeAllKeyboardShortc
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
@ -162,8 +161,6 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
||||
};
|
||||
private PanelShowHideListener mScrollListener;
|
||||
|
||||
// Utility classes
|
||||
private TwidereValidator mValidator;
|
||||
private SharedPreferences mMessageDrafts;
|
||||
private EffectViewHelper mEffectHelper;
|
||||
|
||||
@ -228,8 +225,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final BaseAppCompatActivity activity = (BaseAppCompatActivity) getActivity();
|
||||
mMessageDrafts = getSharedPreferences(MESSAGE_DRAFTS_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mValidator = new TwidereValidator(activity);
|
||||
mMessageDrafts = activity.getSharedPreferences(MESSAGE_DRAFTS_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
|
||||
final View view = getView();
|
||||
assert view != null;
|
||||
|
@ -62,7 +62,6 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
|
||||
|
||||
public static final String FRAGMENT_TAG = "retweet_quote";
|
||||
private PopupMenu mPopupMenu;
|
||||
private TwidereValidator mValidator;
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
@ -95,7 +94,6 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
|
||||
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
|
||||
final Context context = builder.getContext();
|
||||
mValidator = new TwidereValidator(context);
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
@SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.dialog_status_quote_retweet, null);
|
||||
final DummyStatusHolderAdapter adapter = new DummyStatusHolderAdapter(context);
|
||||
|
@ -24,11 +24,8 @@ import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Outline;
|
||||
@ -45,6 +42,7 @@ import android.nfc.NfcEvent;
|
||||
import android.os.Build;
|
||||
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.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
@ -65,6 +63,7 @@ import android.support.v7.widget.Toolbar;
|
||||
import android.support.v7.widget.TwidereToolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@ -81,9 +80,12 @@ import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.desmond.asyncmanager.AsyncManager;
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.meizu.flyme.reflect.StatusBarProxy;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.R;
|
||||
@ -98,13 +100,14 @@ import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
|
||||
import org.mariotaku.twidere.api.twitter.model.Relationship;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.graphic.ActionBarColorDrawable;
|
||||
import org.mariotaku.twidere.graphic.ActionIconDrawable;
|
||||
import org.mariotaku.twidere.loader.support.ParcelableUserLoader;
|
||||
import org.mariotaku.twidere.model.CachedRelationship;
|
||||
import org.mariotaku.twidere.model.CachedRelationshipValuesCreator;
|
||||
import org.mariotaku.twidere.model.ConsumerKeyType;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
@ -112,6 +115,7 @@ import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.model.SupportTabSpec;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
@ -122,13 +126,13 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
||||
import org.mariotaku.twidere.util.LinkCreator;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereColorUtils;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
|
||||
import org.mariotaku.twidere.util.TwidereMathUtils;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
|
||||
@ -151,17 +155,14 @@ import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class UserFragment extends BaseSupportFragment implements OnClickListener,
|
||||
OnLinkClickListener, OnSizeChangedListener, OnSharedPreferenceChangeListener,
|
||||
OnTouchListener, DrawerCallback, SupportFragmentCallback, SystemWindowsInsetsCallback,
|
||||
RefreshScrollTopInterface, OnPageChangeListener, KeyboardShortcutCallback {
|
||||
|
||||
private static final ArgbEvaluator sArgbEvaluator = new ArgbEvaluator();
|
||||
public class UserFragment extends BaseSupportFragment implements OnClickListener, OnLinkClickListener,
|
||||
OnSizeChangedListener, OnTouchListener, DrawerCallback, SupportFragmentCallback,
|
||||
SystemWindowsInsetsCallback, RefreshScrollTopInterface, OnPageChangeListener, KeyboardShortcutCallback,
|
||||
UserColorNameManager.UserColorChangedListener, UserColorNameManager.UserNicknameChangedListener {
|
||||
|
||||
public static final String TRANSITION_NAME_PROFILE_IMAGE = "profile_image";
|
||||
public static final String TRANSITION_NAME_PROFILE_TYPE = "profile_type";
|
||||
public static final String TRANSITION_NAME_CARD = "card";
|
||||
|
||||
private static final ArgbEvaluator sArgbEvaluator = new ArgbEvaluator();
|
||||
private static final int LOADER_ID_USER = 1;
|
||||
private static final int LOADER_ID_FRIENDSHIP = 2;
|
||||
|
||||
@ -172,6 +173,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
private static final String TAB_TYPE_MEDIA = "media";
|
||||
private static final String TAB_TYPE_FAVORITES = "favorites";
|
||||
|
||||
// Views
|
||||
private ShapedImageView mProfileImageView;
|
||||
private ImageView mProfileTypeView;
|
||||
private ProfileBannerImageView mProfileBannerView;
|
||||
@ -201,12 +203,12 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
private View mProfileDetailsContainer;
|
||||
private View mFollowingYouIndicator;
|
||||
|
||||
|
||||
private ActionBarDrawable mActionBarBackground;
|
||||
private SupportTabsAdapter mPagerAdapter;
|
||||
|
||||
// Data fields
|
||||
private ParcelableUser mUser;
|
||||
private Relationship mRelationship;
|
||||
private UserRelationship mRelationship;
|
||||
private Locale mLocale;
|
||||
private boolean mGetUserInfoLoaderInitialized, mGetFriendShipLoaderInitialized;
|
||||
private int mBannerWidth;
|
||||
@ -217,85 +219,35 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
private int mPreviousTabItemIsDark, mPreviousActionBarItemIsDark;
|
||||
private boolean mHideBirthdayView;
|
||||
|
||||
private final LoaderCallbacks<SingleResponse<UserRelationship>> mFriendshipLoaderCallbacks =
|
||||
new LoaderCallbacks<SingleResponse<UserRelationship>>() {
|
||||
|
||||
private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() {
|
||||
@Override
|
||||
public Loader<SingleResponse<UserRelationship>> onCreateLoader(final int id, final Bundle args) {
|
||||
invalidateOptionsMenu();
|
||||
mFollowButton.setVisibility(View.GONE);
|
||||
mFollowProgress.setVisibility(View.VISIBLE);
|
||||
mFollowingYouIndicator.setVisibility(View.GONE);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
return new UserRelationshipLoader(getActivity(), accountId, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<SingleResponse<Relationship>> onCreateLoader(final int id, final Bundle args) {
|
||||
invalidateOptionsMenu();
|
||||
mFollowButton.setVisibility(View.GONE);
|
||||
mFollowProgress.setVisibility(View.VISIBLE);
|
||||
mFollowingYouIndicator.setVisibility(View.GONE);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
return new RelationshipLoader(getActivity(), accountId, userId);
|
||||
}
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<UserRelationship>> loader) {
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<Relationship>> loader) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<SingleResponse<Relationship>> loader,
|
||||
final SingleResponse<Relationship> data) {
|
||||
mFollowProgress.setVisibility(View.GONE);
|
||||
final ParcelableUser user = getUser();
|
||||
final Relationship relationship = data.getData();
|
||||
showRelationship(user, relationship);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private void showRelationship(ParcelableUser user, Relationship relationship) {
|
||||
mRelationship = relationship;
|
||||
if (user == null) return;
|
||||
invalidateOptionsMenu();
|
||||
final boolean isMyself = user.account_id == user.id;
|
||||
if (isMyself) {
|
||||
mFollowButton.setText(R.string.edit);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
} else if (relationship != null) {
|
||||
mFollowButton.setEnabled(!relationship.isSourceBlockedByTarget());
|
||||
if (relationship.isSourceBlockedByTarget()) {
|
||||
mPagesErrorContainer.setVisibility(View.GONE);
|
||||
mPagesErrorText.setText(null);
|
||||
mPagesContent.setVisibility(View.VISIBLE);
|
||||
} else if (!relationship.isSourceFollowingTarget() && user.is_protected) {
|
||||
mPagesErrorContainer.setVisibility(View.VISIBLE);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
|
||||
mPagesErrorText.setText(getString(R.string.user_protected_summary, displayName));
|
||||
mPagesErrorIcon.setImageResource(R.drawable.ic_info_locked);
|
||||
mPagesContent.setVisibility(View.GONE);
|
||||
} else {
|
||||
mPagesErrorContainer.setVisibility(View.GONE);
|
||||
mPagesErrorText.setText(null);
|
||||
mPagesContent.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (relationship.isSourceBlockingTarget()) {
|
||||
mFollowButton.setText(R.string.unblock);
|
||||
} else if (relationship.isSourceFollowingTarget()) {
|
||||
mFollowButton.setText(R.string.unfollow);
|
||||
} else if (user.is_follow_request_sent) {
|
||||
mFollowButton.setText(R.string.requested);
|
||||
} else {
|
||||
mFollowButton.setText(R.string.follow);
|
||||
}
|
||||
mFollowButton.setCompoundDrawablePadding(Math.round(mFollowButton.getTextSize() * 0.25f));
|
||||
mFollowingYouIndicator.setVisibility(relationship.isTargetFollowingSource() ? View.VISIBLE : View.GONE);
|
||||
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
final ContentValues cachedValues = ContentValuesCreator.makeCachedUserContentValues(user);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedValues);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mFollowButton.setText(null);
|
||||
mFollowButton.setVisibility(View.GONE);
|
||||
mPagesErrorContainer.setVisibility(View.GONE);
|
||||
mPagesContent.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<SingleResponse<UserRelationship>> loader,
|
||||
final SingleResponse<UserRelationship> data) {
|
||||
mFollowProgress.setVisibility(View.GONE);
|
||||
final ParcelableUser user = getUser();
|
||||
final UserRelationship relationship = data.getData();
|
||||
showRelationship(user, relationship);
|
||||
}
|
||||
|
||||
};
|
||||
private final LoaderCallbacks<SingleResponse<ParcelableUser>> mUserInfoLoaderCallbacks = new LoaderCallbacks<SingleResponse<ParcelableUser>>() {
|
||||
|
||||
@Override
|
||||
@ -362,6 +314,69 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
};
|
||||
|
||||
private static void setCompatToolbarOverlayAlpha(FragmentActivity activity, float alpha) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return;
|
||||
final View windowOverlay = activity.findViewById(R.id.window_overlay);
|
||||
if (windowOverlay != null) {
|
||||
windowOverlay.setAlpha(alpha);
|
||||
return;
|
||||
}
|
||||
final Drawable drawable = ThemeUtils.getCompatToolbarOverlay(activity);
|
||||
if (drawable == null) return;
|
||||
drawable.setAlpha(Math.round(alpha * 255));
|
||||
}
|
||||
|
||||
private void showRelationship(@Nullable ParcelableUser user, @Nullable UserRelationship userRelationship) {
|
||||
if (user == null) {
|
||||
mRelationship = null;
|
||||
return;
|
||||
} else if (userRelationship != null && userRelationship.check(user)) {
|
||||
mRelationship = userRelationship;
|
||||
} else {
|
||||
mRelationship = null;
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
if (mRelationship == null && user.account_id == user.id) {
|
||||
mFollowButton.setText(R.string.edit);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
final Relationship relationship = mRelationship.relationship;
|
||||
mFollowButton.setEnabled(relationship.isSourceBlockingTarget() ||
|
||||
!relationship.isSourceBlockedByTarget());
|
||||
if (relationship.isSourceBlockedByTarget()) {
|
||||
mPagesErrorContainer.setVisibility(View.GONE);
|
||||
mPagesErrorText.setText(null);
|
||||
mPagesContent.setVisibility(View.VISIBLE);
|
||||
} else if (!relationship.isSourceFollowingTarget() && user.is_protected) {
|
||||
mPagesErrorContainer.setVisibility(View.VISIBLE);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
|
||||
mPagesErrorText.setText(getString(R.string.user_protected_summary, displayName));
|
||||
mPagesErrorIcon.setImageResource(R.drawable.ic_info_locked);
|
||||
mPagesContent.setVisibility(View.GONE);
|
||||
} else {
|
||||
mPagesErrorContainer.setVisibility(View.GONE);
|
||||
mPagesErrorText.setText(null);
|
||||
mPagesContent.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (relationship.isSourceBlockingTarget()) {
|
||||
mFollowButton.setText(R.string.unblock);
|
||||
} else if (relationship.isSourceFollowingTarget()) {
|
||||
mFollowButton.setText(R.string.unfollow);
|
||||
} else if (user.is_follow_request_sent) {
|
||||
mFollowButton.setText(R.string.requested);
|
||||
} else {
|
||||
mFollowButton.setText(R.string.follow);
|
||||
}
|
||||
mFollowButton.setCompoundDrawablePadding(Math.round(mFollowButton.getTextSize() * 0.25f));
|
||||
mFollowingYouIndicator.setVisibility(relationship.isTargetFollowingSource() ? View.VISIBLE : View.GONE);
|
||||
|
||||
final CacheUserInfoRunnable task = new CacheUserInfoRunnable(getContext().getApplicationContext());
|
||||
task.setParams(Pair.create(user, relationship));
|
||||
AsyncManager.runBackgroundTask(task);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScroll(float dy) {
|
||||
final Fragment fragment = getCurrentVisibleFragment();
|
||||
@ -487,14 +502,17 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(LOADER_ID_USER);
|
||||
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
|
||||
final boolean userIsMe = user.account_id == user.id;
|
||||
mCardContent.setVisibility(View.VISIBLE);
|
||||
mHeaderErrorContainer.setVisibility(View.GONE);
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mUser = user;
|
||||
final int userColor = mUserColorNameManager.getUserColor(user.id, true);
|
||||
mProfileImageView.setBorderColor(userColor != 0 ? userColor : Color.WHITE);
|
||||
mProfileNameContainer.drawEnd(DataStoreUtils.getAccountColor(activity, user.account_id));
|
||||
if (user.account_color != 0) {
|
||||
mProfileNameContainer.drawEnd(user.account_color);
|
||||
} else {
|
||||
mProfileNameContainer.drawEnd(DataStoreUtils.getAccountColor(activity, user.account_id));
|
||||
}
|
||||
final String nick = mUserColorNameManager.getUserNickname(user.id, true);
|
||||
mNameView.setText(mBidiFormatter.unicodeWrap(TextUtils.isEmpty(nick) ? user.name : getString(R.string.name_with_nickname, user.name, nick)));
|
||||
final int typeIconRes = Utils.getUserTypeIconRes(user.is_verified, user.is_protected);
|
||||
@ -533,9 +551,13 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
final int defWidth = resources.getDisplayMetrics().widthPixels;
|
||||
final int width = mBannerWidth > 0 ? mBannerWidth : defWidth;
|
||||
mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, width);
|
||||
final Relationship relationship = mRelationship;
|
||||
if (relationship == null || relationship.getTargetUserId() != user.id) {
|
||||
if (ObjectUtils.notEqual(mProfileBannerView.getTag(), user.profile_banner_url) ||
|
||||
mProfileBannerView.getDrawable() == null) {
|
||||
mProfileBannerView.setTag(user.profile_banner_url);
|
||||
mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, width);
|
||||
}
|
||||
final UserRelationship relationship = mRelationship;
|
||||
if (relationship == null) {
|
||||
getFriendship();
|
||||
}
|
||||
activity.setTitle(mUserColorNameManager.getDisplayName(user, mNameFirst, true));
|
||||
@ -570,6 +592,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ParcelableUser getUser() {
|
||||
return mUser;
|
||||
}
|
||||
@ -678,17 +701,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final FragmentActivity activity = getActivity();
|
||||
setHasOptionsMenu(true);
|
||||
getSharedPreferences(USER_COLOR_PREFERENCES_NAME, Context.MODE_PRIVATE)
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE)
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
mUserColorNameManager.registerColorChangedListener(this);
|
||||
mUserColorNameManager.registerNicknameChangedListener(this);
|
||||
mNameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
mLocale = getResources().getConfiguration().locale;
|
||||
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity,
|
||||
ThemeUtils.getThemeBackgroundOption(activity),
|
||||
ThemeUtils.getUserThemeBackgroundAlpha(activity));
|
||||
mActionBarShadowColor = 0xA0000000;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(activity);
|
||||
final Bundle args = getArguments();
|
||||
long accountId = -1, userId = -1;
|
||||
String screenName = null;
|
||||
@ -777,16 +797,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
final float actionBarElevation = ThemeUtils.getSupportActionBarElevation(activity);
|
||||
ViewCompat.setElevation(mPagerIndicator, actionBarElevation);
|
||||
|
||||
setupBaseActionBar();
|
||||
setupUserPages();
|
||||
|
||||
if (activity instanceof IThemedActivity) {
|
||||
ViewSupport.setBackground(mPagerOverlay, ThemeUtils.getNormalWindowContentOverlay(activity,
|
||||
((IThemedActivity) activity).getCurrentThemeResourceId()));
|
||||
ViewSupport.setBackground(mErrorOverlay, ThemeUtils.getNormalWindowContentOverlay(activity,
|
||||
((IThemedActivity) activity).getCurrentThemeResourceId()));
|
||||
}
|
||||
|
||||
setupBaseActionBar();
|
||||
setupUserPages();
|
||||
if (activity instanceof IThemedActivity) {
|
||||
setUiColor(((IThemedActivity) activity).getCurrentThemeColor());
|
||||
}
|
||||
|
||||
@ -830,8 +848,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
public void onPrepareOptionsMenu(final Menu menu) {
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
final ParcelableUser user = getUser();
|
||||
final Relationship relationship = mRelationship;
|
||||
if (twitter == null || user == null) return;
|
||||
final UserRelationship userRelationship = mRelationship;
|
||||
if (twitter == null || user == null || userRelationship == null) return;
|
||||
final Relationship relationship = userRelationship.relationship;
|
||||
|
||||
final boolean isMyself = user.account_id == user.id;
|
||||
final MenuItem mentionItem = menu.findItem(R.id.mention);
|
||||
@ -857,7 +876,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
// followItem.setTitle(null);
|
||||
// followItem.setIcon(null);
|
||||
// }
|
||||
if (!isMyself && relationship != null) {
|
||||
if (!isMyself) {
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.send_direct_message, relationship.canSourceDMTarget());
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.block, true);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.mute_user, true);
|
||||
@ -873,9 +892,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
final MenuItem filterItem = menu.findItem(R.id.add_to_filter);
|
||||
if (filterItem != null) {
|
||||
final boolean filtering = Utils.isFilteringUser(getActivity(), user.id);
|
||||
ActionIconDrawable.setMenuHighlight(filterItem, new TwidereMenuInfo(filtering));
|
||||
filterItem.setTitle(filtering ? R.string.remove_from_filter : R.string.add_to_filter);
|
||||
ActionIconDrawable.setMenuHighlight(filterItem, new TwidereMenuInfo(userRelationship.isFiltering));
|
||||
filterItem.setTitle(userRelationship.isFiltering ? R.string.remove_from_filter : R.string.add_to_filter);
|
||||
}
|
||||
final MenuItem wantRetweetsItem = menu.findItem(R.id.enable_retweets);
|
||||
if (wantRetweetsItem != null) {
|
||||
@ -909,16 +927,15 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
final ParcelableUser user = getUser();
|
||||
final Relationship relationship = mRelationship;
|
||||
final UserRelationship userRelationship = mRelationship;
|
||||
if (user == null || twitter == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.block: {
|
||||
if (mRelationship != null) {
|
||||
if (mRelationship.isSourceBlockingTarget()) {
|
||||
twitter.destroyBlockAsync(user.account_id, user.id);
|
||||
} else {
|
||||
CreateUserBlockDialogFragment.show(getFragmentManager(), user);
|
||||
}
|
||||
if (userRelationship == null) return true;
|
||||
if (userRelationship.relationship.isSourceBlockingTarget()) {
|
||||
twitter.destroyBlockAsync(user.account_id, user.id);
|
||||
} else {
|
||||
CreateUserBlockDialogFragment.show(getFragmentManager(), user);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -927,9 +944,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
break;
|
||||
}
|
||||
case R.id.add_to_filter: {
|
||||
final boolean filtering = Utils.isFilteringUser(getActivity(), user.id);
|
||||
if (userRelationship == null) return true;
|
||||
final ContentResolver cr = getContentResolver();
|
||||
if (filtering) {
|
||||
if (userRelationship.isFiltering) {
|
||||
final Expression where = Expression.equals(Filters.Users.USER_ID, user.id);
|
||||
cr.delete(Filters.Users.CONTENT_URI, where.getSQL(), null);
|
||||
Utils.showInfoMessage(getActivity(), R.string.message_user_unmuted, false);
|
||||
@ -940,12 +957,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
break;
|
||||
}
|
||||
case R.id.mute_user: {
|
||||
if (mRelationship != null) {
|
||||
if (mRelationship.isSourceMutingTarget()) {
|
||||
twitter.destroyMuteAsync(user.account_id, user.id);
|
||||
} else {
|
||||
CreateUserMuteDialogFragment.show(getFragmentManager(), user);
|
||||
}
|
||||
if (userRelationship == null) return true;
|
||||
if (userRelationship.relationship.isSourceMutingTarget()) {
|
||||
twitter.destroyMuteAsync(user.account_id, user.id);
|
||||
} else {
|
||||
CreateUserMuteDialogFragment.show(getFragmentManager(), user);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1002,8 +1018,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
break;
|
||||
}
|
||||
case R.id.follow: {
|
||||
if (relationship == null) return false;
|
||||
final boolean isFollowing = relationship.isSourceFollowingTarget();
|
||||
if (userRelationship == null) return true;
|
||||
final boolean isFollowing = userRelationship.relationship.isSourceFollowingTarget();
|
||||
final boolean isCreatingFriendship = twitter.isCreatingFriendship(user.account_id, user.id);
|
||||
final boolean isDestroyingFriendship = twitter.isDestroyingFriendship(user.account_id, user.id);
|
||||
if (!isCreatingFriendship && !isDestroyingFriendship) {
|
||||
@ -1211,12 +1227,12 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
Utils.openProfileEditor(getActivity(), user.account_id);
|
||||
break;
|
||||
}
|
||||
final Relationship relationship = mRelationship;
|
||||
final UserRelationship userRelationship = mRelationship;
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (relationship == null || twitter == null) return;
|
||||
if (relationship.isSourceBlockingTarget()) {
|
||||
if (userRelationship == null || twitter == null) return;
|
||||
if (userRelationship.relationship.isSourceBlockingTarget()) {
|
||||
twitter.destroyBlockAsync(user.account_id, user.id);
|
||||
} else if (relationship.isSourceFollowingTarget()) {
|
||||
} else if (userRelationship.relationship.isSourceFollowingTarget()) {
|
||||
DestroyFriendshipDialogFragment.show(getFragmentManager(), user);
|
||||
} else {
|
||||
twitter.createFriendshipAsync(user.account_id, user.id);
|
||||
@ -1310,8 +1326,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
if (mUser == null || !ParseUtils.parseString(mUser.id).equals(key)) return;
|
||||
public void onUserNicknameChanged(long userId, String nick) {
|
||||
if (mUser == null || mUser.id != userId) return;
|
||||
displayUser(mUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserColorChanged(long userId, int color) {
|
||||
if (mUser == null || mUser.id != userId) return;
|
||||
displayUser(mUser);
|
||||
}
|
||||
|
||||
@ -1354,8 +1376,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
|
||||
private void getFriendship() {
|
||||
mRelationship = null;
|
||||
final ParcelableUser user = getUser();
|
||||
if (user == null) return;
|
||||
mRelationship = null;
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
|
||||
final Bundle args = new Bundle();
|
||||
@ -1375,20 +1398,10 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
getUserInfo(user.account_id, user.id, user.screen_name, omitIntentExtra);
|
||||
}
|
||||
|
||||
private static void setCompatToolbarOverlayAlpha(FragmentActivity activity, float alpha) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return;
|
||||
final View windowOverlay = activity.findViewById(R.id.window_overlay);
|
||||
if (windowOverlay != null) {
|
||||
windowOverlay.setAlpha(alpha);
|
||||
return;
|
||||
}
|
||||
final Drawable drawable = ThemeUtils.getCompatToolbarOverlay(activity);
|
||||
if (drawable == null) return;
|
||||
drawable.setAlpha(Math.round(alpha * 255));
|
||||
}
|
||||
|
||||
private void setUiColor(int color) {
|
||||
mUiColor = color;
|
||||
mPreviousActionBarItemIsDark = 0;
|
||||
mPreviousTabItemIsDark = 0;
|
||||
if (mActionBarBackground == null) {
|
||||
setupBaseActionBar();
|
||||
}
|
||||
@ -1674,32 +1687,34 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
}
|
||||
|
||||
static class RelationshipLoader extends AsyncTaskLoader<SingleResponse<Relationship>> {
|
||||
static class UserRelationshipLoader extends AsyncTaskLoader<SingleResponse<UserRelationship>> {
|
||||
|
||||
private final Context context;
|
||||
private final long account_id, user_id;
|
||||
private final long accountId, userId;
|
||||
|
||||
public RelationshipLoader(final Context context, final long account_id, final long user_id) {
|
||||
public UserRelationshipLoader(final Context context, final long accountId, final long userId) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
this.account_id = account_id;
|
||||
this.user_id = user_id;
|
||||
this.accountId = accountId;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<Relationship> loadInBackground() {
|
||||
if (account_id == user_id) return SingleResponse.getInstance();
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, account_id, false);
|
||||
public SingleResponse<UserRelationship> loadInBackground() {
|
||||
final boolean isFiltering = Utils.isFilteringUser(context, userId);
|
||||
if (accountId == userId)
|
||||
return SingleResponse.getInstance();
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, false);
|
||||
if (twitter == null) return SingleResponse.getInstance();
|
||||
try {
|
||||
final Relationship relationship = twitter.showFriendship(user_id);
|
||||
final Relationship relationship = twitter.showFriendship(userId);
|
||||
if (relationship.isSourceBlockingTarget() || relationship.isSourceBlockedByTarget()) {
|
||||
Utils.setLastSeen(context, user_id, -1);
|
||||
Utils.setLastSeen(context, userId, -1);
|
||||
} else {
|
||||
Utils.setLastSeen(context, user_id, System.currentTimeMillis());
|
||||
Utils.setLastSeen(context, userId, System.currentTimeMillis());
|
||||
}
|
||||
Utils.updateRelationship(context, relationship, account_id);
|
||||
return SingleResponse.getInstance(relationship);
|
||||
Utils.updateRelationship(context, relationship, accountId);
|
||||
return SingleResponse.getInstance(new UserRelationship(relationship, isFiltering));
|
||||
} catch (final TwitterException e) {
|
||||
return SingleResponse.getInstance(e);
|
||||
}
|
||||
@ -1711,4 +1726,37 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
}
|
||||
|
||||
static class UserRelationship {
|
||||
@NonNull
|
||||
Relationship relationship;
|
||||
boolean isFiltering;
|
||||
|
||||
public UserRelationship(@NonNull Relationship relationship, boolean isFiltering) {
|
||||
this.relationship = relationship;
|
||||
this.isFiltering = isFiltering;
|
||||
}
|
||||
|
||||
public boolean check(@NonNull ParcelableUser user) {
|
||||
return relationship.getSourceUserId() == user.account_id
|
||||
&& relationship.getTargetUserId() == user.id;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CacheUserInfoRunnable extends TaskRunnable<Pair<ParcelableUser, Relationship>, Object, Object> {
|
||||
private final Context context;
|
||||
|
||||
public CacheUserInfoRunnable(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object doLongOperation(Pair<ParcelableUser, Relationship> args) throws InterruptedException {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final ParcelableUser user = args.first;
|
||||
resolver.insert(CachedUsers.CONTENT_URI, ContentValuesCreator.makeCachedUserContentValues(user));
|
||||
resolver.insert(CachedRelationships.CONTENT_URI, CachedRelationshipValuesCreator.create(
|
||||
new CachedRelationship(user.account_id, user.id, args.second)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,7 @@
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.content.Loader;
|
||||
@ -30,32 +27,20 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserListsLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.message.UserListDestroyedEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserListsFragment extends ParcelableUserListsFragment {
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_USER_LIST_DELETED.equals(action)) {
|
||||
final ParcelableUserList list = intent.getParcelableExtra(EXTRA_USER_LIST);
|
||||
if (list != null) {
|
||||
removeUserList(list.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,
|
||||
final Bundle args, final boolean fromUser) {
|
||||
@ -114,15 +99,20 @@ public class UserListsFragment extends ParcelableUserListsFragment {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
registerReceiver(mStatusReceiver, new IntentFilter(BROADCAST_USER_LIST_DELETED));
|
||||
mBus.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
mBus.unregister(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
void onUserListDestroyed(UserListDestroyedEvent event) {
|
||||
removeUserList(event.userList.id);
|
||||
}
|
||||
|
||||
private void removeUserList(final long id) {
|
||||
final AbsUserListsAdapter<List<ParcelableUserList>> adapter = getAdapter();
|
||||
// final int listsIdx = adapter.findItemPosition(id);
|
||||
|
@ -38,6 +38,7 @@ import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.DataStoreUtils;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
|
||||
@ -67,11 +68,13 @@ public final class ParcelableUserLoader extends AsyncTaskLoader<SingleResponse<P
|
||||
public SingleResponse<ParcelableUser> loadInBackground() {
|
||||
final Context context = getContext();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
int accountColor = DataStoreUtils.getAccountColor(context, mAccountId);
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableUser user = mExtras.getParcelable(EXTRA_USER);
|
||||
if (user != null) {
|
||||
final ContentValues values = ContentValuesCreator.makeCachedUserContentValues(user);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, values);
|
||||
user.account_color = accountColor;
|
||||
return SingleResponse.getInstance(user);
|
||||
}
|
||||
}
|
||||
@ -89,33 +92,37 @@ public final class ParcelableUserLoader extends AsyncTaskLoader<SingleResponse<P
|
||||
}
|
||||
final Cursor cur = resolver.query(CachedUsers.CONTENT_URI, CachedUsers.COLUMNS,
|
||||
where.getSQL(), whereArgs, null);
|
||||
final int count = cur.getCount();
|
||||
try {
|
||||
if (count > 0) {
|
||||
final ParcelableUserCursorIndices indices = new ParcelableUserCursorIndices(cur);
|
||||
cur.moveToFirst();
|
||||
return SingleResponse.getInstance(new ParcelableUser(cur, indices, mAccountId));
|
||||
if (cur != null) {
|
||||
try {
|
||||
if (cur.moveToFirst()) {
|
||||
final ParcelableUserCursorIndices indices = new ParcelableUserCursorIndices(cur);
|
||||
final ParcelableUser user = indices.newObject(cur);
|
||||
user.account_id = mAccountId;
|
||||
user.account_color = accountColor;
|
||||
return SingleResponse.getInstance(user);
|
||||
}
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
try {
|
||||
final User user = TwitterWrapper.tryShowUser(twitter, mUserId, mScreenName);
|
||||
final ContentValues cachedUserValues = createCachedUser(user);
|
||||
final long userId = user.getId();
|
||||
final User twitterUser = TwitterWrapper.tryShowUser(twitter, mUserId, mScreenName);
|
||||
final ContentValues cachedUserValues = createCachedUser(twitterUser);
|
||||
final long userId = twitterUser.getId();
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues);
|
||||
final ParcelableUser result = new ParcelableUser(user, mAccountId);
|
||||
final ParcelableUser user = new ParcelableUser(twitterUser, mAccountId);
|
||||
if (isMyAccount(context, userId)) {
|
||||
final ContentValues accountValues = new ContentValues();
|
||||
accountValues.put(Accounts.NAME, result.name);
|
||||
accountValues.put(Accounts.SCREEN_NAME, result.screen_name);
|
||||
accountValues.put(Accounts.PROFILE_IMAGE_URL, result.profile_image_url);
|
||||
accountValues.put(Accounts.PROFILE_BANNER_URL, result.profile_banner_url);
|
||||
accountValues.put(Accounts.NAME, user.name);
|
||||
accountValues.put(Accounts.SCREEN_NAME, user.screen_name);
|
||||
accountValues.put(Accounts.PROFILE_IMAGE_URL, user.profile_image_url);
|
||||
accountValues.put(Accounts.PROFILE_BANNER_URL, user.profile_banner_url);
|
||||
final String accountWhere = Expression.equals(Accounts.ACCOUNT_ID, userId).getSQL();
|
||||
resolver.update(Accounts.CONTENT_URI, accountValues, accountWhere, null);
|
||||
}
|
||||
return SingleResponse.getInstance(result);
|
||||
user.account_color = accountColor;
|
||||
return SingleResponse.getInstance(user);
|
||||
} catch (final TwitterException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return SingleResponse.getInstance(e);
|
||||
|
@ -0,0 +1,54 @@
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorField;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorObject;
|
||||
import org.mariotaku.twidere.api.twitter.model.Relationship;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/1.
|
||||
*/
|
||||
@CursorObject(valuesCreator = true)
|
||||
public class CachedRelationship {
|
||||
|
||||
@CursorField(CachedRelationships.ACCOUNT_ID)
|
||||
public long account_id;
|
||||
|
||||
@CursorField(CachedRelationships.USER_ID)
|
||||
public long user_id;
|
||||
|
||||
@CursorField(CachedRelationships.FOLLOWING)
|
||||
public boolean following;
|
||||
|
||||
@CursorField(CachedRelationships.FOLLOWED_BY)
|
||||
public boolean followed_by;
|
||||
|
||||
@CursorField(CachedRelationships.BLOCKING)
|
||||
public boolean blocking;
|
||||
|
||||
@CursorField(CachedRelationships.BLOCKED_BY)
|
||||
public boolean blocked_by;
|
||||
|
||||
@CursorField(CachedRelationships.MUTING)
|
||||
public boolean muting;
|
||||
|
||||
@CursorField(CachedRelationships.RETWEET_ENABLED)
|
||||
public boolean retweet_enabled;
|
||||
|
||||
public CachedRelationship() {
|
||||
|
||||
}
|
||||
|
||||
public CachedRelationship(long accountId, long userId, @NonNull Relationship relationship) {
|
||||
account_id = accountId;
|
||||
user_id = userId;
|
||||
following = relationship.isSourceFollowingTarget();
|
||||
following = relationship.isSourceFollowedByTarget();
|
||||
blocking = relationship.isSourceBlockingTarget();
|
||||
blocked_by = relationship.isSourceBlockedByTarget();
|
||||
muting = relationship.isSourceMutingTarget();
|
||||
retweet_enabled = relationship.isSourceWantRetweetsFromTarget();
|
||||
}
|
||||
}
|
@ -26,7 +26,6 @@ import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.BitmapFactory;
|
||||
@ -81,6 +80,7 @@ import org.mariotaku.twidere.util.BitmapUtils;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.MediaUploaderInterface;
|
||||
import org.mariotaku.twidere.util.NotificationManagerWrapper;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.StatusShortenerInterface;
|
||||
import org.mariotaku.twidere.util.TwidereListUtils;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
@ -112,16 +112,18 @@ import static org.mariotaku.twidere.util.Utils.getImageUploadStatus;
|
||||
|
||||
public class BackgroundOperationService extends IntentService implements Constants {
|
||||
|
||||
private TwidereValidator mValidator;
|
||||
private final Extractor extractor = new Extractor();
|
||||
|
||||
private Handler mHandler;
|
||||
private SharedPreferences mPreferences;
|
||||
private ContentResolver mResolver;
|
||||
@Inject
|
||||
SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
AsyncTwitterWrapper mTwitter;
|
||||
@Inject
|
||||
NotificationManagerWrapper mNotificationManager;
|
||||
@Inject
|
||||
TwidereValidator mValidator;
|
||||
@Inject
|
||||
Extractor mExtractor;
|
||||
|
||||
private MediaUploaderInterface mUploader;
|
||||
private StatusShortenerInterface mShortener;
|
||||
@ -138,9 +140,6 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
GeneralComponentHelper.build(this).inject(this);
|
||||
final TwidereApplication app = TwidereApplication.getInstance(this);
|
||||
mHandler = new Handler();
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||
mValidator = new TwidereValidator(this);
|
||||
mResolver = getContentResolver();
|
||||
final String uploaderComponent = mPreferences.getString(KEY_MEDIA_UPLOADER, null);
|
||||
final String shortenerComponent = mPreferences.getString(KEY_STATUS_SHORTENER, null);
|
||||
mUseUploader = !ServicePickerPreference.isNoneValue(uploaderComponent);
|
||||
@ -292,16 +291,17 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
final SingleResponse<ParcelableDirectMessage> result = sendDirectMessage(builder, accountId, recipientId, text,
|
||||
imageUri);
|
||||
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
if (result.getData() != null && result.getData().id > 0) {
|
||||
final ContentValues values = ContentValuesCreator.createDirectMessage(result.getData());
|
||||
final String delete_where = DirectMessages.ACCOUNT_ID + " = " + accountId + " AND "
|
||||
+ DirectMessages.MESSAGE_ID + " = " + result.getData().id;
|
||||
mResolver.delete(DirectMessages.Outbox.CONTENT_URI, delete_where, null);
|
||||
mResolver.insert(DirectMessages.Outbox.CONTENT_URI, values);
|
||||
resolver.delete(DirectMessages.Outbox.CONTENT_URI, delete_where, null);
|
||||
resolver.insert(DirectMessages.Outbox.CONTENT_URI, values);
|
||||
showOkMessage(R.string.direct_message_sent, false);
|
||||
} else {
|
||||
final ContentValues values = createMessageDraft(accountId, recipientId, text, imageUri);
|
||||
mResolver.insert(Drafts.CONTENT_URI, values);
|
||||
resolver.insert(Drafts.CONTENT_URI, values);
|
||||
showErrorMessage(R.string.action_sending_direct_message, result.getException(), true);
|
||||
}
|
||||
stopForeground(false);
|
||||
@ -333,7 +333,8 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
updateUpdateStatusNotification(this, builder, 0, item));
|
||||
final ContentValues draftValues = ContentValuesCreator.createStatusDraft(item,
|
||||
ParcelableAccount.getAccountIds(item.accounts));
|
||||
final Uri draftUri = mResolver.insert(Drafts.CONTENT_URI, draftValues);
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
final Uri draftUri = resolver.insert(Drafts.CONTENT_URI, draftValues);
|
||||
final long def = -1;
|
||||
final long draftId = draftUri != null ? NumberUtils.toLong(draftUri.getLastPathSegment(), def) : -1;
|
||||
mTwitter.addSendingDraftId(draftId);
|
||||
@ -371,15 +372,15 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
} else {
|
||||
final ContentValues accountIdsValues = new ContentValues();
|
||||
accountIdsValues.put(Drafts.ACCOUNT_IDS, TwidereListUtils.toString(failedAccountIds, ',', false));
|
||||
mResolver.update(Drafts.CONTENT_URI, accountIdsValues, where.getSQL(), null);
|
||||
resolver.update(Drafts.CONTENT_URI, accountIdsValues, where.getSQL(), null);
|
||||
showErrorMessage(R.string.action_updating_status, exception, true);
|
||||
final ContentValues notifValues = new ContentValues();
|
||||
notifValues.put(BaseColumns._ID, draftId);
|
||||
mResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, notifValues);
|
||||
resolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, notifValues);
|
||||
}
|
||||
} else {
|
||||
showOkMessage(R.string.status_updated, false);
|
||||
mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
||||
resolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
||||
if (item.media != null) {
|
||||
for (final ParcelableMediaUpdate media : item.media) {
|
||||
final String path = getImagePathFromUri(this, Uri.parse(media.uri));
|
||||
@ -453,7 +454,7 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
private List<SingleResponse<ParcelableStatus>> updateStatus(final Builder builder,
|
||||
final ParcelableStatusUpdate statusUpdate) {
|
||||
final ArrayList<ContentValues> hashTagValues = new ArrayList<>();
|
||||
final Collection<String> hashTags = extractor.extractHashtags(statusUpdate.text);
|
||||
final Collection<String> hashTags = mExtractor.extractHashtags(statusUpdate.text);
|
||||
for (final String hashTag : hashTags) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(CachedHashtags.NAME, hashTag);
|
||||
@ -464,7 +465,8 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
&& statusUpdate.text.contains(EASTER_EGG_RESTORE_TEXT_PART2)
|
||||
&& statusUpdate.text.contains(EASTER_EGG_RESTORE_TEXT_PART3);
|
||||
boolean mentionedHondaJOJO = false, notReplyToOther = false;
|
||||
mResolver.bulkInsert(CachedHashtags.CONTENT_URI,
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.bulkInsert(CachedHashtags.CONTENT_URI,
|
||||
hashTagValues.toArray(new ContentValues[hashTagValues.size()]));
|
||||
|
||||
final List<SingleResponse<ParcelableStatus>> results = new ArrayList<>();
|
||||
@ -547,8 +549,8 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||
for (int i = 0, j = mediaIds.length; i < j; i++) {
|
||||
final ParcelableMediaUpdate media = statusUpdate.media[i];
|
||||
final Uri mediaUri = Uri.parse(media.uri);
|
||||
final String mediaType = mResolver.getType(mediaUri);
|
||||
final InputStream is = mResolver.openInputStream(mediaUri);
|
||||
final String mediaType = resolver.getType(mediaUri);
|
||||
final InputStream is = resolver.openInputStream(mediaUri);
|
||||
final long length = is.available();
|
||||
cis = new ContentLengthInputStream(is, length);
|
||||
cis.setReadListener(new StatusMediaUploadListener(this, mNotificationManager, builder,
|
||||
|
@ -93,6 +93,8 @@ import org.mariotaku.twidere.util.message.ProfileUpdatedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
|
||||
import org.mariotaku.twidere.util.message.UserListCreatedEvent;
|
||||
import org.mariotaku.twidere.util.message.UserListDestroyedEvent;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
@ -207,9 +209,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
return mAsyncTaskManager.add(task, true);
|
||||
}
|
||||
|
||||
public int createUserListAsync(final long accountId, final String list_name, final boolean is_public,
|
||||
public int createUserListAsync(final long accountId, final String listName, final boolean isPublic,
|
||||
final String description) {
|
||||
final CreateUserListTask task = new CreateUserListTask(accountId, list_name, is_public, description);
|
||||
final CreateUserListTask task = new CreateUserListTask(mContext, accountId, listName, isPublic,
|
||||
description);
|
||||
return mAsyncTaskManager.add(task, true);
|
||||
}
|
||||
|
||||
@ -269,7 +272,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
}
|
||||
|
||||
public int destroyUserListAsync(final long accountId, final long listId) {
|
||||
final DestroyUserListTask task = new DestroyUserListTask(accountId, listId);
|
||||
final DestroyUserListTask task = new DestroyUserListTask(mContext, accountId, listId);
|
||||
return mAsyncTaskManager.add(task, true);
|
||||
}
|
||||
|
||||
@ -1245,48 +1248,47 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
}
|
||||
|
||||
class CreateUserListTask extends ManagedAsyncTask<Object, Object, SingleResponse<UserList>> {
|
||||
static class CreateUserListTask extends ManagedAsyncTask<Object, Object, SingleResponse<ParcelableUserList>> {
|
||||
|
||||
private final long account_id;
|
||||
private final String list_name, description;
|
||||
private final boolean is_public;
|
||||
private final long accountId;
|
||||
private final String listName, description;
|
||||
private final boolean isPublic;
|
||||
|
||||
public CreateUserListTask(final long account_id, final String list_name, final boolean is_public,
|
||||
public CreateUserListTask(Context context, final long accountId, final String listName, final boolean isPublic,
|
||||
final String description) {
|
||||
super(mContext);
|
||||
this.account_id = account_id;
|
||||
this.list_name = list_name;
|
||||
super(context);
|
||||
this.accountId = accountId;
|
||||
this.listName = listName;
|
||||
this.description = description;
|
||||
this.is_public = is_public;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SingleResponse<UserList> doInBackground(final Object... params) {
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false);
|
||||
if (twitter == null || list_name == null) return SingleResponse.getInstance();
|
||||
protected SingleResponse<ParcelableUserList> doInBackground(final Object... params) {
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), accountId, false);
|
||||
if (twitter == null || listName == null) return SingleResponse.getInstance();
|
||||
try {
|
||||
final UserListUpdate userListUpdate = new UserListUpdate();
|
||||
userListUpdate.setName(list_name);
|
||||
userListUpdate.setMode(is_public ? UserList.Mode.PUBLIC : UserList.Mode.PRIVATE);
|
||||
userListUpdate.setName(listName);
|
||||
userListUpdate.setMode(isPublic ? UserList.Mode.PUBLIC : UserList.Mode.PRIVATE);
|
||||
userListUpdate.setDescription(description);
|
||||
final UserList list = twitter.createUserList(userListUpdate);
|
||||
return SingleResponse.getInstance(list, null);
|
||||
return SingleResponse.getInstance(new ParcelableUserList(list, accountId), null);
|
||||
} catch (final TwitterException e) {
|
||||
return SingleResponse.getInstance(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final SingleResponse<UserList> result) {
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUserList> result) {
|
||||
final Context context = getContext();
|
||||
if (result.hasData()) {
|
||||
final UserList userList = result.getData();
|
||||
final String message = mContext.getString(R.string.created_list, userList.getName());
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_CREATED);
|
||||
intent.putExtra(EXTRA_USER_LIST, new ParcelableUserList(userList, account_id));
|
||||
mContext.sendBroadcast(intent);
|
||||
final ParcelableUserList userList = result.getData();
|
||||
final String message = context.getString(R.string.created_list, userList.name);
|
||||
Utils.showOkMessage(context, message, false);
|
||||
bus.post(new UserListCreatedEvent(userList));
|
||||
} else {
|
||||
Utils.showErrorMessage(mContext, R.string.action_creating_list, result.getException(), true);
|
||||
Utils.showErrorMessage(context, R.string.action_creating_list, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1870,13 +1872,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
}
|
||||
|
||||
class DestroyUserListTask extends ManagedAsyncTask<Object, Object, SingleResponse<ParcelableUserList>> {
|
||||
static class DestroyUserListTask extends ManagedAsyncTask<Object, Object, SingleResponse<ParcelableUserList>> {
|
||||
|
||||
private final long mAccountId;
|
||||
private final long mListId;
|
||||
|
||||
public DestroyUserListTask(final long accountId, final long listId) {
|
||||
super(mContext);
|
||||
public DestroyUserListTask(Context context, final long accountId, final long listId) {
|
||||
super(context);
|
||||
mAccountId = accountId;
|
||||
mListId = listId;
|
||||
}
|
||||
@ -1884,7 +1886,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
@Override
|
||||
protected SingleResponse<ParcelableUserList> doInBackground(final Object... params) {
|
||||
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false);
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, false);
|
||||
if (twitter != null) {
|
||||
try {
|
||||
if (mListId > 0) {
|
||||
@ -1902,14 +1904,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
@Override
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUserList> result) {
|
||||
final boolean succeed = result.hasData();
|
||||
final Context context = getContext();
|
||||
if (succeed) {
|
||||
final String message = mContext.getString(R.string.deleted_list, result.getData().name);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_DELETED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
mContext.sendBroadcast(intent);
|
||||
final String message = context.getString(R.string.deleted_list, result.getData().name);
|
||||
Utils.showInfoMessage(context, message, false);
|
||||
bus.post(new UserListDestroyedEvent(result.getData()));
|
||||
} else {
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(context, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.twitter.Validator;
|
||||
@ -29,35 +28,29 @@ import org.mariotaku.twidere.Constants;
|
||||
|
||||
public class TwidereValidator implements Constants {
|
||||
|
||||
private final int mMaxTweetLength;
|
||||
private final Validator mValidator;
|
||||
private final int mMaxTweetLength;
|
||||
private final Validator mValidator;
|
||||
|
||||
public TwidereValidator(final Context context) {
|
||||
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
mValidator = new Validator();
|
||||
if (prefs != null) {
|
||||
final String textLimit = prefs.getString(KEY_STATUS_TEXT_LIMIT, null);
|
||||
mMaxTweetLength = NumberUtils.toInt(textLimit, Validator.MAX_TWEET_LENGTH);
|
||||
} else {
|
||||
mMaxTweetLength = Validator.MAX_TWEET_LENGTH;
|
||||
}
|
||||
}
|
||||
public TwidereValidator(final SharedPreferencesWrapper preferences) {
|
||||
mValidator = new Validator();
|
||||
final String textLimit = preferences.getString(KEY_STATUS_TEXT_LIMIT, null);
|
||||
mMaxTweetLength = NumberUtils.toInt(textLimit, Validator.MAX_TWEET_LENGTH);
|
||||
}
|
||||
|
||||
public int getMaxTweetLength() {
|
||||
return mMaxTweetLength;
|
||||
}
|
||||
public int getMaxTweetLength() {
|
||||
return mMaxTweetLength;
|
||||
}
|
||||
|
||||
public int getTweetLength(final String text) {
|
||||
return mValidator.getTweetLength(text);
|
||||
}
|
||||
public int getTweetLength(final String text) {
|
||||
return mValidator.getTweetLength(text);
|
||||
}
|
||||
|
||||
public boolean isValidTweet(final String text) {
|
||||
return !TextUtils.isEmpty(text) && getTweetLength(text) <= getMaxTweetLength();
|
||||
}
|
||||
public boolean isValidTweet(final String text) {
|
||||
return !TextUtils.isEmpty(text) && getTweetLength(text) <= getMaxTweetLength();
|
||||
}
|
||||
|
||||
public boolean isValidDirectMessage(final CharSequence text) {
|
||||
return !TextUtils.isEmpty(text);
|
||||
}
|
||||
public boolean isValidDirectMessage(final CharSequence text) {
|
||||
return !TextUtils.isEmpty(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,19 +49,14 @@ public class UserColorNameManager implements TwidereConstants {
|
||||
mNicknamePreferences = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static void registerOnUserColorChangedListener(final Context context,
|
||||
final OnUserColorChangedListener listener) {
|
||||
public void registerColorChangedListener(final UserColorChangedListener listener) {
|
||||
|
||||
final SharedPreferences prefs = context.getSharedPreferences(USER_COLOR_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
prefs.registerOnSharedPreferenceChangeListener(new OnColorPreferenceChangeListener(listener));
|
||||
mColorPreferences.registerOnSharedPreferenceChangeListener(new OnColorPreferenceChangeListener(listener));
|
||||
}
|
||||
|
||||
public static void registerOnUserNicknameChangedListener(final Context context,
|
||||
final OnUserNicknameChangedListener listener) {
|
||||
public void registerNicknameChangedListener(final UserNicknameChangedListener listener) {
|
||||
|
||||
final SharedPreferences prefs = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
prefs.registerOnSharedPreferenceChangeListener(new OnNickPreferenceChangeListener(listener));
|
||||
mNicknamePreferences.registerOnSharedPreferenceChangeListener(new OnNickPreferenceChangeListener(listener));
|
||||
}
|
||||
|
||||
public void clearUserColor(final long userId) {
|
||||
@ -159,19 +154,19 @@ public class UserColorNameManager implements TwidereConstants {
|
||||
return TextUtils.isEmpty(nick) ? name : nick;
|
||||
}
|
||||
|
||||
public interface OnUserColorChangedListener {
|
||||
public interface UserColorChangedListener {
|
||||
void onUserColorChanged(long userId, int color);
|
||||
}
|
||||
|
||||
public interface OnUserNicknameChangedListener {
|
||||
public interface UserNicknameChangedListener {
|
||||
void onUserNicknameChanged(long userId, String nick);
|
||||
}
|
||||
|
||||
private static final class OnColorPreferenceChangeListener implements OnSharedPreferenceChangeListener {
|
||||
|
||||
private final OnUserColorChangedListener mListener;
|
||||
private final UserColorChangedListener mListener;
|
||||
|
||||
OnColorPreferenceChangeListener(final OnUserColorChangedListener listener) {
|
||||
OnColorPreferenceChangeListener(final UserColorChangedListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@ -188,9 +183,9 @@ public class UserColorNameManager implements TwidereConstants {
|
||||
|
||||
private static final class OnNickPreferenceChangeListener implements OnSharedPreferenceChangeListener {
|
||||
|
||||
private final OnUserNicknameChangedListener mListener;
|
||||
private final UserNicknameChangedListener mListener;
|
||||
|
||||
OnNickPreferenceChangeListener(final OnUserNicknameChangedListener listener) {
|
||||
OnNickPreferenceChangeListener(final UserNicknameChangedListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.nostra13.universalimageloader.utils.L;
|
||||
import com.squareup.okhttp.Dns;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.ThreadEnforcer;
|
||||
import com.twitter.Extractor;
|
||||
|
||||
import org.mariotaku.mediaviewer.library.FileCache;
|
||||
import org.mariotaku.mediaviewer.library.MediaDownloader;
|
||||
@ -54,6 +55,7 @@ import org.mariotaku.twidere.util.NotificationManagerWrapper;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.TwidereMathUtils;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.imageloader.ReadOnlyDiskLRUNameCache;
|
||||
@ -216,6 +218,18 @@ public class ApplicationModule implements Constants {
|
||||
return new TwidereMediaDownloader(application, preferences, client);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public TwidereValidator twidereValidator(SharedPreferencesWrapper preferences) {
|
||||
return new TwidereValidator(preferences);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Extractor extractor() {
|
||||
return new Extractor();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ErrorInfoStore errorInfoStore() {
|
||||
|
@ -27,6 +27,7 @@ import org.mariotaku.restfu.http.RestHttpClient;
|
||||
import org.mariotaku.twidere.util.ActivityTracker;
|
||||
import org.mariotaku.twidere.util.ExternalThemeManager;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -50,6 +51,8 @@ public class DependencyHolder {
|
||||
ActivityTracker mActivityTracker;
|
||||
@Inject
|
||||
Dns mDns;
|
||||
@Inject
|
||||
TwidereValidator mValidator;
|
||||
|
||||
DependencyHolder(Context context) {
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
@ -83,4 +86,8 @@ public class DependencyHolder {
|
||||
public Dns getDns() {
|
||||
return mDns;
|
||||
}
|
||||
|
||||
public TwidereValidator getValidator() {
|
||||
return mValidator;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import android.support.v7.widget.RecyclerView;
|
||||
import org.mariotaku.twidere.activity.BasePreferenceActivity;
|
||||
import org.mariotaku.twidere.activity.BaseThemedActivity;
|
||||
import org.mariotaku.twidere.activity.support.BaseAppCompatActivity;
|
||||
import org.mariotaku.twidere.activity.support.ComposeActivity;
|
||||
import org.mariotaku.twidere.activity.support.MediaViewerActivity;
|
||||
import org.mariotaku.twidere.activity.support.ThemedFragmentActivity;
|
||||
import org.mariotaku.twidere.adapter.AccountsAdapter;
|
||||
@ -85,6 +86,8 @@ public interface GeneralComponent {
|
||||
|
||||
void inject(ThemedFragmentActivity object);
|
||||
|
||||
void inject(ComposeActivity object);
|
||||
|
||||
void inject(TwidereDataProvider object);
|
||||
|
||||
void inject(BaseListFragment object);
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util.message;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/10.
|
||||
*/
|
||||
public class UserListCreatedEvent {
|
||||
|
||||
@NonNull
|
||||
public final ParcelableUserList userList;
|
||||
|
||||
public UserListCreatedEvent(@NonNull ParcelableUserList userList) {
|
||||
this.userList = userList;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util.message;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/10.
|
||||
*/
|
||||
public class UserListDestroyedEvent {
|
||||
|
||||
@NonNull
|
||||
public final ParcelableUserList userList;
|
||||
|
||||
public UserListDestroyedEvent(@NonNull ParcelableUserList userList) {
|
||||
this.userList = userList;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.v4.view.accessibility.AccessibilityEventCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.Checkable;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/1.
|
||||
*/
|
||||
public class CheckableLinearLayout extends LinearLayout implements Checkable {
|
||||
private boolean mChecked;
|
||||
|
||||
public CheckableLinearLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CheckableLinearLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
event.setChecked(isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.setCheckable(true);
|
||||
info.setChecked(isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
mChecked = checked;
|
||||
sendAccessibilityEvent(AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggle() {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.dagger.DependencyHolder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@ -48,7 +49,7 @@ public class StatusTextCountView extends AppCompatTextView {
|
||||
|
||||
public StatusTextCountView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mValidator = new TwidereValidator(context);
|
||||
mValidator = DependencyHolder.get(context).getValidator();
|
||||
if (isInEditMode()) {
|
||||
mTextColor = 0;
|
||||
mLocale = Locale.getDefault();
|
||||
|
@ -409,7 +409,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
|
||||
} else if (TwitterCardUtils.CARD_NAME_PLAYER.equals(cardName)) {
|
||||
extraTypeView.setImageResource(sensitive ? R.drawable.ic_action_warning : R.drawable.ic_action_play_circle);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (media != null && media.length > 0) {
|
||||
} else if (!ArrayUtils.isEmpty(media)) {
|
||||
if (hasVideo(media)) {
|
||||
extraTypeView.setImageResource(sensitive ? R.drawable.ic_action_warning : R.drawable.ic_action_movie);
|
||||
} else {
|
||||
@ -426,9 +426,11 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
|
||||
|
||||
boolean hasVideo(ParcelableMedia[] media) {
|
||||
for (ParcelableMedia mediaItem : media) {
|
||||
if (mediaItem.type == ParcelableMedia.Type.TYPE_VIDEO
|
||||
|| mediaItem.type == ParcelableMedia.Type.TYPE_ANIMATED_GIF)
|
||||
return true;
|
||||
switch (mediaItem.type) {
|
||||
case ParcelableMedia.Type.TYPE_VIDEO:
|
||||
case ParcelableMedia.Type.TYPE_ANIMATED_GIF:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -168,6 +168,7 @@
|
||||
android:layout_alignStart="@id/account_profile_image_frame"
|
||||
android:layout_alignTop="@id/account_profile_image_frame"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/select_accounts_for_compose"
|
||||
android:textColor="?android:colorForeground"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"
|
||||
android:baselineAligned="false">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/account_selector_button"
|
||||
style="?actionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:clickable="true"
|
||||
android:paddingBottom="@dimen/element_spacing_msmall"
|
||||
android:paddingEnd="@dimen/element_spacing_msmall"
|
||||
android:paddingLeft="@dimen/element_spacing_msmall"
|
||||
android:paddingRight="@dimen/element_spacing_msmall"
|
||||
android:paddingStart="@dimen/element_spacing_msmall"
|
||||
android:paddingTop="@dimen/element_spacing_msmall">
|
||||
|
||||
<org.mariotaku.twidere.view.SquareFrameLayout
|
||||
android:id="@+id/account_profile_image_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<org.mariotaku.twidere.view.ShapedImageView
|
||||
android:id="@+id/account_profile_image"
|
||||
style="?profileImageStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
app:sivBackgroundColor="?android:colorBackground"
|
||||
app:sivBorder="true"
|
||||
app:sivBorderWidth="@dimen/line_width_compose_account_profile_image" />
|
||||
</org.mariotaku.twidere.view.SquareFrameLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.BadgeView
|
||||
android:id="@+id/accounts_count"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@id/account_profile_image_frame"
|
||||
android:layout_alignEnd="@id/account_profile_image_frame"
|
||||
android:layout_alignLeft="@id/account_profile_image_frame"
|
||||
android:layout_alignRight="@id/account_profile_image_frame"
|
||||
android:layout_alignStart="@id/account_profile_image_frame"
|
||||
android:layout_alignTop="@id/account_profile_image_frame"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="?android:colorForeground" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toEndOf="@+id/account_selector_button"
|
||||
android:layout_toLeftOf="@+id/send"
|
||||
android:layout_toRightOf="@+id/account_selector_button"
|
||||
android:layout_toStartOf="@+id/send"
|
||||
android:scrollbars="none">
|
||||
|
||||
<android.support.v7.widget.ActionMenuView
|
||||
android:id="@+id/menu_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:background="@null" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/send"
|
||||
style="?actionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:contentDescription="@string/send"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/element_spacing_normal"
|
||||
android:paddingEnd="@dimen/element_spacing_normal"
|
||||
android:paddingLeft="@dimen/element_spacing_large"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:paddingStart="@dimen/element_spacing_large"
|
||||
android:paddingTop="@dimen/element_spacing_normal">
|
||||
|
||||
<org.mariotaku.twidere.view.StatusTextCountView
|
||||
android:id="@+id/status_text_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minWidth="@dimen/element_size_small"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
tools:text="140" />
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:color="?android:textColorSecondary"
|
||||
android:contentDescription="@string/send"
|
||||
android:cropToPadding="false"
|
||||
android:padding="@dimen/element_spacing_xsmall"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_action_send" />
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
@ -16,7 +16,7 @@
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout
|
||||
<org.mariotaku.twidere.view.CheckableLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tool="http://schemas.android.com/tools"
|
||||
@ -57,4 +57,4 @@
|
||||
tool:text="Name"/>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
</LinearLayout>
|
||||
</org.mariotaku.twidere.view.CheckableLinearLayout>
|
@ -841,4 +841,5 @@
|
||||
<string name="title_summary_line_format"><xliff:g id="title">%1$s</xliff:g>: <xliff:g id="summary">%2$s</xliff:g></string>
|
||||
<string name="mentions_only">Mentions only</string>
|
||||
<string name="error_no_dm_permission">No direct message permission, check your Twitter application permission setting.</string>
|
||||
<string name="select_accounts_for_compose">Select accounts for compose</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user