migrating account

This commit is contained in:
Mariotaku Lee 2016-03-06 23:17:28 +08:00
parent 3abb5a1219
commit 305ff7cbd3
63 changed files with 794 additions and 600 deletions

View File

@ -128,13 +128,13 @@ public class Activity extends TwitterResponseObject implements TwitterResponse,
'}';
}
public static Activity fromMention(long accountId, Status status) {
public static Activity fromMention(long twitterId, Status status) {
final Activity activity = new Activity();
activity.maxPosition = activity.minPosition = status.getId();
activity.createdAt = status.getCreatedAt();
if (status.getInReplyToUserId() == accountId) {
if (status.getInReplyToUserId() == twitterId) {
activity.action = Action.REPLY;
activity.rawAction = "reply";
activity.targetStatuses = new Status[]{status};

View File

@ -58,8 +58,10 @@ public final class ParcelableCardEntity implements Parcelable {
};
@ParcelableThisPlease
@JsonField(name = "account_id")
public
long account_id;
public long account_id;
@ParcelableThisPlease
@JsonField(name = "account_host")
public String account_host;
@ParcelableThisPlease
@JsonField(name = "name")
public String name;

View File

@ -57,6 +57,10 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
@CursorField(DirectMessages.ACCOUNT_ID)
public long account_id;
@ParcelableThisPlease
@JsonField(name = "account_host")
@CursorField(DirectMessages.ACCOUNT_HOST)
public String account_host;
@ParcelableThisPlease
@JsonField(name = "id")
@CursorField(DirectMessages.MESSAGE_ID)
public long id;

View File

@ -440,11 +440,11 @@ public interface TwidereDataStore {
String CONTENT_PATH_SEGMENT = "conversation_entries";
String CONTENT_PATH = DirectMessages.CONTENT_PATH + "/" + CONTENT_PATH_SEGMENT;
Uri CONTENT_URI = Uri
.withAppendedPath(DirectMessages.CONTENT_URI, CONTENT_PATH_SEGMENT);
Uri CONTENT_URI = Uri.withAppendedPath(DirectMessages.CONTENT_URI, CONTENT_PATH_SEGMENT);
String MESSAGE_ID = DirectMessages.MESSAGE_ID;
String ACCOUNT_ID = DirectMessages.ACCOUNT_ID;
String ACCOUNT_HOST = DirectMessages.ACCOUNT_HOST;
String IS_OUTGOING = DirectMessages.IS_OUTGOING;
String MESSAGE_TIMESTAMP = DirectMessages.MESSAGE_TIMESTAMP;
String NAME = "name";
@ -457,12 +457,13 @@ public interface TwidereDataStore {
int IDX_MESSAGE_TIMESTAMP = 1;
int IDX_MESSAGE_ID = 2;
int IDX_ACCOUNT_ID = 3;
int IDX_IS_OUTGOING = 4;
int IDX_NAME = 5;
int IDX_SCREEN_NAME = 6;
int IDX_PROFILE_IMAGE_URL = 7;
int IDX_TEXT = 8;
int IDX_CONVERSATION_ID = 9;
int IDX_ACCOUNT_HOST = 4;
int IDX_IS_OUTGOING = 5;
int IDX_NAME = 6;
int IDX_SCREEN_NAME = 7;
int IDX_PROFILE_IMAGE_URL = 8;
int IDX_TEXT = 9;
int IDX_CONVERSATION_ID = 10;
}
interface Inbox extends DirectMessages {

View File

@ -31,6 +31,8 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.twidere.model.AccountKey;
import java.util.TimeZone;
import edu.tsinghua.hotmobi.util.LocationUtils;
@ -92,9 +94,9 @@ public class NotificationEvent extends BaseEvent implements Parcelable {
}
public static NotificationEvent deleted(Context context, long postTime, String type,
long accountId, long itemId, long itemUserId,
AccountKey accountKey, long itemId, long itemUserId,
boolean itemUserFollowing) {
return create(context, Action.DELETE, System.currentTimeMillis(), postTime, type, accountId,
return create(context, Action.DELETE, System.currentTimeMillis(), postTime, type, accountKey.getId(),
itemId, itemUserId, itemUserFollowing);
}

View File

@ -51,7 +51,6 @@ import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.LongSparseArray;
import android.support.v7.view.SupportMenuInflater;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.ActionMenuView.OnMenuItemClickListener;
@ -158,7 +157,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import javax.inject.Inject;
@ -298,7 +299,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
@Override
public void onSaveInstanceState(final Bundle outState) {
outState.putLongArray(EXTRA_ACCOUNT_IDS, mAccountsAdapter.getSelectedAccountIds());
outState.putParcelableArray(EXTRA_ACCOUNT_KEYS, mAccountsAdapter.getSelectedAccountKeys());
outState.putParcelableArrayList(EXTRA_MEDIA, new ArrayList<Parcelable>(getMediaList()));
outState.putBoolean(EXTRA_IS_POSSIBLY_SENSITIVE, mIsPossiblySensitive);
outState.putParcelable(EXTRA_STATUS, mInReplyToStatus);
@ -441,13 +442,14 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
try {
final String action = intent.getAction();
if (INTENT_ACTION_EXTENSION_COMPOSE.equals(action)) {
final long[] accountIds = mAccountsAdapter.getSelectedAccountIds();
final AccountKey[] accountKeys = mAccountsAdapter.getSelectedAccountKeys();
intent.putExtra(EXTRA_TEXT, ParseUtils.parseString(mEditText.getText()));
intent.putExtra(EXTRA_ACCOUNT_IDS, accountIds);
if (accountIds.length > 0) {
final long account_id = accountIds[0];
intent.putExtra(EXTRA_NAME, DataStoreUtils.getAccountName(this, account_id));
intent.putExtra(EXTRA_SCREEN_NAME, DataStoreUtils.getAccountScreenName(this, account_id));
intent.putExtra(EXTRA_ACCOUNT_IDS, AccountKey.getIds(accountKeys));
intent.putExtra(EXTRA_ACCOUNT_KEYS, accountKeys);
if (accountKeys.length > 0) {
final AccountKey accountKey = accountKeys[0];
intent.putExtra(EXTRA_NAME, DataStoreUtils.getAccountName(this, accountKey));
intent.putExtra(EXTRA_SCREEN_NAME, DataStoreUtils.getAccountScreenName(this, accountKey));
}
if (mInReplyToStatus != null) {
intent.putExtra(EXTRA_IN_REPLY_TO_ID, mInReplyToStatus.id);
@ -561,7 +563,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
final Draft draft = new Draft();
draft.action_type = getDraftAction(getIntent().getAction());
draft.account_ids = mAccountsAdapter.getSelectedAccountIds();
draft.account_ids = AccountKey.getIds(mAccountsAdapter.getSelectedAccountKeys());
draft.text = text;
final UpdateStatusActionExtra extra = new UpdateStatusActionExtra();
extra.setInReplyToStatus(mInReplyToStatus);
@ -626,7 +628,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
finish();
return;
}
final long[] defaultAccountIds = DataStoreUtils.getAccountKeys(accounts);
final AccountKey[] defaultAccountIds = DataStoreUtils.getAccountKeys(accounts);
mMenuBar.setOnMenuItemClickListener(this);
setupEditText();
mAccountSelectorContainer.setOnClickListener(this);
@ -657,7 +659,8 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
if (savedInstanceState != null) {
// Restore from previous saved state
mAccountsAdapter.setSelectedAccountIds(savedInstanceState.getLongArray(EXTRA_ACCOUNT_IDS));
mAccountsAdapter.setSelectedAccountIds(Utils.newParcelableArray(
savedInstanceState.getParcelableArray(EXTRA_ACCOUNT_KEY), AccountKey.CREATOR));
mIsPossiblySensitive = savedInstanceState.getBoolean(EXTRA_IS_POSSIBLY_SENSITIVE);
final ArrayList<ParcelableMediaUpdate> mediaList = savedInstanceState.getParcelableArrayList(EXTRA_MEDIA);
if (mediaList != null) {
@ -680,12 +683,15 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
handleDefaultIntent(intent);
}
setLabel(intent);
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);
mAccountsAdapter.setSelectedAccountIds(intersection.length > 0 ? intersection : defaultAccountIds);
final AccountKey[] selectedAccountIds = mAccountsAdapter.getSelectedAccountKeys();
if (ArrayUtils.isEmpty(selectedAccountIds)) {
final AccountKey[] idsInPrefs = AccountKey.arrayOf(mPreferences.getString(KEY_COMPOSE_ACCOUNTS, null));
AccountKey[] intersection = null;
if (idsInPrefs != null) {
intersection = TwidereArrayUtils.intersection(idsInPrefs, defaultAccountIds);
}
mAccountsAdapter.setSelectedAccountIds(ArrayUtils.isEmpty(intersection) ? defaultAccountIds : intersection);
}
mOriginalText = ParseUtils.parseString(mEditText.getText());
}
@ -866,10 +872,13 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
final String action = intent.getAction();
final boolean hasAccountIds;
if (intent.hasExtra(EXTRA_ACCOUNT_IDS)) {
mAccountsAdapter.setSelectedAccountIds(intent.getLongArrayExtra(EXTRA_ACCOUNT_IDS));
final AccountKey[] accountKeys = Utils.newParcelableArray(
intent.getParcelableArrayExtra(EXTRA_ACCOUNT_KEYS), AccountKey.CREATOR);
mAccountsAdapter.setSelectedAccountIds(accountKeys);
hasAccountIds = true;
} else if (intent.hasExtra(EXTRA_ACCOUNT_ID)) {
mAccountsAdapter.setSelectedAccountIds(intent.getLongExtra(EXTRA_ACCOUNT_ID, -1));
final AccountKey accountKey = intent.getParcelableExtra(EXTRA_ACCOUNT_KEY);
mAccountsAdapter.setSelectedAccountIds(accountKey);
hasAccountIds = true;
} else {
hasAccountIds = false;
@ -997,9 +1006,9 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
}
case INTENT_ACTION_REPLY_MULTIPLE: {
final String[] screenNames = intent.getStringArrayExtra(EXTRA_SCREEN_NAMES);
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
final AccountKey accountKey = intent.getParcelableExtra(EXTRA_ACCOUNT_KEYS);
final ParcelableStatus inReplyToStatus = intent.getParcelableExtra(EXTRA_IN_REPLY_TO_STATUS);
return handleReplyMultipleIntent(screenNames, accountId, inReplyToStatus);
return handleReplyMultipleIntent(screenNames, accountKey, inReplyToStatus);
}
case INTENT_ACTION_COMPOSE_TAKE_PHOTO: {
return takePhoto();
@ -1014,12 +1023,13 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
private boolean handleMentionIntent(final ParcelableUser user) {
if (user == null || user.id <= 0) return false;
final String my_screen_name = DataStoreUtils.getAccountScreenName(this, user.account_id);
if (TextUtils.isEmpty(my_screen_name)) return false;
final String accountScreenName = DataStoreUtils.getAccountScreenName(this,
new AccountKey(user.account_id, user.account_host));
if (TextUtils.isEmpty(accountScreenName)) return false;
mEditText.setText(String.format("@%s ", user.screen_name));
final int selection_end = mEditText.length();
mEditText.setSelection(selection_end);
mAccountsAdapter.setSelectedAccountIds(user.account_id);
mAccountsAdapter.setSelectedAccountIds(new AccountKey(user.account_id, user.account_host));
return true;
}
@ -1027,7 +1037,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
if (status == null || status.id <= 0) return false;
mEditText.setText(Utils.getQuoteStatus(this, status.id, status.user_screen_name, status.text_plain));
mEditText.setSelection(0);
mAccountsAdapter.setSelectedAccountIds(status.account_id);
mAccountsAdapter.setSelectedAccountIds(new AccountKey(status.account_id, status.account_host));
showQuoteLabel(status);
return true;
}
@ -1061,7 +1071,8 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
private boolean handleReplyIntent(final ParcelableStatus status) {
if (status == null || status.id <= 0) return false;
final String myScreenName = DataStoreUtils.getAccountScreenName(this, status.account_id);
final String myScreenName = DataStoreUtils.getAccountScreenName(this,
new AccountKey(status.account_id, status.account_host));
if (TextUtils.isEmpty(myScreenName)) return false;
int selectionStart = 0;
mEditText.append("@" + status.user_screen_name + " ");
@ -1088,14 +1099,14 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
}
final int selectionEnd = mEditText.length();
mEditText.setSelection(selectionStart, selectionEnd);
mAccountsAdapter.setSelectedAccountIds(status.account_id);
mAccountsAdapter.setSelectedAccountIds(new AccountKey(status.account_id, status.account_host));
showReplyLabel(status);
return true;
}
private boolean handleReplyMultipleIntent(final String[] screenNames, final long accountId,
private boolean handleReplyMultipleIntent(final String[] screenNames, final AccountKey accountId,
final ParcelableStatus inReplyToStatus) {
if (screenNames == null || screenNames.length == 0 || accountId <= 0) return false;
if (screenNames == null || screenNames.length == 0 || accountId == null) return false;
final String myScreenName = DataStoreUtils.getAccountScreenName(this, accountId);
if (TextUtils.isEmpty(myScreenName)) return false;
for (final String screenName : screenNames) {
@ -1152,7 +1163,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
private void saveAccountSelection() {
if (!mShouldSaveAccounts) return;
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putString(KEY_COMPOSE_ACCOUNTS, TwidereArrayUtils.toString(mAccountsAdapter.getSelectedAccountIds(), ',', false));
editor.putString(KEY_COMPOSE_ACCOUNTS, TwidereArrayUtils.toString(mAccountsAdapter.getSelectedAccountKeys(), ',', false));
editor.apply();
}
@ -1328,7 +1339,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
return;
}
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false);
final long[] accountIds = mAccountsAdapter.getSelectedAccountIds();
final AccountKey[] accountKeys = mAccountsAdapter.getSelectedAccountKeys();
final ParcelableLocation statusLocation = attachLocation ? mRecentLocation : null;
final boolean isPossiblySensitive = hasMedia && mIsPossiblySensitive;
final ParcelableStatusUpdate update = new ParcelableStatusUpdate();
@ -1338,7 +1349,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
} else {
action = getDraftAction(getIntent().getAction());
}
update.accounts = ParcelableAccountUtils.getAccounts(this, accountIds);
update.accounts = ParcelableAccountUtils.getAccounts(this, accountKeys);
update.text = text;
update.location = statusLocation;
update.media = getMedia();
@ -1470,7 +1481,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
private final ComposeActivity mActivity;
private final LayoutInflater mInflater;
private final LongSparseArray<Boolean> mSelection;
private final Map<AccountKey, Boolean> mSelection;
private final boolean mNameFirst;
private ParcelableCredentials[] mAccounts;
@ -1480,7 +1491,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
setHasStableIds(true);
mActivity = activity;
mInflater = activity.getLayoutInflater();
mSelection = new LongSparseArray<>();
mSelection = new HashMap<>();
mNameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
}
@ -1494,25 +1505,25 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
}
@NonNull
public long[] getSelectedAccountIds() {
if (mAccounts == null) return new long[0];
final long[] temp = new long[mAccounts.length];
public AccountKey[] getSelectedAccountKeys() {
if (mAccounts == null) return new AccountKey[0];
final AccountKey[] temp = new AccountKey[mAccounts.length];
int selectedCount = 0;
for (ParcelableAccount account : mAccounts) {
if (mSelection.get(account.account_id, false)) {
temp[selectedCount++] = account.account_id;
if (Boolean.TRUE.equals(mSelection.get(new AccountKey(account.account_id, account.account_host)))) {
temp[selectedCount++] = new AccountKey(account.account_id, account.account_host);
}
}
final long[] result = new long[selectedCount];
final AccountKey[] result = new AccountKey[selectedCount];
System.arraycopy(temp, 0, result, 0, result.length);
return result;
}
public void setSelectedAccountIds(long... accountIds) {
public void setSelectedAccountIds(AccountKey... accountKeys) {
mSelection.clear();
if (accountIds != null) {
for (long accountId : accountIds) {
mSelection.put(accountId, true);
if (accountKeys != null) {
for (AccountKey accountKey : accountKeys) {
mSelection.put(accountKey, true);
}
}
notifyDataSetChanged();
@ -1524,7 +1535,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
final ParcelableCredentials[] temp = new ParcelableCredentials[mAccounts.length];
int selectedCount = 0;
for (ParcelableCredentials account : mAccounts) {
if (mSelection.get(account.account_id, false)) {
if (Boolean.TRUE.equals(mSelection.get(new AccountKey(account.account_id, account.account_host)))) {
temp[selectedCount++] = account;
}
}
@ -1534,7 +1545,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
}
public boolean isSelectionEmpty() {
return getSelectedAccountIds().length == 0;
return getSelectedAccountKeys().length == 0;
}
@Override
@ -1546,7 +1557,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
@Override
public void onBindViewHolder(AccountIconViewHolder holder, int position) {
final ParcelableAccount account = mAccounts[position];
final boolean isSelected = mSelection.get(account.account_id, false);
final boolean isSelected = Boolean.TRUE.equals(mSelection.get(new AccountKey(account.account_id, account.account_host)));
holder.showAccount(this, account, isSelected);
}
@ -1562,8 +1573,9 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
private void toggleSelection(int position) {
if (mAccounts == null) return;
final long accountId = mAccounts[position].account_id;
mSelection.put(accountId, !mSelection.get(accountId, false));
final ParcelableCredentials account = mAccounts[position];
final AccountKey accountKey = new AccountKey(account.account_id, account.account_host);
mSelection.put(accountKey, !Boolean.TRUE.equals(mSelection.get(accountKey)));
mActivity.notifyAccountSelectionChanged();
notifyDataSetChanged();
}

View File

@ -694,7 +694,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
final String tabType = uri != null ? Utils.matchTabType(uri) : null;
int initialTab = -1;
if (tabType != null) {
final long accountId = NumberUtils.toLong(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_ID), -1);
final AccountKey accountId = AccountKey.valueOf(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_KEY));
for (int i = 0, j = mPagerAdapter.getCount(); i < j; i++) {
final SupportTabSpec tab = mPagerAdapter.getTab(i);
if (tabType.equals(CustomTabUtils.getTabTypeAlias(tab.type))) {

View File

@ -297,7 +297,8 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
try {
final ResponseList<UserList> lists = twitter.getUserLists(mScreenName, true);
final List<ParcelableUserList> data = new ArrayList<>();
boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity, mAccountKey.getId()));
boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity,
mAccountKey));
for (final UserList item : lists) {
final User user = item.getUser();
if (user != null && mScreenName.equalsIgnoreCase(user.getScreenName())) {

View File

@ -241,11 +241,14 @@ public class MessageEntriesAdapter extends LoadMoreSupportAdapter<ViewHolder> im
public static class DirectMessageEntry {
public final long account_id, conversation_id;
public final long account_id;
public final String account_host;
public final long conversation_id;
public final String screen_name, name;
DirectMessageEntry(Cursor cursor) {
account_id = cursor.getLong(ConversationEntries.IDX_ACCOUNT_ID);
account_host = cursor.getString(ConversationEntries.IDX_ACCOUNT_HOST);
conversation_id = cursor.getLong(ConversationEntries.IDX_CONVERSATION_ID);
screen_name = cursor.getString(ConversationEntries.IDX_SCREEN_NAME);
name = cursor.getString(ConversationEntries.IDX_NAME);

View File

@ -58,7 +58,7 @@ import org.mariotaku.twidere.util.dagger.ApplicationModule;
import org.mariotaku.twidere.util.dagger.DependencyHolder;
import org.mariotaku.twidere.util.net.TwidereDns;
import static org.mariotaku.twidere.util.Utils.initAccountColor;
import static org.mariotaku.twidere.util.DataStoreUtils.initAccountColor;
public class TwidereApplication extends Application implements Constants,
OnSharedPreferenceChangeListener {

View File

@ -29,6 +29,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
@ -44,7 +45,8 @@ public class CreateUserMuteDialogFragment extends BaseSupportDialogFragment impl
final ParcelableUser user = getUser();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (user == null || twitter == null) return;
twitter.createMuteAsync(user.account_id, user.id);
twitter.createMuteAsync(new AccountKey(user.account_id, user.account_host),
user.id);
break;
default:
break;

View File

@ -31,6 +31,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
@ -49,7 +50,8 @@ public class DeleteUserListMembersDialogFragment extends BaseSupportDialogFragme
final ParcelableUserList userList = getUserList();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (users == null || userList == null || twitter == null) return;
twitter.deleteUserListMembersAsync(userList.account_id, userList.id, users);
twitter.deleteUserListMembersAsync(new AccountKey(userList.account_id,
userList.account_host), userList.id, users);
break;
default:
break;

View File

@ -29,6 +29,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
@ -45,7 +46,8 @@ public class DestroyFriendshipDialogFragment extends BaseSupportDialogFragment i
final ParcelableUser user = getUser();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (user == null || twitter == null) return;
twitter.destroyFriendshipAsync(user.account_id, user.id);
twitter.destroyFriendshipAsync(new AccountKey(user.account_id, user.account_host),
user.id);
break;
default:
break;

View File

@ -28,6 +28,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
@ -40,11 +41,11 @@ public class DestroySavedSearchDialogFragment extends BaseSupportDialogFragment
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
final long accountId = getAccountId();
final AccountKey accountKey = getAccountKey();
final long searchId = getSearchId();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (searchId <= 0 || twitter == null) return;
twitter.destroySavedSearchAsync(accountId, searchId);
twitter.destroySavedSearchAsync(accountKey, searchId);
break;
default:
break;
@ -66,10 +67,9 @@ public class DestroySavedSearchDialogFragment extends BaseSupportDialogFragment
return builder.create();
}
private long getAccountId() {
private AccountKey getAccountKey() {
final Bundle args = getArguments();
if (!args.containsKey(EXTRA_ACCOUNT_ID)) return -1;
return args.getLong(EXTRA_ACCOUNT_ID);
return args.getParcelable(EXTRA_ACCOUNT_KEY);
}
private long getSearchId() {

View File

@ -28,6 +28,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
@ -40,10 +41,11 @@ public class DestroyUserListDialogFragment extends BaseSupportDialogFragment imp
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
final ParcelableUserList user_list = getUserList();
final ParcelableUserList userList = getUserList();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (user_list == null || twitter == null) return;
twitter.destroyUserListAsync(user_list.account_id, user_list.id);
if (userList == null || twitter == null) return;
twitter.destroyUserListAsync(new AccountKey(userList.account_id,
userList.account_host), userList.id);
break;
default:
break;

View File

@ -28,6 +28,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
@ -41,10 +42,11 @@ public class DestroyUserListSubscriptionDialogFragment extends BaseSupportDialog
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
final ParcelableUserList user_list = getUserList();
final ParcelableUserList userList = getUserList();
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (user_list == null || twitter == null) return;
twitter.destroyUserListSubscriptionAsync(user_list.account_id, user_list.id);
if (userList == null || twitter == null) return;
twitter.destroyUserListSubscriptionAsync(new AccountKey(userList.account_id,
userList.account_host), userList.id);
break;
default:
break;

View File

@ -195,7 +195,8 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
@Override
public void onEntryClick(int position, DirectMessageEntry entry) {
Utils.openMessageConversation(getActivity(), entry.account_id, entry.conversation_id);
Utils.openMessageConversation(getActivity(), new AccountKey(entry.account_id,
entry.account_host), entry.conversation_id);
}
@Override
@ -324,7 +325,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
if (accountIds.length == 1) {
Utils.openMessageConversation(getActivity(), accountIds[0], -1);
} else {
Utils.openMessageConversation(getActivity(), -1, -1);
Utils.openMessageConversation(getActivity(), null, -1);
}
}

View File

@ -30,7 +30,9 @@ import org.mariotaku.twidere.adapter.ListParcelableStatusesAdapter;
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.BaseRefreshTaskParam;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.model.message.FavoriteTaskEvent;
import org.mariotaku.twidere.model.message.StatusDestroyedEvent;
import org.mariotaku.twidere.model.message.StatusListChangedEvent;
@ -66,12 +68,14 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
}
@Override
public boolean getStatuses(long[] accountIds, final long[] maxIds, final long[] sinceIds) {
public boolean getStatuses(RefreshTaskParam param) {
final Bundle args = new Bundle(getArguments());
long[] maxIds = param.getMaxIds();
if (maxIds != null) {
args.putLong(EXTRA_MAX_ID, maxIds[0]);
args.putBoolean(EXTRA_MAKE_GAP, false);
}
long[] sinceIds = param.getSinceIds();
if (sinceIds != null) {
args.putLong(EXTRA_SINCE_ID, sinceIds[0]);
}
@ -130,8 +134,10 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
super.onLoadMoreContents(position);
if (position == 0) return;
final IStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
final long[] maxIds = new long[]{adapter.getStatusId(adapter.getStatusCount() - 1)};
getStatuses(null, maxIds, null);
final ParcelableStatus status = adapter.getStatus(adapter.getItemCount() - 1);
AccountKey[] accountKeys = {new AccountKey(status.account_id, status.account_host)};
final long[] maxIds = {status.id};
getStatuses(new BaseRefreshTaskParam(accountKeys, maxIds, null));
}
public final void replaceStatus(final ParcelableStatus status) {
@ -152,9 +158,9 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
final AccountKey[] accountIds = getAccountKeys();
if (adapter.getStatusCount() > 0) {
final long[] sinceIds = new long[]{adapter.getStatus(0).id};
getStatuses(accountIds, null, sinceIds);
getStatuses(new BaseRefreshTaskParam(accountIds, null, sinceIds));
} else {
getStatuses(accountIds, null, null);
getStatuses(new BaseRefreshTaskParam(accountIds, null, null));
}
return true;
}

View File

@ -27,6 +27,7 @@ import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.IntentUtils;
@ -50,7 +51,7 @@ public class SensitiveContentWarningDialogFragment extends BaseSupportDialogFrag
final boolean newDocument = args.getBoolean(EXTRA_NEW_DOCUMENT);
final ParcelableMedia[] media = Utils.newParcelableArray(args.getParcelableArray(EXTRA_MEDIA),
ParcelableMedia.CREATOR);
IntentUtils.openMediaDirectly(context, accountId, status, null, current, media,
IntentUtils.openMediaDirectly(context, accountKey, status, null, current, media,
option, newDocument);
break;
}

View File

@ -25,6 +25,7 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
import org.mariotaku.twidere.loader.support.StatusFavoritersLoader;
import org.mariotaku.twidere.model.AccountKey;
public class StatusFavoritersListFragment extends CursorSupportUsersListFragment {
@ -32,7 +33,7 @@ public class StatusFavoritersListFragment extends CursorSupportUsersListFragment
public IDsUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long statusId = args.getLong(EXTRA_STATUS_ID, -1);
final StatusFavoritersLoader loader = new StatusFavoritersLoader(context, accountId,
final StatusFavoritersLoader loader = new StatusFavoritersLoader(context, accountKey,
statusId, getData(), false);
loader.setCursor(getNextCursor());
return loader;

View File

@ -105,6 +105,7 @@ import org.mariotaku.twidere.fragment.support.AbsStatusesFragment.DefaultOnLiked
import org.mariotaku.twidere.loader.support.ConversationLoader;
import org.mariotaku.twidere.loader.support.ParcelableStatusLoader;
import org.mariotaku.twidere.menu.support.FavoriteItemProvider;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.model.ParcelableActivityCursorIndices;
import org.mariotaku.twidere.model.ParcelableActivityValuesCreator;
@ -288,9 +289,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override
public Loader<StatusActivity> onCreateLoader(int id, Bundle args) {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final String accountHost = args.getString(EXTRA_ACCOUNT_HOST);
final long statusId = args.getLong(EXTRA_STATUS_ID, -1);
return new StatusActivitySummaryLoader(getActivity(), accountId, accountHost, statusId);
return new StatusActivitySummaryLoader(getActivity(), accountKey, statusId);
}
@Override
@ -406,7 +406,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
MediaEvent event = MediaEvent.create(getActivity(), status, media, TimelineType.DETAILS,
mStatusAdapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_id, event);
HotMobiLogger.getInstance(getActivity()).log(new AccountKey(status.account_id,
status.account_host), event);
}
@Override
@ -430,7 +431,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (twitter == null) return;
if (status.is_favorite) {
twitter.destroyFavoriteAsync(status.account_id, status.id);
twitter.destroyFavoriteAsync(new AccountKey(status.account_id,
status.account_host), status.id);
} else {
holder.playLikeAnimation(new DefaultOnLikedListener(twitter, status));
}
@ -472,7 +474,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
// BEGIN HotMobi
MediaEvent event = MediaEvent.create(getActivity(), status, media, TimelineType.OTHER,
mStatusAdapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_id, event);
HotMobiLogger.getInstance(getActivity()).log(new AccountKey(status.account_id,
status.account_host), event);
// END HotMobi
}
@ -505,9 +508,11 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
case ACTION_STATUS_FAVORITE: {
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (status.is_favorite) {
twitter.destroyFavoriteAsync(status.account_id, status.id);
twitter.destroyFavoriteAsync(new AccountKey(status.account_id,
status.account_host), status.id);
} else {
twitter.createFavoriteAsync(status.account_id, status.id);
twitter.createFavoriteAsync(new AccountKey(status.account_id,
status.account_host), status.id);
}
return true;
}
@ -800,7 +805,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public void notifyFavoriteTask(FavoriteTaskEvent event) {
if (!event.isSucceeded()) return;
final StatusAdapter adapter = getAdapter();
final ParcelableStatus status = adapter.findStatusById(event.getAccountKey(), event.getStatusId());
final ParcelableStatus status = adapter.findStatusById(event.getAccountKey().getId(), event.getStatusId());
if (status != null) {
switch (event.getAction()) {
case FavoriteTaskEvent.Action.CREATE: {
@ -864,8 +869,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override
protected SingleResponse<TranslationResult> doInBackground(ParcelableStatus... params) {
final ParcelableStatus status = params[0];
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, status.account_id,
accountHost, true);
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context,
new AccountKey(status.account_id, status.account_host), true);
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
if (twitter == null) return SingleResponse.getInstance();
@ -993,7 +998,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
retweetedByView.setVisibility(View.GONE);
}
profileContainer.drawEnd(DataStoreUtils.getAccountColor(context, status.account_id));
profileContainer.drawEnd(DataStoreUtils.getAccountColor(context,
new AccountKey(status.account_id, status.account_host)));
final int layoutPosition = getLayoutPosition();
final boolean skipLinksInText = status.extras != null && status.extras.support_entities;
@ -2416,22 +2422,20 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
public static class StatusActivitySummaryLoader extends AsyncTaskLoader<StatusActivity> {
private final long mAccountId;
private final String mAccountHost;
private final AccountKey mAccountKey;
private final long mStatusId;
public StatusActivitySummaryLoader(Context context, long accountId, String accountHost,
long statusId) {
public StatusActivitySummaryLoader(Context context, AccountKey accountKey, long statusId) {
super(context);
mAccountId = accountId;
mAccountHost = accountHost;
mAccountKey = accountKey;
mStatusId = statusId;
}
@Override
public StatusActivity loadInBackground() {
final Context context = getContext();
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, mAccountId, accountHost, false);
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, mAccountKey, false);
if (twitter == null) return null;
final Paging paging = new Paging();
paging.setCount(10);
final StatusActivity activitySummary = new StatusActivity(mStatusId);
@ -2440,7 +2444,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
for (Status status : twitter.getRetweets(mStatusId, paging)) {
final User user = status.getUser();
if (!DataStoreUtils.isFilteringUser(context, user.getId())) {
retweeters.add(ParcelableUserUtils.fromUser(user, mAccountId));
retweeters.add(ParcelableUserUtils.fromUser(user, mAccountKey));
}
}
activitySummary.setRetweeters(retweeters);
@ -2465,8 +2469,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
Expression.equals(Activities.STATUS_RETWEET_ID, mStatusId)
);
final ParcelableStatus pStatus = ParcelableStatusUtils.fromStatus(status, mAccountId,
mAccountHost, false);
final ParcelableStatus pStatus = ParcelableStatusUtils.fromStatus(status,
mAccountKey, false);
cr.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(pStatus));
final Cursor activityCursor = cr.query(Activities.AboutMe.CONTENT_URI,

View File

@ -25,6 +25,7 @@ import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserFavoritesLoader;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
@ -47,7 +48,7 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
return new UserFavoritesLoader(context, accountId, userId, screenName, sinceId, maxId,
return new UserFavoritesLoader(context, accountKey, userId, screenName, sinceId, maxId,
getAdapterData(), getSavedStatusesFileArgs(), tabPosition, fromUser);
}
@ -58,7 +59,7 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
return new String[]{AUTHORITY_USER_FAVORITES, "account" + accountId, "user" + userId, "name" + screenName};
return new String[]{AUTHORITY_USER_FAVORITES, "account" + accountKey, "user" + userId, "name" + screenName};
}

View File

@ -28,6 +28,7 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
import org.mariotaku.twidere.loader.support.UserFollowersLoader;
import org.mariotaku.twidere.model.AccountKey;
import static org.mariotaku.twidere.util.DataStoreUtils.getAccountScreenName;
@ -59,7 +60,7 @@ public class UserFollowersFragment extends CursorSupportUsersListFragment {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final UserFollowersLoader loader = new UserFollowersLoader(context, accountId, userId,
final UserFollowersLoader loader = new UserFollowersLoader(context, accountKey, userId,
screenName, getData(), fromUser);
loader.setCursor(getNextCursor());
return loader;

View File

@ -237,7 +237,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mFollowingYouIndicator.setVisibility(View.GONE);
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
return new UserRelationshipLoader(getActivity(), accountId, userId);
return new UserRelationshipLoader(getActivity(), accountKey, userId);
}
@Override
@ -273,7 +273,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
setProgressBarIndeterminateVisibility(true);
final ParcelableUser user = mUser;
return new ParcelableUserLoader(getActivity(), accountId, userId, screenName, getArguments(),
return new ParcelableUserLoader(getActivity(), accountKey, userId, screenName, getArguments(),
omitIntentExtra, user == null || !user.is_cache && userId != user.id);
}
@ -529,7 +529,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
if (user.account_color != 0) {
mProfileNameContainer.drawEnd(user.account_color);
} else {
mProfileNameContainer.drawEnd(DataStoreUtils.getAccountColor(activity, user.account_id));
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
mProfileNameContainer.drawEnd(DataStoreUtils.getAccountColor(activity, accountKey));
}
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)));
@ -646,7 +647,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Subscribe
public void notifyFriendshipUpdated(FriendshipUpdatedEvent event) {
final ParcelableUser user = getUser();
if (user == null || event.mAccountKey != user.account_id || event.userId != user.id) return;
if (user == null || !event.isAccount(user.account_id, user.account_host) ||
!event.isUser(user.id)) return;
getFriendship();
}
@ -690,7 +692,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final AsyncTwitterWrapper twitter = mTwitterWrapper;
final ParcelableUserList list = data.getParcelableExtra(EXTRA_USER_LIST);
if (list == null || twitter == null) return;
twitter.addUserListMembersAsync(user.account_id, list.id, user);
twitter.addUserListMembersAsync(new AccountKey(user.account_id, user.account_host),
list.id, user);
}
break;
}
@ -982,7 +985,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
case R.id.block: {
if (userRelationship == null) return true;
if (userRelationship.relationship.isSourceBlockingTarget()) {
twitter.destroyBlockAsync(user.account_id, user.id);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
twitter.destroyBlockAsync(accountKey, user.id);
} else {
CreateUserBlockDialogFragment.show(getFragmentManager(), user);
}
@ -1008,7 +1012,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
case R.id.mute_user: {
if (userRelationship == null) return true;
if (userRelationship.relationship.isSourceMutingTarget()) {
twitter.destroyMuteAsync(user.account_id, user.id);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
twitter.destroyMuteAsync(accountKey, user.id);
} else {
CreateUserMuteDialogFragment.show(getFragmentManager(), user);
}
@ -1029,7 +1034,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(user.account_id));
builder.appendQueryParameter(QUERY_PARAM_USER_ID, String.valueOf(user.id));
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.putExtra(EXTRA_ACCOUNT, DataStoreUtils.getCredentials(getActivity(), user.account_id));
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
intent.putExtra(EXTRA_ACCOUNT, DataStoreUtils.getCredentials(getActivity(), accountKey));
intent.putExtra(EXTRA_USER, user);
startActivity(intent);
break;
@ -1055,7 +1061,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER_LIST);
intent.setClass(getActivity(), UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, user.account_id);
intent.putExtra(EXTRA_SCREEN_NAME, DataStoreUtils.getAccountScreenName(getActivity(), user.account_id));
intent.putExtra(EXTRA_SCREEN_NAME, DataStoreUtils.getAccountScreenName(getActivity(),
new AccountKey(user.account_id, user.account_host)));
startActivityForResult(intent, REQUEST_ADD_TO_LIST);
break;
}
@ -1069,13 +1076,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
case R.id.follow: {
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);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
final boolean isCreatingFriendship = twitter.isCreatingFriendship(accountKey, user.id);
final boolean isDestroyingFriendship = twitter.isDestroyingFriendship(accountKey, user.id);
if (!isCreatingFriendship && !isDestroyingFriendship) {
if (isFollowing) {
DestroyFriendshipDialogFragment.show(getFragmentManager(), user);
} else {
twitter.createFriendshipAsync(user.account_id, user.id);
twitter.createFriendshipAsync(accountKey, user.id);
}
}
return true;
@ -1084,7 +1092,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final boolean newState = !item.isChecked();
final FriendshipUpdate update = new FriendshipUpdate();
update.retweets(newState);
twitter.updateFriendship(user.account_id, user.id, update);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
twitter.updateFriendship(accountKey, user.id, update);
item.setChecked(newState);
return true;
}
@ -1294,11 +1303,13 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (userRelationship == null || twitter == null) return;
if (userRelationship.relationship.isSourceBlockingTarget()) {
twitter.destroyBlockAsync(user.account_id, user.id);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
twitter.destroyBlockAsync(accountKey, user.id);
} else if (userRelationship.relationship.isSourceFollowingTarget()) {
DestroyFriendshipDialogFragment.show(getFragmentManager(), user);
} else {
twitter.createFriendshipAsync(user.account_id, user.id);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
twitter.createFriendshipAsync(accountKey, user.id);
}
break;
}
@ -1358,7 +1369,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
break;
}
case TwidereLinkify.LINK_TYPE_HASHTAG: {
Utils.openTweetSearch(getActivity(), user.account_id, "#" + link);
Utils.openTweetSearch(getActivity(), new AccountKey(user.account_id, user.account_host),
"#" + link);
break;
}
case TwidereLinkify.LINK_TYPE_ENTITY_URL: {
@ -1557,10 +1569,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
final LoaderManager lm = getLoaderManager();
final boolean loadingRelationship = lm.getLoader(LOADER_ID_FRIENDSHIP) != null;
final boolean creatingFriendship = twitter.isCreatingFriendship(user.account_id, user.id);
final boolean destroyingFriendship = twitter.isDestroyingFriendship(user.account_id, user.id);
final boolean creatingBlock = twitter.isCreatingFriendship(user.account_id, user.id);
final boolean destroyingBlock = twitter.isDestroyingFriendship(user.account_id, user.id);
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
final boolean creatingFriendship = twitter.isCreatingFriendship(accountKey, user.id);
final boolean destroyingFriendship = twitter.isDestroyingFriendship(accountKey, user.id);
final boolean creatingBlock = twitter.isCreatingFriendship(accountKey, user.id);
final boolean destroyingBlock = twitter.isDestroyingFriendship(accountKey, user.id);
if (loadingRelationship || creatingFriendship || destroyingFriendship || creatingBlock || destroyingBlock) {
mFollowButton.setVisibility(View.GONE);
mFollowProgress.setVisibility(View.VISIBLE);
@ -1575,13 +1588,12 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
private void updateRefreshState() {
final ParcelableUser user = getUser();
if (user == null) return;
final AsyncTwitterWrapper twitter = mTwitterWrapper;
final boolean is_creating_friendship = twitter != null
&& twitter.isCreatingFriendship(user.account_id, user.id);
final boolean is_destroying_friendship = twitter != null
&& twitter.isDestroyingFriendship(user.account_id, user.id);
setProgressBarIndeterminateVisibility(is_creating_friendship || is_destroying_friendship);
if (user == null || twitter == null) return;
final AccountKey accountKey = new AccountKey(user.account_id, user.account_host);
final boolean isCreatingFriendship = twitter.isCreatingFriendship(accountKey, user.id);
final boolean destroyingFriendship = twitter.isDestroyingFriendship(accountKey, user.id);
setProgressBarIndeterminateVisibility(isCreatingFriendship || destroyingFriendship);
invalidateOptionsMenu();
}

View File

@ -25,6 +25,7 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
import org.mariotaku.twidere.loader.support.UserFriendsLoader;
import org.mariotaku.twidere.model.AccountKey;
public class UserFriendsFragment extends CursorSupportUsersListFragment {
@ -34,7 +35,7 @@ public class UserFriendsFragment extends CursorSupportUsersListFragment {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final UserFriendsLoader loader = new UserFriendsLoader(context, accountId, userId,
final UserFriendsLoader loader = new UserFriendsLoader(context, accountKey, userId,
screenName, getData(), fromUser);
loader.setCursor(getNextCursor());
return loader;

View File

@ -24,6 +24,7 @@ import android.os.Bundle;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserListMembershipsLoader;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
@ -37,7 +38,7 @@ public class UserListMembershipsFragment extends ParcelableUserListsFragment {
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final long cursor = args.getLong(EXTRA_NEXT_CURSOR, -1);
return new UserListMembershipsLoader(getActivity(), accountId, userId, screenName, cursor, getData());
return new UserListMembershipsLoader(getActivity(), accountKey, userId, screenName, cursor, getData());
}
}

View File

@ -25,19 +25,21 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
import org.mariotaku.twidere.loader.support.UserListSubscribersLoader;
import org.mariotaku.twidere.model.AccountKey;
public class UserListSubscribersFragment extends CursorSupportUsersListFragment {
@Override
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
if (args == null) return null;
final long listId = args.getLong(EXTRA_LIST_ID, -1);
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final String listName = args.getString(EXTRA_LIST_NAME);
return new UserListSubscribersLoader(context, accountId, listId, userId, screenName, listName,
getNextCursor(), getData(), fromUser);
}
@Override
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
final long listId = args.getLong(EXTRA_LIST_ID, -1);
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final String listName = args.getString(EXTRA_LIST_NAME);
final UserListSubscribersLoader loader = new UserListSubscribersLoader(context, accountKey,
listId, userId, screenName, listName, getData(), fromUser);
loader.setCursor(getNextCursor());
return loader;
}
}

View File

@ -25,6 +25,7 @@ import android.support.annotation.NonNull;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
@ -57,7 +58,7 @@ public class UserListTimelineFragment extends ParcelableStatusesFragment {
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final String listName = args.getString(EXTRA_LIST_NAME);
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
return new UserListTimelineLoader(getActivity(), accountId, listId, userId, screenName,
return new UserListTimelineLoader(getActivity(), accountKey, listId, userId, screenName,
listName, sinceId, maxId, getAdapterData(), getSavedStatusesFileArgs(), tabPosition, fromUser);
}
@ -70,7 +71,7 @@ public class UserListTimelineFragment extends ParcelableStatusesFragment {
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final String listName = args.getString(EXTRA_LIST_NAME);
return new String[]{AUTHORITY_USER_LIST_TIMELINE, "account" + accountId, "list_id" + listId,
return new String[]{AUTHORITY_USER_LIST_TIMELINE, "account" + accountKey, "list_id" + listId,
"list_name" + listName, "user_id" + userId, "screen_name" + screenName};
}

View File

@ -32,6 +32,7 @@ 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.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.MenuUtils;
import org.mariotaku.twidere.util.Utils;
@ -47,7 +48,7 @@ public class UserListsFragment extends ParcelableUserListsFragment {
final AccountKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
return new UserListsLoader(getActivity(), accountId, userId, screenName, true, getData());
return new UserListsLoader(getActivity(), accountKey, userId, screenName, true, getData());
}
@Override

View File

@ -19,6 +19,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
import org.mariotaku.twidere.loader.support.MediaTimelineLoader;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.Utils;
@ -104,7 +105,7 @@ public class UserMediaTimelineFragment extends AbsContentRecyclerViewFragment<St
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
return new MediaTimelineLoader(context, accountId, userId, screenName, sinceId, maxId,
return new MediaTimelineLoader(context, accountKey, userId, screenName, sinceId, maxId,
getAdapter().getData(), null, tabPosition, fromUser);
}

View File

@ -51,6 +51,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.CardDataMap;
import org.mariotaku.twidere.api.twitter.model.CardEntity;
import org.mariotaku.twidere.fragment.support.BaseSupportFragment;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableCardEntity;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils;
@ -175,11 +176,13 @@ public class CardPollFragment extends BaseSupportFragment implements
@Override
public ParcelableCardEntity doLongOperation(CardDataMap cardDataMap) {
final TwitterCaps caps = TwitterAPIFactory.getTwitterInstance(getContext(),
card.account_id, accountHost, true, true, TwitterCaps.class);
new AccountKey(card.account_id, card.account_host),
true, true, TwitterCaps.class);
if (caps == null) return null;
try {
final CardEntity cardEntity = caps.sendPassThrough(cardDataMap).getCard();
return ParcelableCardEntityUtils.fromCardEntity(cardEntity, card.account_id);
return ParcelableCardEntityUtils.fromCardEntity(cardEntity,
new AccountKey(card.account_id, card.account_host));
} catch (TwitterException e) {
Log.w(LOGTAG, e);
}
@ -267,7 +270,8 @@ public class CardPollFragment extends BaseSupportFragment implements
@Override
public Loader<ParcelableCardEntity> onCreateLoader(int id, Bundle args) {
final ParcelableCardEntity card = getCard();
return new ParcelableCardEntityLoader(getContext(), card.account_id, card.url, card.name);
return new ParcelableCardEntityLoader(getContext(), new AccountKey(card.account_id,
card.account_host), card.url, card.name);
}
@Override
@ -325,21 +329,22 @@ public class CardPollFragment extends BaseSupportFragment implements
}
public static class ParcelableCardEntityLoader extends AsyncTaskLoader<ParcelableCardEntity> {
private final long mAccountId;
private final AccountKey mAccountKey;
private final String mCardUri;
private final String mCardName;
public ParcelableCardEntityLoader(Context context, long accountId, String cardUri, String cardName) {
public ParcelableCardEntityLoader(Context context, AccountKey accountKey,
String cardUri, String cardName) {
super(context);
mAccountId = accountId;
mAccountKey = accountKey;
mCardUri = cardUri;
mCardName = cardName;
}
@Override
public ParcelableCardEntity loadInBackground() {
final TwitterCaps caps = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId,
accountHost, true, true, TwitterCaps.class);
final TwitterCaps caps = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountKey,
true, true, TwitterCaps.class);
if (caps == null) return null;
try {
final CardDataMap params = new CardDataMap();
@ -350,7 +355,7 @@ public class CardPollFragment extends BaseSupportFragment implements
if (card == null || card.getName() == null) {
return null;
}
final ParcelableCardEntity parcelableCard = ParcelableCardEntityUtils.fromCardEntity(card, mAccountId);
final ParcelableCardEntity parcelableCard = ParcelableCardEntityUtils.fromCardEntity(card, mAccountKey);
return parcelableCard;
} catch (TwitterException e) {

View File

@ -30,7 +30,9 @@ import org.mariotaku.twidere.api.twitter.model.CursorSupport;
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
import org.mariotaku.twidere.api.twitter.model.UserList;
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.util.ParcelableUserListUtils;
import org.mariotaku.twidere.util.TwitterAPIFactory;
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList;
@ -42,19 +44,19 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<Parcelabl
implements TwidereConstants, ICursorSupportLoader {
protected final NoDuplicatesArrayList<ParcelableUserList> mData = new NoDuplicatesArrayList<>();
protected final long mAccountId;
protected final AccountKey mAccountId;
private final long mCursor;
private long mNextCursor, mPrevCursor;
public BaseUserListsLoader(final Context context, final long accountId, final long cursor,
public BaseUserListsLoader(final Context context, final AccountKey accountKey, final long cursor,
final List<ParcelableUserList> data) {
super(context);
if (data != null) {
mData.addAll(data);
}
mCursor = cursor;
mAccountId = accountId;
mAccountId = accountKey;
}
@Override
@ -76,7 +78,7 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<Parcelabl
@Override
public List<ParcelableUserList> loadInBackground() {
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, accountHost, true);
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true);
List<UserList> listLoaded = null;
try {
listLoaded = getUserLists(twitter);
@ -91,12 +93,12 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<Parcelabl
final int dataSize = mData.size();
for (int i = 0; i < listSize; i++) {
final UserList list = listLoaded.get(i);
mData.add(new ParcelableUserList(list, mAccountId, dataSize + i, isFollowing(list)));
mData.add(ParcelableUserListUtils.from(list, mAccountId, dataSize + i, isFollowing(list)));
}
} else {
for (int i = 0; i < listSize; i++) {
final UserList list = listLoaded.get(i);
mData.add(new ParcelableUserList(listLoaded.get(i), mAccountId, i, isFollowing(list)));
mData.add(ParcelableUserListUtils.from(listLoaded.get(i), mAccountId, i, isFollowing(list)));
}
}
}

View File

@ -26,15 +26,16 @@ import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.IDs;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import java.util.List;
public class IncomingFriendshipsLoader extends IDsUsersLoader {
public IncomingFriendshipsLoader(final Context context, final long accountId,
public IncomingFriendshipsLoader(final Context context, final AccountKey accountKey,
final List<ParcelableUser> data, boolean fromUser) {
super(context, accountId, data, fromUser);
super(context, accountKey, data, fromUser);
}
@NonNull

View File

@ -31,6 +31,7 @@ import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.SearchQuery;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.DataStoreUtils;
@ -49,10 +50,11 @@ public class MediaTimelineLoader extends TwitterAPIStatusesLoader {
private User mUser;
public MediaTimelineLoader(final Context context, final long accountId, final long userId, final String screenName,
final long sinceId, final long maxId, final List<ParcelableStatus> data, final String[] savedStatusesArgs,
public MediaTimelineLoader(final Context context, final AccountKey accountKey, final long userId,
final String screenName, final long sinceId, final long maxId,
final List<ParcelableStatus> data, final String[] savedStatusesArgs,
final int tabPosition, final boolean fromUser) {
super(context, accountId, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
super(context, accountKey, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
mUserId = userId;
mUserScreenName = screenName;
}
@ -107,7 +109,7 @@ public class MediaTimelineLoader extends TwitterAPIStatusesLoader {
private boolean isMyTimeline() {
if (mUserId > 0) {
return getAccountKey() == mUserId;
return getAccountKey().getId() == mUserId;
} else {
final String accountScreenName = DataStoreUtils.getAccountScreenName(getContext(), getAccountKey());
return accountScreenName != null && accountScreenName.equalsIgnoreCase(mUserScreenName);

View File

@ -26,6 +26,7 @@ import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.IDs;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import java.util.List;
@ -34,9 +35,9 @@ public class StatusFavoritersLoader extends IDsUsersLoader {
private final long mStatusId;
public StatusFavoritersLoader(final Context context, final long accountId, final long statusId,
public StatusFavoritersLoader(final Context context, final AccountKey accountKey, final long statusId,
final List<ParcelableUser> data, boolean fromUser) {
super(context, accountId, data, fromUser);
super(context, accountKey, data, fromUser);
mStatusId = statusId;
}

View File

@ -29,6 +29,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
@ -37,14 +38,14 @@ public class UserFavoritesLoader extends TwitterAPIStatusesLoader {
private final long mUserId;
private final String mUserScreenName;
private int mTotalItemsCount;
public UserFavoritesLoader(final Context context, final long accountId, final long userId,
final String screen_name, final long sinceId, final long maxId, final List<ParcelableStatus> data,
final String[] savedStatusesArgs, final int tabPosition, boolean fromUser) {
super(context, accountId, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
public UserFavoritesLoader(final Context context, final AccountKey accountKey, final long userId,
final String screenName, final long sinceId, final long maxId,
final List<ParcelableStatus> data, final String[] savedStatusesArgs,
final int tabPosition, boolean fromUser) {
super(context, accountKey, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
mUserId = userId;
mUserScreenName = screen_name;
mUserScreenName = screenName;
}
@NonNull
@ -56,10 +57,6 @@ public class UserFavoritesLoader extends TwitterAPIStatusesLoader {
throw new IllegalArgumentException();
}
public int getTotalItemsCount() {
return mTotalItemsCount;
}
@WorkerThread
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {

View File

@ -27,6 +27,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.DataStoreUtils;
@ -38,7 +39,7 @@ public class UserFollowersLoader extends CursorSupportUsersLoader {
private final long mUserId;
private final String mScreenName;
public UserFollowersLoader(final Context context, final long accountId, final long userId,
public UserFollowersLoader(final Context context, final AccountKey accountId, final long userId,
final String screenName, final List<ParcelableUser> data,
final boolean fromUser) {
super(context, accountId, data, fromUser);

View File

@ -27,6 +27,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.DataStoreUtils;
@ -38,10 +39,10 @@ public class UserFriendsLoader extends CursorSupportUsersLoader {
private final long mUserId;
private final String mScreenName;
public UserFriendsLoader(final Context context, final long accountId, final long userId,
public UserFriendsLoader(final Context context, final AccountKey accountKey, final long userId,
final String screenName, final List<ParcelableUser> userList,
boolean fromUser) {
super(context, accountId, userList, fromUser);
super(context, accountKey, userList, fromUser);
mUserId = userId;
mScreenName = screenName;
}

View File

@ -21,26 +21,27 @@ package org.mariotaku.twidere.loader.support;
import android.content.Context;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.UserList;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.UserList;
public class UserListMembershipsLoader extends BaseUserListsLoader {
private final long mUserId;
private final String mScreenName;
public UserListMembershipsLoader(final Context context, final long account_id, final long user_id,
final String screen_name, final long cursor, final List<ParcelableUserList> data) {
super(context, account_id, cursor, data);
mUserId = user_id;
mScreenName = screen_name;
public UserListMembershipsLoader(final Context context, final AccountKey accountKey,
final long userId, final String screenName,
final long cursor, final List<ParcelableUserList> data) {
super(context, accountKey, cursor, data);
mUserId = userId;
mScreenName = screenName;
}
@Override

View File

@ -27,6 +27,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUser;
import java.util.List;
@ -37,10 +38,10 @@ public class UserListSubscribersLoader extends CursorSupportUsersLoader {
private final long mUserId;
private final String mScreenName, mListName;
public UserListSubscribersLoader(final Context context, final long accountId, final long listId,
final long userId, final String screenName, final String listName, final long cursor,
public UserListSubscribersLoader(final Context context, final AccountKey accountKey, final long listId,
final long userId, final String screenName, final String listName,
final List<ParcelableUser> data, boolean fromUser) {
super(context, accountId, data, fromUser);
super(context, accountKey, data, fromUser);
mListId = listId;
mUserId = userId;
mScreenName = screenName;

View File

@ -24,28 +24,28 @@ import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
import java.util.List;
public class UserListTimelineLoader extends TwitterAPIStatusesLoader {
private final long mUserId;
private final String mScreenName, mListName;
private final long mListId;
public UserListTimelineLoader(final Context context, final long accountId, final long listId,
public UserListTimelineLoader(final Context context, final AccountKey accountKey, final long listId,
final long userId, final String screenName, final String listName,
final long sinceId, final long maxId, final List<ParcelableStatus> data,
final String[] savedStatusesArgs, final int tabPosition, boolean fromUser) {
super(context, accountId, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
super(context, accountKey, sinceId, maxId, data, savedStatusesArgs, tabPosition, fromUser);
mListId = listId;
mUserId = userId;
mScreenName = screenName;

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.loader.support;
import android.content.Context;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
@ -36,9 +37,9 @@ public class UserListsLoader extends BaseUserListsLoader {
private final String mScreenName;
private final boolean mReverse;
public UserListsLoader(final Context context, final long accountId, final long userId,
public UserListsLoader(final Context context, final AccountKey accountKey, final long userId,
final String screenName, final boolean reverse, final List<ParcelableUserList> data) {
super(context, accountId, 0, data);
super(context, accountKey, 0, data);
mUserId = userId;
mScreenName = screenName;
mReverse = reverse;

View File

@ -10,6 +10,7 @@ import android.view.View;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.util.ParcelableAccountUtils;
@ -19,7 +20,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons
private ParcelableAccount[] mAccounts;
private long[] mAccountIds;
private AccountKey[] mAccountIds;
private boolean mExclusive;
public AccountActionProvider(final Context context, final ParcelableAccount[] accounts) {
@ -78,7 +79,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons
mExclusive = exclusive;
}
public void setSelectedAccountIds(final long... accountIds) {
public void setSelectedAccountIds(final AccountKey... accountIds) {
mAccountIds = accountIds;
}

View File

@ -10,6 +10,8 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.apache.commons.lang3.StringUtils;
/**
* Created by mariotaku on 16/3/5.
*/
@ -17,6 +19,18 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
@ParcelablePlease
public class AccountKey implements Comparable<AccountKey>, Parcelable {
public static final Creator<AccountKey> CREATOR = new Creator<AccountKey>() {
public AccountKey createFromParcel(Parcel source) {
AccountKey target = new AccountKey();
AccountKeyParcelablePlease.readFromParcel(target, source);
return target;
}
public AccountKey[] newArray(int size) {
return new AccountKey[size];
}
};
@JsonField(name = "id")
@ParcelableThisPlease
long id;
@ -52,32 +66,6 @@ public class AccountKey implements Comparable<AccountKey>, Parcelable {
return String.valueOf(id);
}
@Nullable
public static AccountKey valueOf(@Nullable String str) {
if (str == null) return null;
int idxOfAt = str.indexOf("@");
try {
if (idxOfAt != -1) {
final String idStr = str.substring(0, idxOfAt);
return new AccountKey(Long.parseLong(idStr),
str.substring(idxOfAt + 1, str.length()));
} else {
return new AccountKey(Long.parseLong(str), null);
}
} catch (NumberFormatException e) {
return null;
}
}
public static long[] getIds(AccountKey[] ids) {
long[] result = new long[ids.length];
for (int i = 0, idsLength = ids.length; i < idsLength; i++) {
result[i] = ids[i].getId();
}
return result;
}
@Override
public int compareTo(@NonNull AccountKey another) {
if (this.id == another.id) {
@ -119,15 +107,45 @@ public class AccountKey implements Comparable<AccountKey>, Parcelable {
AccountKeyParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<AccountKey> CREATOR = new Creator<AccountKey>() {
public AccountKey createFromParcel(Parcel source) {
AccountKey target = new AccountKey();
AccountKeyParcelablePlease.readFromParcel(target, source);
return target;
}
public boolean isAccount(long accountId, String accountHost) {
return this.id == accountId;
}
public AccountKey[] newArray(int size) {
return new AccountKey[size];
@Nullable
public static AccountKey valueOf(@Nullable String str) {
if (str == null) return null;
int idxOfAt = str.indexOf("@");
try {
if (idxOfAt != -1) {
final String idStr = str.substring(0, idxOfAt);
return new AccountKey(Long.parseLong(idStr),
str.substring(idxOfAt + 1, str.length()));
} else {
return new AccountKey(Long.parseLong(str), null);
}
} catch (NumberFormatException e) {
return null;
}
};
}
@Nullable
public static AccountKey[] arrayOf(@Nullable String str) {
if (str == null) return null;
String[] split = StringUtils.split(str, ",");
AccountKey[] keys = new AccountKey[split.length];
for (int i = 0, splitLength = split.length; i < splitLength; i++) {
keys[i] = valueOf(split[i]);
if (keys[i] == null) return null;
}
return keys;
}
public static long[] getIds(AccountKey[] ids) {
long[] result = new long[ids.length];
for (int i = 0, idsLength = ids.length; i < idsLength; i++) {
result[i] = ids[i].getId();
}
return result;
}
}

View File

@ -30,14 +30,36 @@ import org.mariotaku.twidere.model.AccountKey;
public class FriendshipUpdatedEvent {
@NonNull
public final AccountKey mAccountKey;
public final long userId;
AccountKey accountKey;
long userId;
@NonNull
public final Relationship relationship;
Relationship relationship;
public FriendshipUpdatedEvent(@NonNull AccountKey accountKey, long userId, @NonNull Relationship relationship) {
this.mAccountKey = accountKey;
this.accountKey = accountKey;
this.userId = userId;
this.relationship = relationship;
}
@NonNull
public AccountKey getAccountKey() {
return accountKey;
}
public long getUserId() {
return userId;
}
@NonNull
public Relationship getRelationship() {
return relationship;
}
public boolean isAccount(long accountId, String accountHost) {
return accountKey.isAccount(accountId, accountHost);
}
public boolean isUser(long id) {
return userId == id;
}
}

View File

@ -68,10 +68,10 @@ public class ParcelableAccountUtils {
}
@NonNull
public static ParcelableAccount[] getAccounts(@Nullable final Context context, @Nullable final long... accountIds) {
public static ParcelableAccount[] getAccounts(@Nullable final Context context, @Nullable final AccountKey... accountIds) {
if (context == null) return new ParcelableAccount[0];
final String where = accountIds != null ? Expression.in(new Columns.Column(Accounts.ACCOUNT_ID),
new RawItemArray(accountIds)).getSQL() : null;
new RawItemArray(AccountKey.getIds(accountIds))).getSQL() : null;
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, Accounts.COLUMNS_NO_CREDENTIALS, where, null, null);
if (cur == null) return new ParcelableAccount[0];
return getAccounts(cur, new ParcelableAccountCursorIndices(cur));

View File

@ -77,7 +77,9 @@ public class ParcelableUserUtils implements TwidereConstants {
public static String getUserHost(@Nullable String uri) {
if (uri == null) return USER_TYPE_TWITTER_COM;
return PreviewMediaExtractor.getAuthority(uri);
final String authority = PreviewMediaExtractor.getAuthority(uri);
if (authority == null) return null;
return authority.replaceAll("[^\\w\\d]", "-");
}
public static String getUserHost(ParcelableUser user) {

View File

@ -49,6 +49,7 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.InboxStyle;
import android.support.v4.text.BidiFormatter;
@ -80,6 +81,7 @@ import org.mariotaku.twidere.annotation.NotificationType;
import org.mariotaku.twidere.annotation.ReadPositionTag;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.AccountPreferences;
import org.mariotaku.twidere.model.ActivityTitleSummaryMessage;
import org.mariotaku.twidere.model.Draft;
@ -190,13 +192,15 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
private boolean mUseStarForLikes;
private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String type,
long accountId, long position, boolean extraUserFollowing) {
return getMarkReadDeleteIntent(context, type, accountId, position, -1, -1, extraUserFollowing);
@Nullable AccountKey accountKey, long position,
boolean extraUserFollowing) {
return getMarkReadDeleteIntent(context, type, accountKey, position, -1, -1, extraUserFollowing);
}
private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String type,
long accountId, long position, long extraId,
long extraUserId, boolean extraUserFollowing) {
@Nullable AccountKey accountKey, long position,
long extraId, long extraUserId,
boolean extraUserFollowing) {
// Setup delete intent
final Intent intent = new Intent(context, NotificationReceiver.class);
intent.setAction(BROADCAST_NOTIFICATION_DELETED);
@ -204,7 +208,9 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
linkBuilder.scheme(SCHEME_TWIDERE);
linkBuilder.authority(AUTHORITY_INTERACTIONS);
linkBuilder.appendPath(type);
linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountKey != null) {
linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
linkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITION, String.valueOf(position));
linkBuilder.appendQueryParameter(QUERY_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
linkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, type);
@ -217,14 +223,16 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String notificationType,
long accountId, StringLongPair[] positions) {
@Nullable AccountKey accountId, StringLongPair[] positions) {
// Setup delete intent
final Intent intent = new Intent(context, NotificationReceiver.class);
final Uri.Builder linkBuilder = new Uri.Builder();
linkBuilder.scheme(SCHEME_TWIDERE);
linkBuilder.authority(AUTHORITY_INTERACTIONS);
linkBuilder.appendPath(notificationType);
linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountId != null) {
linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, accountId.toString());
}
linkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITIONS, StringLongPair.toString(positions));
linkBuilder.appendQueryParameter(QUERY_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
linkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, notificationType);
@ -405,11 +413,11 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
clearNotification();
} else if (segments.size() == 2) {
final int notificationType = NumberUtils.toInt(segments.get(1), -1);
clearNotification(notificationType, 0);
clearNotification(notificationType, null);
} else if (segments.size() == 3) {
final int notificationType = NumberUtils.toInt(segments.get(1), -1);
final long accountId = NumberUtils.toLong(segments.get(2), -1);
clearNotification(notificationType, accountId);
final AccountKey accountKey = AccountKey.valueOf(segments.get(2));
clearNotification(notificationType, accountKey);
}
return 1;
}
@ -1063,7 +1071,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
mNotificationManager.cancelAll();
}
private void clearNotification(final int notificationType, final long accountId) {
private void clearNotification(final int notificationType, final AccountKey accountId) {
mNotificationManager.cancelById(Utils.getNotificationId(notificationType, accountId));
}
@ -1257,29 +1265,30 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
}
private long getPositionTag(String tag, long accountId) {
private long getPositionTag(String tag, AccountKey accountKey) {
final long position = mReadStateManager.getPosition(Utils.getReadPositionTagWithAccounts(tag,
accountId));
accountKey));
if (position != -1) return position;
return mReadStateManager.getPosition(tag);
}
private void showTimelineNotification(AccountPreferences pref, long position) {
final long accountId = pref.getAccountKey();
final AccountKey accountKey = pref.getAccountKey();
final Context context = getContext();
if (context == null) return;
final Resources resources = context.getResources();
final NotificationManagerWrapper nm = mNotificationManager;
final Expression selection = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
final Expression selection = Expression.and(Utils.getAccountCompareExpression(),
Expression.greaterThan(Statuses.STATUS_ID, position));
final String filteredSelection = DataStoreUtils.buildStatusFilterWhereClause(Statuses.TABLE_NAME,
selection).getSQL();
final String[] selectionArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
final String[] userProjection = {Statuses.USER_ID, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME};
final String[] statusProjection = {Statuses.STATUS_ID};
final Cursor statusCursor = mDatabaseWrapper.query(Statuses.TABLE_NAME, statusProjection,
filteredSelection, null, null, null, Statuses.DEFAULT_SORT_ORDER);
filteredSelection, selectionArgs, null, null, Statuses.DEFAULT_SORT_ORDER);
final Cursor userCursor = mDatabaseWrapper.query(Statuses.TABLE_NAME, userProjection,
filteredSelection, null, Statuses.USER_ID, null, Statuses.DEFAULT_SORT_ORDER);
filteredSelection, selectionArgs, Statuses.USER_ID, null, Statuses.DEFAULT_SORT_ORDER);
//noinspection TryFinallyCanBeTryWithResources
try {
final int usersCount = userCursor.getCount();
@ -1316,14 +1325,14 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
builder.setContentText(notificationContent);
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
builder.setContentIntent(getContentIntent(context, CustomTabType.HOME_TIMELINE,
NotificationType.HOME_TIMELINE, accountId, statusId));
NotificationType.HOME_TIMELINE, accountKey, statusId));
builder.setDeleteIntent(getMarkReadDeleteIntent(context, NotificationType.HOME_TIMELINE,
accountId, statusId, false));
accountKey, statusId, false));
builder.setNumber(statusesCount);
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
applyNotificationPreferences(builder, pref, pref.getHomeTimelineNotificationType());
try {
nm.notify("home_" + accountId, Utils.getNotificationId(NOTIFICATION_ID_HOME_TIMELINE, accountId), builder.build());
nm.notify("home_" + accountKey, Utils.getNotificationId(NOTIFICATION_ID_HOME_TIMELINE, accountKey), builder.build());
Utils.sendPebbleNotification(context, notificationContent);
} catch (SecurityException e) {
// Silently ignore
@ -1337,12 +1346,13 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
private void showInteractionsNotification(AccountPreferences pref, long position, boolean combined) {
final Context context = getContext();
if (context == null) return;
final long accountId = pref.getAccountKey();
final AccountKey accountKey = pref.getAccountKey();
final String where = Expression.and(
Expression.equals(Activities.ACCOUNT_ID, pref.getAccountKey()),
Utils.getAccountCompareExpression(),
Expression.greaterThan(Activities.TIMESTAMP, position)
).getSQL();
Cursor c = query(Activities.AboutMe.CONTENT_URI, Activities.COLUMNS, where, null,
final String[] whereArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
Cursor c = query(Activities.AboutMe.CONTENT_URI, Activities.COLUMNS, where, whereArgs,
new OrderBy(Activities.TIMESTAMP, false).getSQL());
if (c == null) return;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
@ -1354,7 +1364,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
applyNotificationPreferences(builder, pref, pref.getMentionsNotificationType());
final Resources resources = context.getResources();
final String accountName = DataStoreUtils.getAccountDisplayName(context, accountId, mNameFirst);
final String accountName = DataStoreUtils.getAccountDisplayName(context, accountKey, mNameFirst);
builder.setContentText(accountName);
final InboxStyle style = new InboxStyle();
builder.setStyle(style);
@ -1405,27 +1415,29 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
style.setBigContentTitle(title);
builder.setNumber(displayCount);
builder.setContentIntent(getContentIntent(context, CustomTabType.NOTIFICATIONS_TIMELINE,
NotificationType.INTERACTIONS, accountId, timestamp));
NotificationType.INTERACTIONS, accountKey, timestamp));
if (timestamp != -1) {
builder.setDeleteIntent(getMarkReadDeleteIntent(context,
NotificationType.INTERACTIONS, accountId, timestamp, false));
NotificationType.INTERACTIONS, accountKey, timestamp, false));
}
} finally {
c.close();
}
final int notificationId = Utils.getNotificationId(NOTIFICATION_ID_INTERACTIONS_TIMELINE, accountId);
final int notificationId = Utils.getNotificationId(NOTIFICATION_ID_INTERACTIONS_TIMELINE,
accountKey);
mNotificationManager.notify("interactions", notificationId, builder.build());
}
private PendingIntent getContentIntent(final Context context, @CustomTabType final String type,
@NotificationType final String notificationType,
final long accountId, final long readPosition) {
@Nullable final AccountKey accountKey, final long readPosition) {
// Setup click intent
final Intent homeIntent = new Intent(context, HomeActivity.class);
final Uri.Builder homeLinkBuilder = new Uri.Builder();
homeLinkBuilder.scheme(SCHEME_TWIDERE);
homeLinkBuilder.authority(type);
homeLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountKey != null)
homeLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
homeLinkBuilder.appendQueryParameter(QUERY_PARAM_FROM_NOTIFICATION, String.valueOf(true));
homeLinkBuilder.appendQueryParameter(QUERY_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
homeLinkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, notificationType);
@ -1483,19 +1495,21 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
private void showMessagesNotification(AccountPreferences pref, StringLongPair[] pairs, ContentValues[] valuesArray) {
final Context context = getContext();
assert context != null;
final long accountId = pref.getAccountKey();
final long prevOldestId = mReadStateManager.getPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId));
final AccountKey accountKey = pref.getAccountKey();
final long prevOldestId = mReadStateManager.getPosition(TAG_OLDEST_MESSAGES,
String.valueOf(accountKey));
long oldestId = -1;
for (final ContentValues contentValues : valuesArray) {
final long messageId = contentValues.getAsLong(DirectMessages.MESSAGE_ID);
oldestId = oldestId < 0 ? messageId : Math.min(oldestId, messageId);
if (messageId <= prevOldestId) return;
}
mReadStateManager.setPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId), oldestId, false);
mReadStateManager.setPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountKey), oldestId,
false);
final Resources resources = context.getResources();
final NotificationManagerWrapper nm = mNotificationManager;
final ArrayList<Expression> orExpressions = new ArrayList<>();
final String prefix = accountId + "-";
final String prefix = accountKey + "-";
final int prefixLength = prefix.length();
final Set<Long> senderIds = new CompactHashSet<>();
for (StringLongPair pair : pairs) {
@ -1512,27 +1526,30 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
orExpressions.add(Expression.notIn(new Column(DirectMessages.SENDER_ID), new RawItemArray(senderIds.toArray())));
final Expression selection = Expression.and(
Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
Utils.getAccountCompareExpression(),
Expression.greaterThan(DirectMessages.MESSAGE_ID, prevOldestId),
Expression.or(orExpressions.toArray(new Expression[orExpressions.size()]))
);
final String filteredSelection = selection.getSQL();
final String[] selectionArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
final String[] userProjection = {DirectMessages.SENDER_ID, DirectMessages.SENDER_NAME,
DirectMessages.SENDER_SCREEN_NAME};
final String[] messageProjection = {DirectMessages.MESSAGE_ID, DirectMessages.SENDER_ID,
DirectMessages.SENDER_NAME, DirectMessages.SENDER_SCREEN_NAME, DirectMessages.TEXT_UNESCAPED,
DirectMessages.MESSAGE_TIMESTAMP};
final Cursor messageCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, messageProjection,
filteredSelection, null, null, null, DirectMessages.DEFAULT_SORT_ORDER);
final Cursor userCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, userProjection,
filteredSelection, null, DirectMessages.SENDER_ID, null, DirectMessages.DEFAULT_SORT_ORDER);
final Cursor messageCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME,
messageProjection, filteredSelection, selectionArgs, null, null,
DirectMessages.DEFAULT_SORT_ORDER);
final Cursor userCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME,
userProjection, filteredSelection, selectionArgs, DirectMessages.SENDER_ID, null,
DirectMessages.DEFAULT_SORT_ORDER);
//noinspection TryFinallyCanBeTryWithResources
try {
final int usersCount = userCursor.getCount();
final int messagesCount = messageCursor.getCount();
if (messagesCount == 0 || usersCount == 0) return;
final String accountName = DataStoreUtils.getAccountName(context, accountId);
final String accountScreenName = DataStoreUtils.getAccountScreenName(context, accountId);
final String accountName = DataStoreUtils.getAccountName(context, accountKey);
final String accountScreenName = DataStoreUtils.getAccountScreenName(context, accountKey);
final int idxMessageText = messageCursor.getColumnIndex(DirectMessages.TEXT_UNESCAPED),
idxMessageTimestamp = messageCursor.getColumnIndex(DirectMessages.MESSAGE_TIMESTAMP),
idxMessageId = messageCursor.getColumnIndex(DirectMessages.MESSAGE_ID),
@ -1601,16 +1618,16 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
builder.setContentText(notificationContent);
builder.setCategory(NotificationCompat.CATEGORY_MESSAGE);
builder.setContentIntent(getContentIntent(context, CustomTabType.DIRECT_MESSAGES,
NotificationType.DIRECT_MESSAGES, accountId, -1));
NotificationType.DIRECT_MESSAGES, accountKey, -1));
builder.setDeleteIntent(getMarkReadDeleteIntent(context,
NotificationType.DIRECT_MESSAGES, accountId, positions));
NotificationType.DIRECT_MESSAGES, accountKey, positions));
builder.setNumber(messagesCount);
builder.setWhen(when);
builder.setStyle(style);
builder.setColor(pref.getNotificationLightColor());
applyNotificationPreferences(builder, pref, pref.getDirectMessagesNotificationType());
try {
nm.notify("messages_" + accountId, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build());
nm.notify("messages_" + accountKey, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build());
Utils.sendPebbleNotification(context, notificationContent);
} catch (SecurityException e) {
// Silently ignore

View File

@ -31,6 +31,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.annotation.CustomTabType;
import org.mariotaku.twidere.annotation.NotificationType;
import org.mariotaku.twidere.annotation.ReadPositionTag;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.StringLongPair;
import org.mariotaku.twidere.util.CustomTabUtils;
import org.mariotaku.twidere.util.ReadStateManager;
@ -56,15 +57,15 @@ public class NotificationReceiver extends BroadcastReceiver implements Constants
DependencyHolder holder = DependencyHolder.get(context);
@NotificationType
final String notificationType = uri.getQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE);
final long accountId = NumberUtils.toLong(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_ID), -1);
final AccountKey accountKey = AccountKey.valueOf(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_KEY));
final long itemId = NumberUtils.toLong(UriExtraUtils.getExtra(uri, "item_id"), -1);
final long itemUserId = NumberUtils.toLong(UriExtraUtils.getExtra(uri, "item_user_id"), -1);
final boolean itemUserFollowing = Boolean.parseBoolean(UriExtraUtils.getExtra(uri, "item_user_following"));
final long timestamp = NumberUtils.toLong(uri.getQueryParameter(QUERY_PARAM_TIMESTAMP), -1);
if (CustomTabType.NOTIFICATIONS_TIMELINE.equals(CustomTabUtils.getTabTypeAlias(notificationType))
&& accountId != -1 && itemId != -1 && timestamp != -1) {
&& accountKey != null && itemId != -1 && timestamp != -1) {
final HotMobiLogger logger = holder.getHotMobiLogger();
logger.log(accountId, NotificationEvent.deleted(context, timestamp, notificationType, accountId,
logger.log(accountKey, NotificationEvent.deleted(context, timestamp, notificationType, accountKey,
itemId, itemUserId, itemUserFollowing));
}
final ReadStateManager manager = holder.getReadStateManager();
@ -73,7 +74,7 @@ public class NotificationReceiver extends BroadcastReceiver implements Constants
final String tag = getPositionTag(notificationType);
if (tag != null && !TextUtils.isEmpty(paramReadPosition = uri.getQueryParameter(QUERY_PARAM_READ_POSITION))) {
final long def = -1;
manager.setPosition(Utils.getReadPositionTagWithAccounts(tag, accountId),
manager.setPosition(Utils.getReadPositionTagWithAccounts(tag, accountKey),
NumberUtils.toLong(paramReadPosition, def));
} else if (!TextUtils.isEmpty(paramReadPositions = uri.getQueryParameter(QUERY_PARAM_READ_POSITIONS))) {
try {

View File

@ -35,6 +35,7 @@ import android.util.Log;
import org.apache.commons.lang3.math.NumberUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.AccountPreferences;
import org.mariotaku.twidere.model.SimpleRefreshTaskParam;
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
@ -90,11 +91,11 @@ public class RefreshService extends Service implements Constants {
if (BROADCAST_REFRESH_HOME_TIMELINE.equals(action)) {
if (!isHomeTimelineRefreshing()) {
mTwitterWrapper.getHomeTimelineAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
private AccountKey[] accountIds;
@NonNull
@Override
public long[] getAccountKeys() {
public AccountKey[] getAccountKeys() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountKeys(context));
@ -111,11 +112,11 @@ public class RefreshService extends Service implements Constants {
}
} else if (BROADCAST_REFRESH_NOTIFICATIONS.equals(action)) {
mTwitterWrapper.getActivitiesAboutMeAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
private AccountKey[] accountIds;
@NonNull
@Override
public long[] getAccountKeys() {
public AccountKey[] getAccountKeys() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountKeys(context));
@ -132,11 +133,11 @@ public class RefreshService extends Service implements Constants {
} else if (BROADCAST_REFRESH_DIRECT_MESSAGES.equals(action)) {
if (!isReceivedDirectMessagesRefreshing()) {
mTwitterWrapper.getReceivedDirectMessagesAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
private AccountKey[] accountIds;
@NonNull
@Override
public long[] getAccountKeys() {
public AccountKey[] getAccountKeys() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountKeys(context));
@ -154,7 +155,7 @@ public class RefreshService extends Service implements Constants {
} else if (BROADCAST_REFRESH_TRENDS.equals(action)) {
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountKeys(context));
final long[] refreshIds = getRefreshableIds(prefs, TrendsRefreshableFilter.INSTANCE);
final AccountKey[] refreshIds = getRefreshableIds(prefs, TrendsRefreshableFilter.INSTANCE);
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing trends for %s", Arrays.toString(refreshIds)));
}
@ -274,22 +275,22 @@ public class RefreshService extends Service implements Constants {
return isNetworkAvailable(this) && (isBatteryOkay(this) || !shouldStopAutoRefreshOnBatteryLow(this));
}
private void getLocalTrends(final long[] accountIds) {
final long account_id = getDefaultAccountKey(this);
private void getLocalTrends(final AccountKey[] accountIds) {
final AccountKey account_id = getDefaultAccountKey(this);
final int woeid = mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1);
mTwitterWrapper.getLocalTrendsAsync(account_id, woeid);
}
private long[] getRefreshableIds(final AccountPreferences[] prefs, final RefreshableAccountFilter filter) {
private AccountKey[] getRefreshableIds(final AccountPreferences[] prefs, final RefreshableAccountFilter filter) {
if (prefs == null) return null;
final long[] temp = new long[prefs.length];
final AccountKey[] temp = new AccountKey[prefs.length];
int i = 0;
for (final AccountPreferences pref : prefs) {
if (pref.isAutoRefreshEnabled() && filter.isRefreshable(pref)) {
temp[i++] = pref.getAccountKey();
}
}
final long[] result = new long[i];
final AccountKey[] result = new AccountKey[i];
System.arraycopy(temp, 0, result, 0, i);
return result;
}

View File

@ -12,6 +12,7 @@ import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.util.ErrorInfoStore;
@ -33,7 +34,7 @@ public class GetActivitiesAboutMeTask extends GetActivitiesTask {
}
@Override
protected void saveReadPosition(long accountId, Twitter twitter) {
protected void saveReadPosition(@NonNull AccountKey accountId, @NonNull Twitter twitter) {
try {
CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountId);
@ -44,13 +45,13 @@ public class GetActivitiesAboutMeTask extends GetActivitiesTask {
}
@Override
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, final long accountId, final Paging paging) throws TwitterException {
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, @NonNull final AccountKey accountId, @NonNull final Paging paging) throws TwitterException {
if (Utils.isOfficialCredentials(context, accountId)) {
return twitter.getActivitiesAboutMe(paging);
}
final ResponseList<Activity> activities = new ResponseList<>();
for (Status status : twitter.getMentionsTimeline(paging)) {
activities.add(Activity.fromMention(accountId, status));
activities.add(Activity.fromMention(accountId.getId(), status));
}
return activities;
}

View File

@ -7,6 +7,7 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Trends;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
import java.util.List;
@ -18,8 +19,8 @@ public class GetLocalTrendsTask extends GetTrendsTask {
private final int woeid;
public GetLocalTrendsTask(final Context context, final long accountId, final int woeid) {
super(context, accountId);
public GetLocalTrendsTask(final Context context, final AccountKey accountKey, final int woeid) {
super(context, accountKey);
this.woeid = woeid;
}

View File

@ -9,6 +9,7 @@ import android.support.annotation.NonNull;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Trends;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.util.ContentValuesCreator;
import org.mariotaku.twidere.util.TwitterAPIFactory;
@ -23,18 +24,18 @@ import java.util.List;
public abstract class GetTrendsTask extends AbstractTask<Object, Object, Object> {
private final Context mContext;
private final long mAccountId;
private final AccountKey mAccountId;
public GetTrendsTask(Context context, final long accountId) {
public GetTrendsTask(Context context, final AccountKey accountKey) {
this.mContext = context;
this.mAccountId = accountId;
this.mAccountId = accountKey;
}
public abstract List<Trends> getTrends(@NonNull Twitter twitter) throws TwitterException;
@Override
public Object doLongOperation(final Object param) {
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, accountHost, false);
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false);
if (twitter == null) return null;
try {
final List<Trends> trends = getTrends(twitter);

View File

@ -32,6 +32,7 @@ import org.mariotaku.twidere.util.ErrorInfoStore;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.TwitterAPIFactory;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
@ -138,12 +139,13 @@ public abstract class GetActivitiesTask extends AbstractTask<RefreshTaskParam, O
valuesList.add(values);
}
if (deleteBound[0] > 0 && deleteBound[1] > 0) {
Expression where = Expression.and(
Expression.equals(Activities.ACCOUNT_ID, accountKey),
final Expression where = Expression.and(
Utils.getAccountCompareExpression(),
Expression.greaterEquals(Activities.MIN_POSITION, deleteBound[0]),
Expression.lesserEquals(Activities.MAX_POSITION, deleteBound[1])
);
int rowsDeleted = cr.delete(getContentUri(), where.getSQL(), null);
final String[] whereArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
int rowsDeleted = cr.delete(getContentUri(), where.getSQL(), whereArgs);
boolean insertGap = valuesList.size() >= loadItemLimit && !noItemsBefore
&& rowsDeleted <= 0;
if (insertGap && !valuesList.isEmpty()) {
@ -153,10 +155,13 @@ public abstract class GetActivitiesTask extends AbstractTask<RefreshTaskParam, O
ContentResolverUtils.bulkInsert(cr, getContentUri(), valuesList);
}
protected abstract void saveReadPosition(long accountId, Twitter twitter);
protected abstract void saveReadPosition(@NonNull final AccountKey accountId,
@NonNull final Twitter twitter);
protected abstract ResponseList<Activity> getActivities(@NonNull final Twitter twitter,
final long accountId, final Paging paging) throws TwitterException;
@NonNull final AccountKey accountId,
@NonNull final Paging paging)
throws TwitterException;
@Override
public void afterExecute(Object result) {

View File

@ -61,6 +61,7 @@ import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.model.Response;
import org.mariotaku.twidere.model.SimpleRefreshTaskParam;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.model.message.FavoriteTaskEvent;
import org.mariotaku.twidere.model.message.FollowRequestTaskEvent;
@ -287,7 +288,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return true;
}
public void getLocalTrendsAsync(final long accountId, final int woeid) {
public void getLocalTrendsAsync(final AccountKey accountId, final int woeid) {
final GetLocalTrendsTask task = new GetLocalTrendsTask(mContext, accountId, woeid);
TaskStarter.execute(task);
}
@ -373,41 +374,50 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public boolean refreshAll(final AccountKey[] accountKeys) {
AsyncTaskUtils.executeTask(new AsyncTask<AccountKey, Object, Object[]>() {
getHomeTimelineAsync(new SimpleRefreshTaskParam() {
@NonNull
@Override
protected Object[] doInBackground(AccountKey... accountKeys) {
final Object[] result = new Object[8];
result[0] = DataStoreUtils.getNewestStatusIds(mContext, Statuses.CONTENT_URI, accountKeys);
if (Boolean.TRUE.equals(result[1] = mPreferences.getBoolean(KEY_HOME_REFRESH_MENTIONS))) {
result[2] = DataStoreUtils.getNewestActivityMaxPositions(mContext,
Activities.AboutMe.CONTENT_URI, accountKeys);
}
if (Boolean.TRUE.equals(result[3] = mPreferences.getBoolean(KEY_HOME_REFRESH_DIRECT_MESSAGES))) {
result[4] = DataStoreUtils.getNewestMessageIds(mContext, DirectMessages.Inbox.CONTENT_URI, accountKeys);
}
if (Boolean.TRUE.equals(result[5] = mPreferences.getBoolean(KEY_HOME_REFRESH_TRENDS))) {
result[6] = Utils.getDefaultAccountKey(mContext);
result[7] = mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1);
}
return result;
public AccountKey[] getAccountKeys() {
return accountKeys;
}
@Nullable
@Override
protected void onPostExecute(Object[] result) {
getHomeTimelineAsync(accountKeys, null, (long[]) result[0]);
if (Boolean.TRUE.equals(result[1])) {
getActivitiesAboutMeAsync(accountKeys, null, (long[]) result[2]);
}
if (Boolean.TRUE.equals(result[3])) {
getReceivedDirectMessagesAsync(accountKeys, null, (long[]) result[4]);
getSentDirectMessagesAsync(accountKeys, null, null);
}
if (Boolean.TRUE.equals(result[5])) {
getLocalTrendsAsync((Long) result[6], (Integer) result[7]);
}
getSavedSearchesAsync(accountKeys);
public long[] getSinceIds() {
return DataStoreUtils.getNewestStatusIds(mContext, Statuses.CONTENT_URI,
accountKeys);
}
}, accountKeys);
});
getActivitiesAboutMeAsync(new SimpleRefreshTaskParam() {
@NonNull
@Override
public AccountKey[] getAccountKeys() {
return accountKeys;
}
@Nullable
@Override
public long[] getSinceIds() {
return DataStoreUtils.getNewestActivityMaxPositions(mContext,
Activities.AboutMe.CONTENT_URI, accountKeys);
}
});
getReceivedDirectMessagesAsync(new SimpleRefreshTaskParam() {
@NonNull
@Override
public AccountKey[] getAccountKeys() {
return accountKeys;
}
});
getSentDirectMessagesAsync(new SimpleRefreshTaskParam() {
@NonNull
@Override
public AccountKey[] getAccountKeys() {
return accountKeys;
}
});
getSavedSearchesAsync(accountKeys);
return true;
}
@ -423,7 +433,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
AsyncTaskUtils.executeTask(task);
}
public void reportMultiSpam(final long accountId, final long[] userIds) {
public void reportMultiSpam(final AccountKey accountKey, final long[] userIds) {
// TODO implementation
}

View File

@ -49,6 +49,7 @@ import org.mariotaku.twidere.fragment.support.TrendsSuggestionsFragment;
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.CustomTabConfiguration;
import org.mariotaku.twidere.model.CustomTabConfiguration.ExtraConfiguration;
import org.mariotaku.twidere.model.SupportTabSpec;
@ -290,12 +291,14 @@ public class CustomTabUtils implements Constants {
return tabType != null && CUSTOM_TABS_CONFIGURATION_MAP.containsKey(getTabTypeAlias(tabType));
}
public static boolean hasAccountId(@NonNull Bundle args, long[] activatedAccountIds, long accountId) {
if (args.containsKey(EXTRA_ACCOUNT_ID)) {
return args.getLong(EXTRA_ACCOUNT_ID) == accountId;
} else if (args.containsKey(EXTRA_ACCOUNT_IDS)) {
return ArrayUtils.contains(args.getLongArray(EXTRA_ACCOUNT_IDS), accountId);
public static boolean hasAccountId(@NonNull Bundle args, AccountKey[] activatedAccountKeys, AccountKey accountKey) {
final AccountKey[] accountKeys = Utils.getAccountKeys(args);
if (accountKeys != null) {
return ArrayUtils.contains(accountKeys, accountKey);
}
return ArrayUtils.contains(activatedAccountIds, accountId);
if (activatedAccountKeys != null) {
return ArrayUtils.contains(activatedAccountKeys, accountKey);
}
return false;
}
}

View File

@ -29,7 +29,6 @@ import android.os.Bundle;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import android.text.TextUtils;
import com.bluelinelabs.logansquare.JsonMapper;
@ -98,8 +97,8 @@ import static org.mariotaku.twidere.provider.TwidereDataStore.STATUSES_URIS;
public class DataStoreUtils implements Constants {
static final UriMatcher CONTENT_PROVIDER_URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static Map<AccountKey, Integer> sAccountColors = new HashMap<>();
static LongSparseArray<String> sAccountScreenNames = new LongSparseArray<>();
static LongSparseArray<String> sAccountNames = new LongSparseArray<>();
static Map<AccountKey, String> sAccountScreenNames = new HashMap<>();
static Map<AccountKey, String> sAccountNames = new HashMap<>();
static {
CONTENT_PROVIDER_URI_MATCHER.addURI(TwidereDataStore.AUTHORITY, Accounts.CONTENT_PATH,
@ -327,18 +326,51 @@ public class DataStoreUtils implements Constants {
return filterExpression;
}
public static String getAccountScreenName(final Context context, final long accountId) {
public static String getAccountDisplayName(final Context context, final AccountKey accountKey, final boolean nameFirst) {
final String name;
if (nameFirst) {
name = getAccountName(context, accountKey);
} else {
name = String.format("@%s", getAccountScreenName(context, accountKey));
}
return name;
}
public static String getAccountName(final Context context, final AccountKey accountKey) {
if (context == null) return null;
final String cached = sAccountScreenNames.get(accountId);
final String cached = sAccountNames.get(accountKey);
if (!isEmpty(cached)) return cached;
final String[] projection = {Accounts.SCREEN_NAME};
String[] whereArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, projection,
Accounts.ACCOUNT_ID + " = " + accountId, null, null);
Utils.getAccountCompareExpression().getSQL(), whereArgs, null);
if (cur == null) return null;
try {
if (cur.getCount() > 0 && cur.moveToFirst()) {
final String name = cur.getString(0);
sAccountScreenNames.put(accountId, name);
sAccountNames.put(accountKey, name);
return name;
}
return null;
} finally {
cur.close();
}
}
public static String getAccountScreenName(final Context context, final AccountKey accountKey) {
if (context == null) return null;
final String cached = sAccountScreenNames.get(accountKey);
if (!isEmpty(cached)) return cached;
final String[] projection = {Accounts.SCREEN_NAME};
String[] whereArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, projection,
Utils.getAccountCompareExpression().getSQL(), whereArgs, null);
if (cur == null) return null;
try {
if (cur.getCount() > 0 && cur.moveToFirst()) {
final String name = cur.getString(0);
sAccountScreenNames.put(accountKey, name);
return name;
}
return null;
@ -621,16 +653,6 @@ public class DataStoreUtils implements Constants {
}
}
public static String getAccountDisplayName(final Context context, final long accountId, final boolean nameFirst) {
final String name;
if (nameFirst) {
name = getAccountName(context, accountId);
} else {
name = String.format("@%s", getAccountScreenName(context, accountId));
}
return name;
}
public static long getAccountId(final Context context, final String screenName) {
if (context == null || isEmpty(screenName)) return -1;
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{Accounts.ACCOUNT_ID}, Expression.equalsArgs(Accounts.SCREEN_NAME).getSQL(), new String[]{screenName}, null);
@ -676,24 +698,6 @@ public class DataStoreUtils implements Constants {
}
}
public static String getAccountName(final Context context, final long accountId) {
if (context == null) return null;
final String cached = sAccountNames.get(accountId);
if (!isEmpty(cached)) return cached;
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{Accounts.NAME}, Accounts.ACCOUNT_ID + " = " + accountId, null, null);
if (cur == null) return null;
try {
if (cur.getCount() > 0 && cur.moveToFirst()) {
final String name = cur.getString(0);
sAccountNames.put(accountId, name);
return name;
}
return null;
} finally {
cur.close();
}
}
public static synchronized void cleanDatabasesByItemLimit(final Context context) {
if (context == null) return;
final ContentResolver resolver = context.getContentResolver();
@ -844,10 +848,11 @@ public class DataStoreUtils implements Constants {
}
@NonNull
public static long[] getAccountKeys(final ParcelableAccount[] accounts) {
final long[] ids = new long[accounts.length];
public static AccountKey[] getAccountKeys(final ParcelableAccount[] accounts) {
final AccountKey[] ids = new AccountKey[accounts.length];
for (int i = 0, j = accounts.length; i < j; i++) {
ids[i] = accounts[i].account_id;
final ParcelableAccount account = accounts[i];
ids[i] = new AccountKey(account.account_id, account.account_host);
}
return ids;
}
@ -910,11 +915,11 @@ public class DataStoreUtils implements Constants {
return null;
}
public static String getAccountType(final Context context, final long accountId) {
if (context == null || accountId < 0) return null;
public static String getAccountType(@NonNull final Context context, @NonNull final AccountKey accountKey) {
final String[] projection = {Accounts.ACCOUNT_TYPE};
String[] whereArgs = {String.valueOf(accountKey.getId()), accountKey.getHost()};
Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, projection,
Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(), null, null);
Utils.getAccountCompareExpression().getSQL(), whereArgs, null);
if (cur == null) return null;
try {
if (cur.moveToFirst()) {
@ -982,4 +987,19 @@ public class DataStoreUtils implements Constants {
return getActivitiesCount(context, Activities.AboutMe.CONTENT_URI, extraWhere, extraWhereArgs,
position, followingOnly, accountIds);
}
public static void initAccountColor(final Context context) {
if (context == null) return;
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{
Accounts.ACCOUNT_ID, Accounts.COLOR}, null, null, null);
if (cur == null) return;
final int id_idx = cur.getColumnIndex(Accounts.ACCOUNT_ID), color_idx = cur.getColumnIndex(Accounts.COLOR);
cur.moveToFirst();
while (!cur.isAfterLast()) {
// sAccountColors.put(cur.getLong(id_idx), cur.getInt(color_idx));
// TODO
cur.moveToNext();
}
cur.close();
}
}

View File

@ -22,6 +22,7 @@ import org.mariotaku.twidere.activity.support.MediaViewerActivity;
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
import org.mariotaku.twidere.fragment.support.SensitiveContentWarningDialogFragment;
import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableDirectMessage;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
@ -124,23 +125,25 @@ public class IntentUtils implements Constants {
public static void openMedia(final Context context, final ParcelableDirectMessage message,
final ParcelableMedia current, @Nullable final Bundle options,
final boolean newDocument) {
openMedia(context, message.account_id, false, null, message, current, message.media, options, newDocument);
openMedia(context, new AccountKey(message.account_id, message.account_host), false, null,
message, current, message.media, options, newDocument);
}
public static void openMedia(final Context context, final ParcelableStatus status,
final ParcelableMedia current, final Bundle options,
final boolean newDocument) {
openMedia(context, status.account_id, status.is_possibly_sensitive, status, null, current,
getPrimaryMedia(status), options, newDocument);
openMedia(context, new AccountKey(status.account_id, status.account_host),
status.is_possibly_sensitive, status, null, current, getPrimaryMedia(status),
options, newDocument);
}
public static void openMedia(final Context context, final long accountId, final boolean isPossiblySensitive,
public static void openMedia(final Context context, final AccountKey accountKey, final boolean isPossiblySensitive,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
openMedia(context, accountId, isPossiblySensitive, null, null, current, media, options, newDocument);
openMedia(context, accountKey, isPossiblySensitive, null, null, current, media, options, newDocument);
}
public static void openMedia(final Context context, final long accountId, final boolean isPossiblySensitive,
public static void openMedia(final Context context, final AccountKey accountKey, final boolean isPossiblySensitive,
final ParcelableStatus status, final ParcelableDirectMessage message,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
@ -152,7 +155,7 @@ public class IntentUtils implements Constants {
final FragmentManager fm = activity.getSupportFragmentManager();
final DialogFragment fragment = new SensitiveContentWarningDialogFragment();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, accountId);
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey);
args.putParcelable(EXTRA_CURRENT_MEDIA, current);
if (status != null) {
args.putParcelable(EXTRA_STATUS, status);
@ -167,15 +170,15 @@ public class IntentUtils implements Constants {
fragment.setArguments(args);
fragment.show(fm, "sensitive_content_warning");
} else {
openMediaDirectly(context, accountId, status, message, current, media, options,
openMediaDirectly(context, accountKey, status, message, current, media, options,
newDocument);
}
}
public static void openMediaDirectly(final Context context, final long accountId,
public static void openMediaDirectly(final Context context, final AccountKey accountKey,
final ParcelableStatus status, final ParcelableMedia current,
final Bundle options, final boolean newDocument) {
openMediaDirectly(context, accountId, status, null, current, getPrimaryMedia(status),
openMediaDirectly(context, accountKey, status, null, current, getPrimaryMedia(status),
options, newDocument);
}
@ -187,29 +190,29 @@ public class IntentUtils implements Constants {
}
}
public static void openMediaDirectly(final Context context, final long accountId,
public static void openMediaDirectly(final Context context, final AccountKey accountKey,
final ParcelableDirectMessage message, final ParcelableMedia current,
final ParcelableMedia[] media, final Bundle options,
final boolean newDocument) {
openMediaDirectly(context, accountId, null, message, current, media, options, newDocument);
openMediaDirectly(context, accountKey, null, message, current, media, options, newDocument);
}
public static void openMediaDirectly(final Context context, final long accountId,
public static void openMediaDirectly(final Context context, final AccountKey accountKey,
final ParcelableStatus status, final ParcelableDirectMessage message,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
if (context == null || media == null) return;
final Intent intent = new Intent(context, MediaViewerActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
intent.putExtra(EXTRA_ACCOUNT_ID, accountKey);
intent.putExtra(EXTRA_CURRENT_MEDIA, current);
intent.putExtra(EXTRA_MEDIA, media);
if (status != null) {
intent.putExtra(EXTRA_STATUS, status);
intent.setData(getMediaViewerUri("status", status.id, accountId));
intent.setData(getMediaViewerUri("status", status.id, accountKey));
}
if (message != null) {
intent.putExtra(EXTRA_MESSAGE, message);
intent.setData(getMediaViewerUri("message", message.id, accountId));
intent.setData(getMediaViewerUri("message", message.id, accountKey));
}
if (newDocument && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
@ -221,13 +224,15 @@ public class IntentUtils implements Constants {
}
}
public static Uri getMediaViewerUri(String type, long id, long accountId) {
public static Uri getMediaViewerUri(String type, long id, AccountKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority("media");
builder.appendPath(type);
builder.appendPath(String.valueOf(id));
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
return builder.build();
}
}

View File

@ -170,7 +170,7 @@ public class KeyboardShortcutsHandler implements Constants, KeyboardShortcutCons
return true;
}
case ACTION_MESSAGE: {
Utils.openMessageConversation(context, -1, -1);
Utils.openMessageConversation(context, null, -1);
return true;
}
}

View File

@ -35,6 +35,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseAppCompatActivity;
import org.mariotaku.twidere.menu.AccountActionProvider;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
@ -122,7 +123,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
final ParcelableStatus first_status = (ParcelableStatus) firstObj;
bundle.putLong(EXTRA_IN_REPLY_TO_ID, first_status.id);
}
bundle.putLong(EXTRA_ACCOUNT_ID, mMultiSelectManager.getAccountId());
bundle.putParcelable(EXTRA_ACCOUNT_KEY, mMultiSelectManager.getAccountKey());
bundle.putStringArray(EXTRA_SCREEN_NAMES, allMentions.toArray(new String[allMentions.size()]));
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -153,19 +154,19 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
break;
}
case R.id.block: {
final long accountId = mMultiSelectManager.getAccountId();
final AccountKey accountKey = mMultiSelectManager.getAccountKey();
final long[] userIds = MultiSelectManager.getSelectedUserIds(selectedItems);
if (accountId > 0 && userIds != null) {
mTwitterWrapper.createMultiBlockAsync(accountId, userIds);
if (accountKey != null && userIds != null) {
mTwitterWrapper.createMultiBlockAsync(accountKey, userIds);
}
mode.finish();
break;
}
case R.id.report_spam: {
final long accountId = mMultiSelectManager.getAccountId();
final AccountKey accountKey = mMultiSelectManager.getAccountKey();
final long[] userIds = MultiSelectManager.getSelectedUserIds(selectedItems);
if (accountId > 0 && userIds != null) {
mTwitterWrapper.reportMultiSpam(accountId, userIds);
if (accountKey != null && userIds != null) {
mTwitterWrapper.reportMultiSpam(accountKey, userIds);
}
mode.finish();
break;
@ -175,7 +176,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
final Intent intent = item.getIntent();
if (intent == null || !intent.hasExtra(EXTRA_ACCOUNT)) return false;
final ParcelableAccount account = intent.getParcelableExtra(EXTRA_ACCOUNT);
mMultiSelectManager.setAccountId(account.account_id);
mMultiSelectManager.setAccountKey(new AccountKey(account.account_id, account.account_host));
if (mAccountActionProvider != null) {
mAccountActionProvider.setSelectedAccountIds(account.account_id);
}
@ -188,7 +189,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
mode.getMenuInflater().inflate(R.menu.action_multi_select_contents, menu);
mAccountActionProvider = (AccountActionProvider) menu.findItem(R.id.select_account).getActionProvider();
mAccountActionProvider.setSelectedAccountIds(mMultiSelectManager.getFirstSelectAccountId());
mAccountActionProvider.setSelectedAccountIds(mMultiSelectManager.getFirstSelectAccountKey());
return true;
}

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.util;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.AccountKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList;
@ -29,166 +30,170 @@ import java.util.List;
public class MultiSelectManager implements Constants {
private final NoDuplicatesArrayList<Long> mSelectedStatusIds = new NoDuplicatesArrayList<>();
private final NoDuplicatesArrayList<Long> mSelectedUserIds = new NoDuplicatesArrayList<>();
private final NoDuplicatesArrayList<Callback> mCallbacks = new NoDuplicatesArrayList<>();
private final ItemsList mSelectedItems = new ItemsList(this);
private long mAccountId;
private final NoDuplicatesArrayList<Long> mSelectedStatusIds = new NoDuplicatesArrayList<>();
private final NoDuplicatesArrayList<Long> mSelectedUserIds = new NoDuplicatesArrayList<>();
private final NoDuplicatesArrayList<Callback> mCallbacks = new NoDuplicatesArrayList<>();
private final ItemsList mSelectedItems = new ItemsList(this);
private AccountKey mAccountKey;
public void clearSelectedItems() {
mSelectedItems.clear();
}
public void clearSelectedItems() {
mSelectedItems.clear();
}
public long getAccountId() {
if (mAccountId <= 0) return getFirstSelectAccountId(mSelectedItems);
return mAccountId;
}
public AccountKey getAccountKey() {
if (mAccountKey == null) return getFirstSelectAccountKey(mSelectedItems);
return mAccountKey;
}
public int getCount() {
return mSelectedItems.size();
}
public int getCount() {
return mSelectedItems.size();
}
public long getFirstSelectAccountId() {
return getFirstSelectAccountId(mSelectedItems);
}
public AccountKey getFirstSelectAccountKey() {
return getFirstSelectAccountKey(mSelectedItems);
}
public List<Object> getSelectedItems() {
return mSelectedItems;
}
public List<Object> getSelectedItems() {
return mSelectedItems;
}
public boolean isActive() {
return !mSelectedItems.isEmpty();
}
public boolean isActive() {
return !mSelectedItems.isEmpty();
}
public boolean isSelected(final Object object) {
return mSelectedItems.contains(object);
}
public boolean isSelected(final Object object) {
return mSelectedItems.contains(object);
}
public boolean isStatusSelected(final long status_id) {
return mSelectedStatusIds.contains(status_id);
}
public boolean isStatusSelected(final long status_id) {
return mSelectedStatusIds.contains(status_id);
}
public boolean isUserSelected(final long user_id) {
return mSelectedUserIds.contains(user_id);
}
public boolean isUserSelected(final long user_id) {
return mSelectedUserIds.contains(user_id);
}
public void registerCallback(final Callback callback) {
if (callback == null) return;
mCallbacks.add(callback);
}
public void registerCallback(final Callback callback) {
if (callback == null) return;
mCallbacks.add(callback);
}
public boolean selectItem(final Object item) {
return mSelectedItems.add(item);
}
public boolean selectItem(final Object item) {
return mSelectedItems.add(item);
}
public void setAccountId(final long accountId) {
mAccountId = accountId;
}
public void setAccountKey(final AccountKey accountKey) {
mAccountKey = accountKey;
}
public void unregisterCallback(final Callback callback) {
mCallbacks.remove(callback);
}
public void unregisterCallback(final Callback callback) {
mCallbacks.remove(callback);
}
public boolean deselectItem(final Object item) {
return mSelectedItems.remove(item);
}
public boolean deselectItem(final Object item) {
return mSelectedItems.remove(item);
}
private void onItemsCleared() {
for (final Callback callback : mCallbacks) {
callback.onItemsCleared();
}
mAccountId = -1;
}
private void onItemsCleared() {
for (final Callback callback : mCallbacks) {
callback.onItemsCleared();
}
mAccountKey = null;
}
private void onItemSelected(final Object object) {
for (final Callback callback : mCallbacks) {
callback.onItemSelected(object);
}
}
private void onItemSelected(final Object object) {
for (final Callback callback : mCallbacks) {
callback.onItemSelected(object);
}
}
private void onItemUnselected(final Object object) {
for (final Callback callback : mCallbacks) {
callback.onItemUnselected(object);
}
}
private void onItemUnselected(final Object object) {
for (final Callback callback : mCallbacks) {
callback.onItemUnselected(object);
}
}
public static long getFirstSelectAccountId(final List<Object> selected_items) {
final Object obj = selected_items.get(0);
if (obj instanceof ParcelableUser)
return ((ParcelableUser) obj).account_id;
else if (obj instanceof ParcelableStatus) return ((ParcelableStatus) obj).account_id;
return -1;
}
public static AccountKey getFirstSelectAccountKey(final List<Object> selectedItems) {
final Object obj = selectedItems.get(0);
if (obj instanceof ParcelableUser) {
final ParcelableUser user = (ParcelableUser) obj;
return new AccountKey(user.account_id, user.account_host);
} else if (obj instanceof ParcelableStatus) {
final ParcelableStatus status = (ParcelableStatus) obj;
return new AccountKey(status.account_id, status.account_host);
}
return null;
}
public static long[] getSelectedUserIds(final List<Object> selected_items) {
final ArrayList<Long> ids_list = new ArrayList<>();
for (final Object item : selected_items) {
if (item instanceof ParcelableUser) {
ids_list.add(((ParcelableUser) item).id);
} else if (item instanceof ParcelableStatus) {
ids_list.add(((ParcelableStatus) item).user_id);
}
}
return TwidereArrayUtils.fromList(ids_list);
}
public static long[] getSelectedUserIds(final List<Object> selected_items) {
final ArrayList<Long> ids_list = new ArrayList<>();
for (final Object item : selected_items) {
if (item instanceof ParcelableUser) {
ids_list.add(((ParcelableUser) item).id);
} else if (item instanceof ParcelableStatus) {
ids_list.add(((ParcelableStatus) item).user_id);
}
}
return TwidereArrayUtils.fromList(ids_list);
}
public interface Callback {
public interface Callback {
void onItemsCleared();
void onItemsCleared();
void onItemSelected(Object item);
void onItemSelected(Object item);
void onItemUnselected(Object item);
void onItemUnselected(Object item);
}
}
@SuppressWarnings("serial")
static class ItemsList extends NoDuplicatesArrayList<Object> {
@SuppressWarnings("serial")
static class ItemsList extends NoDuplicatesArrayList<Object> {
private final MultiSelectManager manager;
private final MultiSelectManager manager;
ItemsList(final MultiSelectManager manager) {
this.manager = manager;
}
ItemsList(final MultiSelectManager manager) {
this.manager = manager;
}
@Override
public boolean add(final Object object) {
if (object instanceof ParcelableStatus) {
manager.mSelectedStatusIds.add(((ParcelableStatus) object).id);
} else if (object instanceof ParcelableUser) {
manager.mSelectedUserIds.add(((ParcelableUser) object).id);
} else
return false;
final boolean ret = super.add(object);
manager.onItemSelected(object);
return ret;
}
@Override
public boolean add(final Object object) {
if (object instanceof ParcelableStatus) {
manager.mSelectedStatusIds.add(((ParcelableStatus) object).id);
} else if (object instanceof ParcelableUser) {
manager.mSelectedUserIds.add(((ParcelableUser) object).id);
} else
return false;
final boolean ret = super.add(object);
manager.onItemSelected(object);
return ret;
}
@Override
public void clear() {
super.clear();
manager.mSelectedStatusIds.clear();
manager.mSelectedUserIds.clear();
manager.onItemsCleared();
}
@Override
public void clear() {
super.clear();
manager.mSelectedStatusIds.clear();
manager.mSelectedUserIds.clear();
manager.onItemsCleared();
}
@Override
public boolean remove(final Object object) {
final boolean ret = super.remove(object);
if (object instanceof ParcelableStatus) {
manager.mSelectedStatusIds.remove(((ParcelableStatus) object).id);
} else if (object instanceof ParcelableUser) {
manager.mSelectedUserIds.remove(((ParcelableUser) object).id);
}
if (ret) {
if (isEmpty()) {
manager.onItemsCleared();
} else {
manager.onItemUnselected(object);
}
}
return ret;
}
@Override
public boolean remove(final Object object) {
final boolean ret = super.remove(object);
if (object instanceof ParcelableStatus) {
manager.mSelectedStatusIds.remove(((ParcelableStatus) object).id);
} else if (object instanceof ParcelableUser) {
manager.mSelectedUserIds.remove(((ParcelableUser) object).id);
}
if (ret) {
if (isEmpty()) {
manager.onItemsCleared();
} else {
manager.onItemUnselected(object);
}
}
return ret;
}
}
}
}

View File

@ -173,16 +173,23 @@ public class TwidereQueryBuilder {
public static SQLSelectQuery build(final String selection) {
final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder();
qb.select(new Columns(new Column(ConversationEntries._ID), new Column(ConversationEntries.MESSAGE_TIMESTAMP),
new Column(ConversationEntries.MESSAGE_ID), new Column(ConversationEntries.ACCOUNT_ID), new Column(
ConversationEntries.IS_OUTGOING), new Column(ConversationEntries.NAME), new Column(
ConversationEntries.SCREEN_NAME), new Column(ConversationEntries.PROFILE_IMAGE_URL),
new Column(ConversationEntries.TEXT_HTML), new Column(ConversationEntries.CONVERSATION_ID)));
qb.select(new Columns(new Column(ConversationEntries._ID),
new Column(ConversationEntries.MESSAGE_TIMESTAMP),
new Column(ConversationEntries.MESSAGE_ID),
new Column(ConversationEntries.ACCOUNT_ID),
new Column(ConversationEntries.ACCOUNT_HOST),
new Column(ConversationEntries.IS_OUTGOING),
new Column(ConversationEntries.NAME),
new Column(ConversationEntries.SCREEN_NAME),
new Column(ConversationEntries.PROFILE_IMAGE_URL),
new Column(ConversationEntries.TEXT_HTML),
new Column(ConversationEntries.CONVERSATION_ID)));
final SQLSelectQuery.Builder entryIds = new SQLSelectQuery.Builder();
entryIds.select(new Columns(new Column(DirectMessages._ID),
new Column(DirectMessages.MESSAGE_TIMESTAMP),
new Column(DirectMessages.MESSAGE_ID),
new Column(DirectMessages.ACCOUNT_ID),
new Column(DirectMessages.ACCOUNT_HOST),
new Column("0", DirectMessages.IS_OUTGOING),
new Column(DirectMessages.SENDER_NAME, ConversationEntries.NAME),
new Column(DirectMessages.SENDER_SCREEN_NAME, ConversationEntries.SCREEN_NAME),
@ -195,6 +202,7 @@ public class TwidereQueryBuilder {
new Column(DirectMessages.MESSAGE_TIMESTAMP),
new Column(DirectMessages.MESSAGE_ID),
new Column(DirectMessages.ACCOUNT_ID),
new Column(DirectMessages.ACCOUNT_HOST),
new Column("1", DirectMessages.IS_OUTGOING),
new Column(DirectMessages.RECIPIENT_NAME, ConversationEntries.NAME),
new Column(DirectMessages.RECIPIENT_SCREEN_NAME, ConversationEntries.SCREEN_NAME),

View File

@ -1549,20 +1549,6 @@ public final class Utils implements Constants {
return false;
}
public static void initAccountColor(final Context context) {
if (context == null) return;
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{
Accounts.ACCOUNT_ID, Accounts.COLOR}, null, null, null);
if (cur == null) return;
final int id_idx = cur.getColumnIndex(Accounts.ACCOUNT_ID), color_idx = cur.getColumnIndex(Accounts.COLOR);
cur.moveToFirst();
while (!cur.isAfterLast()) {
DataStoreUtils.sAccountColors.put(cur.getLong(id_idx), cur.getInt(color_idx));
cur.moveToNext();
}
cur.close();
}
public static boolean isBatteryOkay(final Context context) {
if (context == null) return false;
final Context app = context.getApplicationContext();
@ -1696,14 +1682,14 @@ public final class Utils implements Constants {
return null;
}
public static void openMessageConversation(final Context context, final long accountId,
public static void openMessageConversation(final Context context, final AccountKey accountKey,
final long recipientId) {
if (context == null) return;
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION);
if (accountId > 0) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
if (recipientId > 0) {
builder.appendQueryParameter(QUERY_PARAM_RECIPIENT_ID, String.valueOf(recipientId));
}
@ -1778,21 +1764,25 @@ public final class Utils implements Constants {
activity.startActivity(intent);
}
public static void openSearch(final Context context, final AccountKey accountKey, final String query) {
public static void openSearch(final Context context, @Nullable final AccountKey accountKey, final String query) {
openSearch(context, accountKey, query, null);
}
public static void openSearch(final Context context, final AccountKey accountId, final String query, String type) {
public static void openSearch(final Context context, @Nullable final AccountKey accountKey, final String query, String type) {
if (context == null) return;
final Intent intent = new Intent(Intent.ACTION_VIEW);
// Some devices cannot process query parameter with hashes well, so add this intent extra
intent.putExtra(EXTRA_QUERY, query);
intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
if (accountKey != null) {
intent.putExtra(EXTRA_ACCOUNT_KEY, accountKey);
}
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_SEARCH);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
builder.appendQueryParameter(QUERY_PARAM_QUERY, query);
if (!TextUtils.isEmpty(type)) {
builder.appendQueryParameter(QUERY_PARAM_TYPE, type);
@ -2647,9 +2637,9 @@ public final class Utils implements Constants {
return isOfficialCredentials(context, account);
}
public static int getNotificationId(int baseId, long accountId) {
public static int getNotificationId(int baseId, @Nullable AccountKey accountId) {
int result = baseId;
result = 31 * result + (int) (accountId ^ (accountId >>> 32));
result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
return result;
}