diff --git a/resources/Twidere Icon Assets.sketch b/resources/Twidere Icon Assets.sketch index 3eebf403c..6c66512ac 100644 Binary files a/resources/Twidere Icon Assets.sketch and b/resources/Twidere Icon Assets.sketch differ diff --git a/twidere.component.common/build.gradle b/twidere.component.common/build.gradle index 7f7d265f1..0cec10085 100644 --- a/twidere.component.common/build.gradle +++ b/twidere.component.common/build.gradle @@ -38,11 +38,11 @@ android { dependencies { apt 'com.bluelinelabs:logansquare-compiler:1.3.4' apt 'com.hannesdorfmann.parcelableplease:processor:1.0.2' - apt 'com.github.mariotaku.ObjectCursor:processor:0.9.5' + apt 'com.github.mariotaku.ObjectCursor:processor:0.9.6-SNAPSHOT' compile 'com.android.support:support-annotations:23.2.0' compile 'com.bluelinelabs:logansquare:1.3.4' compile 'com.github.mariotaku.RestFu:library:0.9.24' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' - compile 'com.github.mariotaku.ObjectCursor:core:0.9.5' + compile 'com.github.mariotaku.ObjectCursor:core:0.9.6-SNAPSHOT' compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index b2944d92b..547c43a50 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -107,6 +107,7 @@ public interface IntentConstants { String EXTRA_URI_ORIG = "uri_orig"; String EXTRA_MENTIONS = "mentions"; String EXTRA_ACCOUNT_ID = "account_id"; + String EXTRA_ACCOUNT_HOST = "account_host"; String EXTRA_ACCOUNT_IDS = "account_ids"; String EXTRA_PAGE = "page"; String EXTRA_DATA = "data"; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java index fb00b1947..a9e291237 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java @@ -300,6 +300,8 @@ public interface SharedPreferenceConstants { String KEY_API_LAST_CHANGE = "api_last_change"; @Preference(type = LONG, exportable = false) String KEY_DEFAULT_ACCOUNT_ID = "default_account_id"; + @Preference(type = STRING, exportable = false) + String KEY_DEFAULT_ACCOUNT_HOST = "default_account_host"; @Preference(type = BOOLEAN, exportable = true, defaultBoolean = true) String KEY_RETRY_ON_NETWORK_ISSUE = "retry_on_network_issue"; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java index 10823be7c..6d723f6b5 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java @@ -38,6 +38,11 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; @JsonObject public class ParcelableAccount implements Parcelable { + @ParcelableThisPlease + @JsonField(name = "id") + @CursorField(value = Accounts._ID, excludeWrite = true) + public long id; + @ParcelableThisPlease @JsonField(name = "screen_name") @CursorField(Accounts.SCREEN_NAME) diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java index c789bc904..8781207bf 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java @@ -63,6 +63,10 @@ public class ParcelableActivity implements Comparable, Parce @CursorField(value = Activities.ACCOUNT_ID) public long account_id; @ParcelableThisPlease + @JsonField(name = "account_host") + @CursorField(value = Activities.ACCOUNT_HOST) + public String account_host; + @ParcelableThisPlease @JsonField(name = "timestamp") @CursorField(value = Activities.TIMESTAMP) public long timestamp; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java index 9a1601367..240d6e6d1 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java @@ -64,6 +64,10 @@ public class ParcelableStatus implements Parcelable, Comparable { @ParcelableThisPlease @JsonField(name = "account_id") public long account_id; + @ParcelableThisPlease + @JsonField(name = "account_host") + public String account_host; @ParcelableThisPlease public int account_color; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java index d8dfedbfe..9785a2ca5 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java @@ -25,53 +25,53 @@ import android.support.annotation.NonNull; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; +import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; -import org.mariotaku.twidere.api.twitter.model.User; -import org.mariotaku.twidere.api.twitter.model.UserList; -import org.mariotaku.twidere.util.TwitterContentUtils; - +@ParcelablePlease @JsonObject public class ParcelableUserList implements Parcelable, Comparable { - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public ParcelableUserList createFromParcel(final Parcel in) { - return new ParcelableUserList(in); - } - - @Override - public ParcelableUserList[] newArray(final int size) { - return new ParcelableUserList[size]; - } - }; - + @ParcelableThisPlease @JsonField(name = "members_count") public long members_count; + @ParcelableThisPlease @JsonField(name = "subscribers_count") public long subscribers_count; - + @ParcelableThisPlease @JsonField(name = "account_id") public long account_id; + @ParcelableThisPlease + @JsonField(name = "account_host") + public String account_host; + @ParcelableThisPlease @JsonField(name = "id") public long id; + @ParcelableThisPlease @JsonField(name = "user_id") public long user_id; + @ParcelableThisPlease @JsonField(name = "position") public long position; - + @ParcelableThisPlease @JsonField(name = "is_public") public boolean is_public; + @ParcelableThisPlease @JsonField(name = "is_following") public boolean is_following; - + @ParcelableThisPlease @JsonField(name = "description") public String description; + @ParcelableThisPlease @JsonField(name = "name") public String name; + @ParcelableThisPlease @JsonField(name = "user_screen_name") public String user_screen_name; + @ParcelableThisPlease @JsonField(name = "user_name") public String user_name; + @ParcelableThisPlease @JsonField(name = "user_profile_image_url") public String user_profile_image_url; @@ -94,42 +94,6 @@ public class ParcelableUserList implements Parcelable, Comparable CREATOR = new Creator() { + public ParcelableUserList createFromParcel(Parcel source) { + ParcelableUserList target = new ParcelableUserList(); + ParcelableUserListParcelablePlease.readFromParcel(target, source); + return target; + } + + public ParcelableUserList[] newArray(int size) { + return new ParcelableUserList[size]; + } + }; } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java index c493ecc4f..2293db2fd 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java @@ -71,7 +71,14 @@ public interface TwidereDataStore { String INSERTED_DATE_TYPE = TYPE_INT; } - interface Accounts extends BaseColumns { + interface AccountSupportColumns { + + String ACCOUNT_ID = "account_id"; + String ACCOUNT_HOST = "account_host"; + + } + + interface Accounts extends BaseColumns, AccountSupportColumns { String TABLE_NAME = "accounts"; String CONTENT_PATH = TABLE_NAME; @@ -85,11 +92,6 @@ public interface TwidereDataStore { String NAME = "name"; - /** - * Unique ID of the account
- * Type: INTEGER (long) - */ - String ACCOUNT_ID = "account_id"; /** * Auth type of the account.
Type: INTEGER @@ -153,8 +155,6 @@ public interface TwidereDataStore { String ACCOUNT_USER = "account_user"; - String ACCOUNT_HOST = "account_host"; - String[] COLUMNS_NO_CREDENTIALS = {_ID, NAME, SCREEN_NAME, ACCOUNT_ID, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, COLOR, IS_ACTIVATED, SORT_POSITION, ACCOUNT_TYPE, ACCOUNT_USER, ACCOUNT_HOST}; @@ -378,14 +378,13 @@ public interface TwidereDataStore { String[] COLUMNS = {_ID, NAME, PATH}; } - interface DirectMessages extends BaseColumns, InsertedDateColumns { + interface DirectMessages extends BaseColumns, InsertedDateColumns, AccountSupportColumns { String TABLE_NAME = "messages"; String CONTENT_PATH = TABLE_NAME; Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH); - String ACCOUNT_ID = "account_id"; String MESSAGE_ID = "message_id"; String MESSAGE_TIMESTAMP = "message_timestamp"; String SENDER_ID = "sender_id"; @@ -523,7 +522,7 @@ public interface TwidereDataStore { String[] COLUMNS = {_ID, HOST, ADDRESS}; } - interface SavedSearches extends BaseColumns { + interface SavedSearches extends BaseColumns, AccountSupportColumns { String TABLE_NAME = "saved_searches"; @@ -531,16 +530,14 @@ public interface TwidereDataStore { Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH); - String ACCOUNT_ID = "account_id"; String SEARCH_ID = "search_id"; String QUERY = "query"; String NAME = "name"; String CREATED_AT = "created_at"; - String[] COLUMNS = {_ID, ACCOUNT_ID, SEARCH_ID, CREATED_AT, - QUERY, NAME}; - String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT, - TYPE_INT, TYPE_TEXT, TYPE_TEXT}; + String[] COLUMNS = {_ID, ACCOUNT_ID, ACCOUNT_HOST, SEARCH_ID, CREATED_AT, QUERY, NAME}; + String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_TEXT, + TYPE_TEXT}; String DEFAULT_SORT_ORDER = CREATED_AT + " DESC"; } @@ -721,17 +718,12 @@ public interface TwidereDataStore { String[] COLUMNS = {_ID, KEY, VALUE, TYPE}; } - interface Statuses extends BaseColumns, InsertedDateColumns { + interface Statuses extends BaseColumns, InsertedDateColumns, AccountSupportColumns { String TABLE_NAME = "statuses"; String CONTENT_PATH = TABLE_NAME; Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH); - /** - * Account ID of the status.
- * Type: TEXT - */ - String ACCOUNT_ID = "account_id"; /** * Status content, in HTML. Please note, this is not actually original @@ -880,8 +872,8 @@ public interface TwidereDataStore { String EXTRAS = "extras"; - String[] COLUMNS = {_ID, ACCOUNT_ID, STATUS_ID, USER_ID, - STATUS_TIMESTAMP, TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED, USER_NAME, USER_SCREEN_NAME, + String[] COLUMNS = {_ID, ACCOUNT_ID, ACCOUNT_HOST, STATUS_ID, USER_ID, STATUS_TIMESTAMP, + TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED, USER_NAME, USER_SCREEN_NAME, USER_PROFILE_IMAGE_URL, IN_REPLY_TO_STATUS_ID, IN_REPLY_TO_USER_ID, IN_REPLY_TO_USER_NAME, IN_REPLY_TO_USER_SCREEN_NAME, SOURCE, LOCATION, RETWEET_COUNT, FAVORITE_COUNT, REPLY_COUNT, RETWEET_ID, RETWEET_TIMESTAMP, RETWEETED_BY_USER_ID, RETWEETED_BY_USER_NAME, @@ -894,8 +886,8 @@ public interface TwidereDataStore { PLACE_FULL_NAME, LANG, RETWEETED, QUOTED_LOCATION, QUOTED_PLACE_FULL_NAME, INSERTED_DATE, EXTRAS}; - String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT, - TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, + String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, + TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_TEXT, TYPE_INT, @@ -907,9 +899,8 @@ public interface TwidereDataStore { } - interface Activities extends BaseColumns, InsertedDateColumns { + interface Activities extends BaseColumns, InsertedDateColumns, AccountSupportColumns { - String ACCOUNT_ID = "account_id"; String ACTION = "action"; String TIMESTAMP = "timestamp"; String STATUS_ID = "status_id"; @@ -936,13 +927,13 @@ public interface TwidereDataStore { String TARGET_OBJECT_USER_LISTS = "target_object_user_lists"; String TARGET_OBJECT_USERS = "target_object_users"; - String[] COLUMNS = {_ID, ACCOUNT_ID, ACTION, TIMESTAMP, STATUS_ID, STATUS_USER_ID, + String[] COLUMNS = {_ID, ACCOUNT_ID, ACCOUNT_HOST, ACTION, TIMESTAMP, STATUS_ID, STATUS_USER_ID, STATUS_RETWEETED_BY_USER_ID, STATUS_QUOTED_USER_ID, STATUS_SOURCE, STATUS_QUOTE_SOURCE, STATUS_TEXT_PLAIN, STATUS_QUOTE_TEXT_PLAIN, STATUS_TEXT_HTML, STATUS_QUOTE_TEXT_HTML, IS_GAP, MIN_POSITION, MAX_POSITION, SOURCES, SOURCE_IDS, TARGET_STATUSES, TARGET_USERS, TARGET_USER_LISTS, TARGET_OBJECT_STATUSES, TARGET_OBJECT_USER_LISTS, TARGET_OBJECT_USERS, STATUS_RETWEET_ID, STATUS_USER_FOLLOWING, INSERTED_DATE}; - String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, + String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_BOOLEAN, INSERTED_DATE_TYPE}; @@ -993,14 +984,13 @@ public interface TwidereDataStore { String DEFAULT_SORT_ORDER = POSITION + " ASC"; } - interface CachedRelationships extends BaseColumns { + interface CachedRelationships extends BaseColumns, AccountSupportColumns { String TABLE_NAME = "cached_relationships"; String CONTENT_PATH = TABLE_NAME; Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH); - String ACCOUNT_ID = "account_id"; String USER_ID = "user_id"; @@ -1016,14 +1006,15 @@ public interface TwidereDataStore { String RETWEET_ENABLED = "retweet_enabled"; - String[] COLUMNS = {_ID, ACCOUNT_ID, USER_ID, FOLLOWING, FOLLOWED_BY, BLOCKING, + String[] COLUMNS = {_ID, ACCOUNT_ID, ACCOUNT_HOST, USER_ID, FOLLOWING, FOLLOWED_BY, BLOCKING, BLOCKED_BY, MUTING, RETWEET_ENABLED}; - String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT, TYPE_BOOLEAN_DEFAULT_FALSE, + String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_TEXT, TYPE_INT, TYPE_BOOLEAN_DEFAULT_FALSE, TYPE_BOOLEAN_DEFAULT_FALSE, TYPE_BOOLEAN_DEFAULT_FALSE, TYPE_BOOLEAN_DEFAULT_FALSE, TYPE_BOOLEAN_DEFAULT_FALSE, TYPE_BOOLEAN_DEFAULT_TRUE}; } + interface UnreadCounts extends BaseColumns { String CONTENT_PATH = "unread_counts"; diff --git a/twidere/build.gradle b/twidere/build.gradle index 4987559c7..ccacd4d51 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -25,15 +25,21 @@ android { versionName "3.0.6.5" multiDexEnabled true + generatedDensities = [] + buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("false")' buildConfigField 'boolean', 'SHOW_CUSTOM_TOKEN_DIALOG', 'Boolean.parseBoolean("false")' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + aaptOptions { + additionalParameters "--no-version-vectors" + } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } + productFlavors { google {} fdroid {} @@ -72,7 +78,7 @@ dependencies { androidTestApt 'com.bluelinelabs:logansquare-compiler:1.3.4' apt 'com.hannesdorfmann.parcelableplease:processor:1.0.2' apt 'com.google.dagger:dagger-compiler:2.0.2' - apt "com.github.mariotaku.ObjectCursor:processor:0.9.5" + apt "com.github.mariotaku.ObjectCursor:processor:0.9.6-SNAPSHOT" compile 'com.android.support:multidex:1.0.1' compile 'com.android.support:support-v13:23.2.0' @@ -111,7 +117,7 @@ dependencies { compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.12' compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.12' compile 'com.github.mariotaku.SQLiteQB:library:0.9.5' - compile 'com.github.mariotaku.ObjectCursor:core:0.9.5' + compile 'com.github.mariotaku.ObjectCursor:core:0.9.6-SNAPSHOT' compile project(':twidere.component.common') compile project(':twidere.component.nyan') diff --git a/twidere/src/main/java/edu/tsinghua/hotmobi/model/SessionEvent.java b/twidere/src/main/java/edu/tsinghua/hotmobi/model/SessionEvent.java index 76c6fd82e..bf2beb27b 100644 --- a/twidere/src/main/java/edu/tsinghua/hotmobi/model/SessionEvent.java +++ b/twidere/src/main/java/edu/tsinghua/hotmobi/model/SessionEvent.java @@ -32,6 +32,7 @@ import com.bluelinelabs.logansquare.annotation.JsonObject; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.AccountPreferences; import org.mariotaku.twidere.util.DataStoreUtils; @@ -97,7 +98,7 @@ public class SessionEvent extends BaseEvent implements Parcelable { public void dumpPreferences(Context context) { final HashMap preferences = new HashMap<>(); for (AccountPreferences pref : AccountPreferences.getAccountPreferences(context, DataStoreUtils.getAccountIds(context))) { - final long accountId = pref.getAccountId(); + final AccountId accountId = pref.getAccountId(); preferences.put("notification_" + accountId + "_home", String.valueOf(pref.isHomeTimelineNotificationEnabled())); preferences.put("notification_" + accountId + "_interactions", String.valueOf(pref.isInteractionsNotificationEnabled())); } diff --git a/twidere/src/main/java/edu/tsinghua/hotmobi/model/UserEvent.java b/twidere/src/main/java/edu/tsinghua/hotmobi/model/UserEvent.java index 3eb3f6674..3b7843090 100644 --- a/twidere/src/main/java/edu/tsinghua/hotmobi/model/UserEvent.java +++ b/twidere/src/main/java/edu/tsinghua/hotmobi/model/UserEvent.java @@ -5,13 +5,13 @@ import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.annotation.StringDef; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; +import org.mariotaku.twidere.fragment.support.UserFragment; import org.mariotaku.twidere.model.ParcelableUser; /** @@ -38,7 +38,7 @@ public class UserEvent extends BaseEvent implements Parcelable { long friendCount; @ParcelableThisPlease @JsonField(name = "referral") - @Referral + @UserFragment.Referral @Nullable String referral; public static final Creator CREATOR = new Creator() { @@ -53,7 +53,7 @@ public class UserEvent extends BaseEvent implements Parcelable { } }; - public static UserEvent create(Context context, @Referral @Nullable String referral) { + public static UserEvent create(Context context, @UserFragment.Referral @Nullable String referral) { UserEvent event = new UserEvent(); event.markStart(context); event.referral = referral; @@ -96,15 +96,4 @@ public class UserEvent extends BaseEvent implements Parcelable { "} " + super.toString(); } - @StringDef({Referral.SEARCH_RESULT, Referral.USER_MENTION, Referral.TWEET, - Referral.TIMELINE_TWEET, Referral.DIRECT, Referral.EXTERNAL}) - public @interface Referral { - - String SEARCH_RESULT = "search_result"; - String USER_MENTION = "user_mention"; - String TWEET = "tweet"; - String TIMELINE_TWEET = "timeline_tweet"; - String DIRECT = "direct"; - String EXTERNAL = "external"; - } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/Constants.java b/twidere/src/main/java/org/mariotaku/twidere/Constants.java index b2564cef3..52a6e71db 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/Constants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/Constants.java @@ -33,7 +33,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING; public interface Constants extends TwidereConstants { String DATABASES_NAME = "twidere.sqlite"; - int DATABASES_VERSION = 128; + int DATABASES_VERSION = 129; int MENU_GROUP_STATUS_EXTENSION = 10; int MENU_GROUP_COMPOSE_EXTENSION = 11; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java index 26304560f..e0759f172 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java @@ -95,6 +95,7 @@ import com.github.johnpersano.supertoasts.SuperToast.OnDismissListener; import com.nostra13.universalimageloader.utils.IoUtils; import com.twitter.Extractor; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ObjectUtils; import org.mariotaku.restfu.RestFuUtils; import org.mariotaku.twidere.BuildConfig; @@ -103,6 +104,7 @@ import org.mariotaku.twidere.adapter.ArrayRecyclerAdapter; import org.mariotaku.twidere.adapter.BaseRecyclerViewAdapter; import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment; import org.mariotaku.twidere.fragment.support.SupportProgressDialogFragment; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ConsumerKeyType; import org.mariotaku.twidere.model.Draft; import org.mariotaku.twidere.model.DraftValuesCreator; @@ -115,6 +117,7 @@ import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatusUpdate; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.draft.UpdateStatusActionExtra; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; import org.mariotaku.twidere.preference.ServicePickerPreference; import org.mariotaku.twidere.provider.TwidereDataStore.Drafts; import org.mariotaku.twidere.service.BackgroundOperationService; @@ -1130,7 +1133,11 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte private void notifyAccountSelectionChanged() { final ParcelableCredentials[] accounts = mAccountsAdapter.getSelectedAccounts(); setSelectedAccounts(accounts); - mEditText.setAccountId(accounts.length > 0 ? accounts[0].account_id : Utils.getDefaultAccountId(this)); + if (ArrayUtils.isEmpty(accounts)) { + mEditText.setAccountId(Utils.getDefaultAccountId(this)); + } else { + mEditText.setAccountId(new AccountId(accounts[0])); + } mSendTextCountView.setMaxLength(TwidereValidator.getTextLimit(accounts)); setMenu(); // mAccountActionProvider.setSelectedAccounts(mAccountsAdapter.getSelectedAccounts()); @@ -1331,7 +1338,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte } else { action = getDraftAction(getIntent().getAction()); } - update.accounts = DataStoreUtils.getAccounts(this, accountIds); + update.accounts = ParcelableAccountUtils.getAccounts(this, accountIds); update.text = text; update.location = statusLocation; update.media = getMedia(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java index dc4f60ad1..922b7b095 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java @@ -55,6 +55,7 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; +import org.mariotaku.twidere.fragment.support.UserFragment; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory; import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions; @@ -170,12 +171,13 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On switch (mUsersSearchAdapter.getItemViewType(position)) { case SuggestionsAdapter.VIEW_TYPE_USER_SUGGESTION_ITEM: { IntentUtils.openUserProfile(this, getAccountId(), item.extra_id, item.summary, null, - true); + true, UserFragment.Referral.DIRECT); finish(); break; } case SuggestionsAdapter.VIEW_TYPE_USER_SCREEN_NAME: { - IntentUtils.openUserProfile(this, getAccountId(), -1, item.title, null, true); + IntentUtils.openUserProfile(this, getAccountId(), -1, item.title, null, true, + UserFragment.Referral.DIRECT); finish(); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/UserListSelectorActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/UserListSelectorActivity.java index ad4944268..800506c88 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/UserListSelectorActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/UserListSelectorActivity.java @@ -289,7 +289,7 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen @Override protected SingleResponse> doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, accountHost, false); if (twitter == null) return SingleResponse.getInstance(); try { final ResponseList lists = twitter.getUserLists(mScreenName, true); @@ -351,7 +351,7 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen @Override protected SingleResponse> doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, accountHost, false); if (twitter == null) return SingleResponse.getInstance(); try { final Paging paging = new Paging(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java index ecb2b92f8..d86ac583b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java @@ -35,6 +35,7 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IActivitiesAdapter; import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.fragment.support.CursorActivitiesFragment; +import org.mariotaku.twidere.fragment.support.UserFragment; import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; @@ -438,7 +439,7 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter< final ParcelableStatus status = ParcelableActivity.getActivityStatus(activity); assert status != null; IntentUtils.openUserProfile(context, status.account_id, status.user_id, - status.user_screen_name, null, true); + status.user_screen_name, null, true, UserFragment.Referral.TIMELINE_STATUS); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.java index 83fa8b76a..19da35e9a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.java @@ -32,6 +32,7 @@ import android.widget.TextView; import org.apache.commons.lang3.StringUtils; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.SharedPreferencesWrapper; @@ -57,7 +58,7 @@ public class ComposeAutoCompleteAdapter extends SimpleCursorAdapter implements C private final boolean mDisplayProfileImage; private int mTypeIdx, mIconIdx, mTitleIdx, mSummaryIdx, mExtraIdIdx, mValueIdx; - private long mAccountId; + private AccountId mAccountId; private char mToken; public ComposeAutoCompleteAdapter(final Context context) { @@ -142,13 +143,13 @@ public class ComposeAutoCompleteAdapter extends SimpleCursorAdapter implements C return null; } } - builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(mAccountId)); + builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(mAccountId.getId())); return mContext.getContentResolver().query(builder.build(), Suggestions.AutoComplete.COLUMNS, null, null, null); } - public void setAccountId(long accountId) { + public void setAccountId(AccountId accountId) { mAccountId = accountId; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.java index ddd24aaf9..a3a66362a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.java @@ -155,7 +155,7 @@ public class NetworkDiagnosticsFragment extends BaseFragment { for (long accountId : DataStoreUtils.getAccountIds(mContext)) { final ParcelableCredentials credentials = DataStoreUtils.getCredentials(mContext, accountId); - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, accountHost, false); if (credentials == null || twitter == null) continue; publishProgress(new LogText("Testing connection for account " + accountId)); publishProgress(LogText.LINEBREAK); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java index 55184f2d0..54d09275d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsActivitiesFragment.java @@ -47,6 +47,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi import org.mariotaku.twidere.annotation.ReadPositionTag; import org.mariotaku.twidere.fragment.support.AbsStatusesFragment.DefaultOnLikedListener; import org.mariotaku.twidere.loader.iface.IExtendedLoader; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; @@ -187,7 +188,8 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecycler case ACTION_STATUS_FAVORITE: { final AsyncTwitterWrapper twitter = mTwitterWrapper; if (status.is_favorite) { - twitter.destroyFavoriteAsync(activity.account_id, status.id); + twitter.destroyFavoriteAsync(new AccountId(activity.account_id, + activity.account_host), status.id); } else { final IStatusViewHolder holder = (IStatusViewHolder) recyclerView.findViewHolderForLayoutPosition(position); @@ -378,7 +380,8 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecycler final AsyncTwitterWrapper twitter = mTwitterWrapper; if (twitter == null) return; if (status.is_favorite) { - twitter.destroyFavoriteAsync(status.account_id, status.id); + twitter.destroyFavoriteAsync(new AccountId(status.account_id, + status.account_host), status.id); } else { holder.playLikeAnimation(new DefaultOnLikedListener(twitter, status)); } @@ -501,7 +504,7 @@ public abstract class AbsActivitiesFragment extends AbsContentListRecycler return new StatusesBusCallback(); } - protected abstract long[] getAccountIds(); + protected abstract AccountId[] getAccountIds(); protected Data getAdapterData() { final AbsActivitiesAdapter adapter = getAdapter(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java index 83086da42..e64bbdfe1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java @@ -47,6 +47,7 @@ import org.mariotaku.twidere.adapter.iface.IStatusesAdapter.StatusAdapterListene import org.mariotaku.twidere.annotation.ReadPositionTag; import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable; import org.mariotaku.twidere.loader.iface.IExtendedLoader; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.message.StatusListChangedEvent; @@ -184,7 +185,8 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi case ACTION_STATUS_FAVORITE: { final AsyncTwitterWrapper twitter = mTwitterWrapper; if (status.is_favorite) { - twitter.destroyFavoriteAsync(status.account_id, status.id); + twitter.destroyFavoriteAsync(new AccountId(status.account_id, + status.account_host), status.id); } else { final IStatusViewHolder holder = (IStatusViewHolder) recyclerView.findViewHolderForLayoutPosition(position); @@ -367,7 +369,8 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi final AsyncTwitterWrapper twitter = mTwitterWrapper; if (twitter == null) return; if (status.is_favorite) { - twitter.destroyFavoriteAsync(status.account_id, status.id); + twitter.destroyFavoriteAsync(new AccountId(status.account_id, + status.account_host), status.id); } else { holder.playLikeAnimation(new DefaultOnLikedListener(twitter, status)); } @@ -401,7 +404,7 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi public void onUserProfileClick(IStatusViewHolder holder, ParcelableStatus status, int position) { final FragmentActivity activity = getActivity(); IntentUtils.openUserProfile(activity, status.account_id, status.user_id, - status.user_screen_name, null, true); + status.user_screen_name, null, true, UserFragment.Referral.TIMELINE_STATUS); } @Override @@ -588,8 +591,10 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi @Override public boolean onLiked() { - if (mStatus.is_favorite) return false; - mTwitter.createFavoriteAsync(mStatus.account_id, mStatus.id); + final ParcelableStatus status = mStatus; + if (status.is_favorite) return false; + mTwitter.createFavoriteAsync(new AccountId(status.account_id, status.account_host), + status.id); return true; } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java index b655ac1d6..390dfa6d0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java @@ -31,8 +31,8 @@ import android.support.v7.widget.RecyclerView; import android.view.KeyEvent; import org.mariotaku.twidere.adapter.AbsUsersAdapter; -import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserAdapterListener; import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition; +import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserAdapterListener; import org.mariotaku.twidere.loader.iface.IExtendedLoader; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.util.IntentUtils; @@ -112,7 +112,13 @@ abstract class AbsUsersFragment extends AbsContentListRecyclerViewFragment public void onUserClick(UserViewHolder holder, int position) { final ParcelableUser user = getAdapter().getUser(position); final FragmentActivity activity = getActivity(); - IntentUtils.openUserProfile(activity, user.account_id, user.id, user.screen_name, null, true); + IntentUtils.openUserProfile(activity, user.account_id, user.id, user.screen_name, null, + true, getUserReferral()); + } + + @UserFragment.Referral + protected String getUserReferral() { + return null; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java index e04b9d1d3..317b63c47 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java @@ -89,6 +89,7 @@ import org.mariotaku.twidere.annotation.CustomTabType; import org.mariotaku.twidere.menu.support.AccountToggleProvider; import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.SupportTabSpec; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; import org.mariotaku.twidere.util.CompareUtils; import org.mariotaku.twidere.util.DataStoreUtils; @@ -247,7 +248,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo if (account == null) return; final FragmentActivity activity = getActivity(); IntentUtils.openUserProfile(activity, account.account_id, account.account_id, - account.screen_name, null, true); + account.screen_name, null, true, UserFragment.Referral.SELF_PROFILE); break; } } @@ -267,7 +268,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo if (cursor == null) return; final Menu menu = mAccountsToggleMenu.getMenu(); mAccountActionProvider = (AccountToggleProvider) MenuItemCompat.getActionProvider(menu.findItem(R.id.select_account)); - final ParcelableAccount[] accounts = DataStoreUtils.getAccounts(cursor); + final ParcelableAccount[] accounts = ParcelableAccountUtils.getAccounts(cursor); if (accounts.length > 0) { mNoAccountContainer.setVisibility(View.GONE); mAccountProfileContainer.setVisibility(View.VISIBLE); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java index 21baef5f7..fd06a694d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java @@ -149,7 +149,7 @@ public class AccountsManagerFragment extends BaseSupportFragment implements Load public void onItemClick(AdapterView parent, View view, int position, long id) { final ParcelableAccount account = mAdapter.getAccount(position); IntentUtils.openUserProfile(getActivity(), account.account_id, account.account_id, account.screen_name, - null, true); + null, true, UserFragment.Referral.SELF_PROFILE); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyStatusDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyStatusDialogFragment.java index 5a5cfc4f8..7f184f98f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyStatusDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DestroyStatusDialogFragment.java @@ -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.AccountId; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.ThemeUtils; @@ -43,7 +44,8 @@ public class DestroyStatusDialogFragment extends BaseSupportDialogFragment imple final ParcelableStatus status = getStatus(); final AsyncTwitterWrapper twitter = mTwitterWrapper; if (status == null || twitter == null) return; - twitter.destroyStatusAsync(status.account_id, status.id); + twitter.destroyStatusAsync(new AccountId(status.account_id, status.account_host), + status.id); break; default: break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java index 8dfb5bd81..6ae865bf2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java @@ -198,7 +198,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment onCreateLoader(int id, Bundle args) { final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1); + final String accountHost = args.getString(EXTRA_ACCOUNT_HOST); final long statusId = args.getLong(EXTRA_STATUS_ID, -1); - return new StatusActivitySummaryLoader(getActivity(), accountId, statusId); + return new StatusActivitySummaryLoader(getActivity(), accountId, accountHost, statusId); } @Override @@ -460,7 +461,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac public void onUserProfileClick(IStatusViewHolder holder, ParcelableStatus status, int position) { final FragmentActivity activity = getActivity(); IntentUtils.openUserProfile(activity, status.account_id, status.user_id, - status.user_screen_name, null, true); + status.user_screen_name, null, true, UserFragment.Referral.TIMELINE_STATUS); } @Override @@ -815,7 +816,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac } private void onUserClick(ParcelableUser user) { - IntentUtils.openUserProfile(getContext(), user, null, true); + IntentUtils.openUserProfile(getContext(), user, null, true, + UserFragment.Referral.TIMELINE_STATUS); } public static final class LoadSensitiveImageConfirmDialogFragment extends BaseSupportDialogFragment implements @@ -863,7 +865,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac protected SingleResponse doInBackground(ParcelableStatus... params) { final ParcelableStatus status = params[0]; final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, status.account_id, - true); + accountHost, true); final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); if (twitter == null) return SingleResponse.getInstance(); @@ -1195,13 +1197,14 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac case R.id.profile_container: { final FragmentActivity activity = fragment.getActivity(); IntentUtils.openUserProfile(activity, status.account_id, status.user_id, - status.user_screen_name, null, true); + status.user_screen_name, null, true, UserFragment.Referral.STATUS); break; } case R.id.retweeted_by: { if (status.retweet_id > 0) { - IntentUtils.openUserProfile(adapter.getContext(), status.account_id, status.retweeted_by_user_id, - status.retweeted_by_user_screen_name, null, true); + IntentUtils.openUserProfile(adapter.getContext(), status.account_id, + status.retweeted_by_user_id, status.retweeted_by_user_screen_name, + null, true, UserFragment.Referral.STATUS); } break; } @@ -1212,8 +1215,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac break; } case R.id.quoted_name_container: { - IntentUtils.openUserProfile(adapter.getContext(), status.account_id, status.quoted_user_id, - status.quoted_user_screen_name, null, true); + IntentUtils.openUserProfile(adapter.getContext(), status.account_id, + status.quoted_user_id, status.quoted_user_screen_name, null, true, + UserFragment.Referral.STATUS); break; } case R.id.quote_original_link: { @@ -2413,18 +2417,21 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac public static class StatusActivitySummaryLoader extends AsyncTaskLoader { private final long mAccountId; + private final String mAccountHost; private final long mStatusId; - public StatusActivitySummaryLoader(Context context, long accountId, long statusId) { + public StatusActivitySummaryLoader(Context context, long accountId, String accountHost, + long statusId) { super(context); mAccountId = accountId; + mAccountHost = accountHost; mStatusId = statusId; } @Override public StatusActivity loadInBackground() { final Context context = getContext(); - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, mAccountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, mAccountId, accountHost, false); final Paging paging = new Paging(); paging.setCount(10); final StatusActivity activitySummary = new StatusActivity(mStatusId); @@ -2458,7 +2465,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac Expression.equals(Activities.STATUS_RETWEET_ID, mStatusId) ); - final ParcelableStatus pStatus = ParcelableStatusUtils.fromStatus(status, mAccountId, false); + final ParcelableStatus pStatus = ParcelableStatusUtils.fromStatus(status, mAccountId, + mAccountHost, false); cr.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(pStatus)); final Cursor activityCursor = cr.query(Activities.AboutMe.CONTENT_URI, diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java index 81e546d61..b10f81462 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java @@ -43,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.StringDef; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; @@ -697,8 +698,10 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener if (resultCode == Activity.RESULT_OK) { if (data == null || !data.hasExtra(EXTRA_ID)) return; final long accountId = data.getLongExtra(EXTRA_ID, -1); + @Referral + final String referral = getArguments().getString(EXTRA_REFERRAL); IntentUtils.openUserProfile(getActivity(), accountId, user.id, user.screen_name, - null, true); + null, true, referral); } break; } @@ -840,7 +843,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener super.onStart(); mBus.register(this); - @UserEvent.Referral + @Referral final String referral = getArguments().getString(EXTRA_REFERRAL); final Context context = getContext(); if (mUserEvent == null) { @@ -1349,7 +1352,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener if (user == null) return; switch (type) { case TwidereLinkify.LINK_TYPE_MENTION: { - IntentUtils.openUserProfile(getActivity(), user.account_id, -1, link, null, true); + IntentUtils.openUserProfile(getActivity(), user.account_id, -1, link, null, + true, Referral.USER_MENTION); break; } case TwidereLinkify.LINK_TYPE_HASHTAG: { @@ -1670,6 +1674,19 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } } + @StringDef({Referral.SEARCH_RESULT, Referral.USER_MENTION, Referral.STATUS, + Referral.TIMELINE_STATUS, Referral.DIRECT, Referral.EXTERNAL, Referral.SELF_PROFILE}) + public @interface Referral { + + String SEARCH_RESULT = "search_result"; + String USER_MENTION = "user_mention"; + String STATUS = "status"; + String TIMELINE_STATUS = "timeline_status"; + String DIRECT = "direct"; + String EXTERNAL = "external"; + String SELF_PROFILE = "self_profile"; + } + private static class ActionBarDrawable extends LayerDrawable { private final Drawable mShadowDrawable; @@ -1752,7 +1769,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final boolean isFiltering = DataStoreUtils.isFilteringUser(context, userId); if (accountId == userId) return SingleResponse.getInstance(); - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, accountHost, false); if (twitter == null) return SingleResponse.getInstance(); try { final Relationship relationship = twitter.showFriendship(userId); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java index 123f250f4..0e9d19588 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java @@ -68,9 +68,11 @@ import org.mariotaku.twidere.api.twitter.model.UserListUpdate; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; import org.mariotaku.twidere.graphic.EmptyDrawable; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUserList; import org.mariotaku.twidere.model.SingleResponse; +import org.mariotaku.twidere.model.util.ParcelableUserListUtils; import org.mariotaku.twidere.text.validator.UserListNameValidator; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.IntentUtils; @@ -348,9 +350,10 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList break; } case R.id.profile_image: { - if (mUserList == null) return; - IntentUtils.openUserProfile(getActivity(), mUserList.account_id, - mUserList.user_id, mUserList.user_screen_name, null, true); + final ParcelableUserList userList = mUserList; + if (userList == null) return; + IntentUtils.openUserProfile(getActivity(), userList.account_id, userList.user_id, + userList.user_screen_name, null, true, null); break; } } @@ -360,12 +363,12 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList @Override public Loader> onCreateLoader(final int id, final Bundle args) { setProgressBarIndeterminateVisibility(true); - final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1; - final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1; - final long listId = args != null ? args.getLong(EXTRA_LIST_ID, -1) : -1; - final String listName = args != null ? args.getString(EXTRA_LIST_NAME) : null; - final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null; - final boolean omitIntentExtra = args == null || args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true); + final AccountId accountId = args.getParcelable(EXTRA_ACCOUNT_ID); + final long userId = args.getLong(EXTRA_USER_ID, -1); + final long listId = args.getLong(EXTRA_LIST_ID, -1); + final String listName = args.getString(EXTRA_LIST_NAME); + final String screenName = args.getString(EXTRA_SCREEN_NAME); + final boolean omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true); return new ParcelableUserListLoader(getActivity(), omitIntentExtra, getArguments(), accountId, listId, listName, userId, screenName); } @@ -434,13 +437,12 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList DialogInterface.OnClickListener { private String mName, mDescription; - private long mAccountId; + private AccountId mAccountId; private long mListId; private boolean mIsPublic; @Override public void onClick(final DialogInterface dialog, final int which) { - if (mAccountId <= 0) return; switch (which) { case DialogInterface.BUTTON_POSITIVE: { final AlertDialog alertDialog = (AlertDialog) dialog; @@ -466,7 +468,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList @Override public Dialog onCreateDialog(final Bundle savedInstanceState) { final Bundle bundle = savedInstanceState == null ? getArguments() : savedInstanceState; - mAccountId = bundle != null ? bundle.getLong(EXTRA_ACCOUNT_ID, -1) : -1; + mAccountId = bundle != null ? bundle.getParcelable(EXTRA_ACCOUNT_ID) : null; mListId = bundle != null ? bundle.getLong(EXTRA_LIST_ID, -1) : -1; mName = bundle != null ? bundle.getString(EXTRA_LIST_NAME) : null; mDescription = bundle != null ? bundle.getString(EXTRA_DESCRIPTION) : null; @@ -502,7 +504,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList @Override public void onSaveInstanceState(final Bundle outState) { - outState.putLong(EXTRA_ACCOUNT_ID, mAccountId); + outState.putParcelable(EXTRA_ACCOUNT_ID, mAccountId); outState.putLong(EXTRA_LIST_ID, mListId); outState.putString(EXTRA_LIST_NAME, mName); outState.putString(EXTRA_DESCRIPTION, mDescription); @@ -516,12 +518,13 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList private final boolean mOmitIntentExtra; private final Bundle mExtras; - private final long mAccountId, mUserId; + private final AccountId mAccountId; + private final long mUserId; private final long mListId; private final String mScreenName, mListName; private ParcelableUserListLoader(final Context context, final boolean omitIntentExtra, final Bundle extras, - final long accountId, final long listId, final String listName, final long userId, + final AccountId accountId, final long listId, final String listName, final long userId, final String screenName) { super(context); mOmitIntentExtra = omitIntentExtra; @@ -539,7 +542,8 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList final ParcelableUserList cache = mExtras.getParcelable(EXTRA_USER_LIST); if (cache != null) return SingleResponse.getInstance(cache); } - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, + true); if (twitter == null) return SingleResponse.getInstance(); try { final UserList list; @@ -551,7 +555,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList list = twitter.showUserList(mListName, mScreenName); } else return SingleResponse.getInstance(); - return SingleResponse.getInstance(new ParcelableUserList(list, mAccountId)); + return SingleResponse.getInstance(ParcelableUserListUtils.from(list, mAccountId)); } catch (final TwitterException e) { return SingleResponse.getInstance(e); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java index 34b95f58b..4e8c54959 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java @@ -124,7 +124,7 @@ public class UserListMembersFragment extends CursorSupportUsersListFragment { @Override @NonNull protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getActivity(), accountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getActivity(), accountId, accountHost, true); if (twitter == null) return SingleResponse.getInstance(); try { final UserList list; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java index d29abc4e6..18e2794fd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java @@ -448,7 +448,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On @Override protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, mAccountId, accountHost, true); try { User user = null; if (isProfileChanged()) { @@ -547,7 +547,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On public UpdateProfileBannerImageTaskInternal(final Context context, final AsyncTaskManager manager, final long account_id, final Uri image_uri, final boolean delete_image) { - super(context, manager, account_id, image_uri, delete_image); + super(context, account_id, accountHost, image_uri, delete_image); } @Override @@ -569,7 +569,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On public UpdateProfileImageTaskInternal(final Context context, final AsyncTaskManager manager, final long account_id, final Uri image_uri, final boolean delete_image) { - super(context, account_id, image_uri, delete_image); + super(context, account_id, accountHost, image_uri, delete_image); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java index 4c7898dcd..2238e2ce4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/card/CardPollFragment.java @@ -175,7 +175,7 @@ public class CardPollFragment extends BaseSupportFragment implements @Override public ParcelableCardEntity doLongOperation(CardDataMap cardDataMap) { final TwitterCaps caps = TwitterAPIFactory.getTwitterInstance(getContext(), - card.account_id, true, true, TwitterCaps.class); + card.account_id, accountHost, true, true, TwitterCaps.class); if (caps == null) return null; try { final CardEntity cardEntity = caps.sendPassThrough(cardDataMap).getCard(); @@ -339,7 +339,7 @@ public class CardPollFragment extends BaseSupportFragment implements @Override public ParcelableCardEntity loadInBackground() { final TwitterCaps caps = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, - true, true, TwitterCaps.class); + accountHost, true, true, TwitterCaps.class); if (caps == null) return null; try { final CardDataMap params = new CardDataMap(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseUserListsLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseUserListsLoader.java index e04de9922..55726197b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseUserListsLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/BaseUserListsLoader.java @@ -76,7 +76,7 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader loadInBackground() { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, accountHost, true); List listLoaded = null; try { listLoaded = getUserLists(twitter); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableStatusLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableStatusLoader.java index 7919d1aca..a9d97183b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableStatusLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableStatusLoader.java @@ -64,7 +64,7 @@ public class ParcelableStatusLoader extends AsyncTaskLoader response = SingleResponse.getInstance(status); final Bundle extras = response.getExtras(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java index 0bb3ed9e0..e3a959cce 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java @@ -39,7 +39,6 @@ import org.mariotaku.twidere.model.SingleResponse; import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers; -import org.mariotaku.twidere.util.ContentValuesCreator; import org.mariotaku.twidere.util.DataStoreUtils; import org.mariotaku.twidere.util.JsonSerializer; import org.mariotaku.twidere.util.TwitterAPIFactory; @@ -81,7 +80,7 @@ public final class ParcelableUserLoader extends AsyncTaskLoader loadInBackground() { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, accountHost, false); if (twitter == null) return null; try { return twitter.getSavedSearches(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ScheduledStatusesLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ScheduledStatusesLoader.java index 9a15baa07..6f8822425 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ScheduledStatusesLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ScheduledStatusesLoader.java @@ -53,7 +53,7 @@ public class ScheduledStatusesLoader extends AsyncTaskLoader loadInBackground() { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, accountHost, true); final Paging paging = new Paging(); if (mSinceId > 0) { paging.setSinceId(mSinceId); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java index 038a8f85f..ec1bd236d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java @@ -163,7 +163,7 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader && statuses.size() >= loadItemLimit; for (int i = 0, j = statuses.size(); i < j; i++) { final Status status = statuses.get(i); - data.add(ParcelableStatusUtils.fromStatus(status, mAccountId, insertGap && isGapEnabled() && minIdx == i)); + data.add(ParcelableStatusUtils.fromStatus(status, mAccountId, accountHost, insertGap && isGapEnabled() && minIdx == i)); } final SQLiteDatabase db = TwidereApplication.getInstance(context).getSQLiteDatabase(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java index dd2c7d11d..5c4c82c34 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java @@ -44,7 +44,7 @@ public abstract class TwitterAPIUsersLoader extends ParcelableUsersLoader { @Override public List loadInBackground() { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, accountHost, true); if (twitter == null) return null; final List data = getData(); final List users; diff --git a/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java b/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java index c598c2594..526e1e430 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java @@ -11,7 +11,7 @@ import android.view.View; import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.twidere.TwidereConstants; import org.mariotaku.twidere.model.ParcelableAccount; -import org.mariotaku.twidere.util.DataStoreUtils; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; public class AccountActionProvider extends ActionProvider implements TwidereConstants { @@ -28,7 +28,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons } public AccountActionProvider(final Context context) { - this(context, DataStoreUtils.getAccounts(context, false, false)); + this(context, ParcelableAccountUtils.getAccounts(context, false, false)); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/AccountId.java b/twidere/src/main/java/org/mariotaku/twidere/model/AccountId.java new file mode 100644 index 000000000..e51ce7278 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/model/AccountId.java @@ -0,0 +1,109 @@ +package org.mariotaku.twidere.model; + +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.NonNull; + +import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; +import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; + +/** + * Created by mariotaku on 16/3/5. + */ +@ParcelablePlease +public class AccountId implements Comparable, Parcelable { + + @ParcelableThisPlease + long id; + @ParcelableThisPlease + String host; + + public AccountId(long id, String host) { + this.id = id; + this.host = host; + } + + public AccountId(ParcelableAccount account) { + this.id = account.account_id; + this.host = account.account_host; + } + + AccountId() { + + } + + public long getId() { + return id; + } + + public String getHost() { + return host; + } + + @Override + public String toString() { + if (host != null) return id + "@" + host; + return String.valueOf(id); + } + + public static long[] getIds(AccountId[] 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 AccountId another) { + if (this.id == another.id) { + if (this.host != null && another.host != null) { + return this.host.compareTo(another.host); + } else if (this.host != null) { + return 1; + } else if (another.host != null) { + return -1; + } + return 0; + } + return (int) (this.id - another.id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AccountId accountId = (AccountId) o; + + return id == accountId.id; + + } + + @Override + public int hashCode() { + return (int) (id ^ (id >>> 32)); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + AccountIdParcelablePlease.writeToParcel(this, dest, flags); + } + + public static final Creator CREATOR = new Creator() { + public AccountId createFromParcel(Parcel source) { + AccountId target = new AccountId(); + AccountIdParcelablePlease.readFromParcel(target, source); + return target; + } + + public AccountId[] newArray(int size) { + return new AccountId[size]; + } + }; +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java index 513e3968f..82ae41951 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java @@ -29,27 +29,27 @@ import android.text.TextUtils; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; -import org.mariotaku.twidere.util.DataStoreUtils; +import org.mariotaku.twidere.model.util.ParcelableAccountUtils; public class AccountPreferences implements Constants { private final Context mContext; - private final long mAccountId; + private final AccountId mAccountId; private final SharedPreferences mPreferences; - public AccountPreferences(final Context context, final long accountId) { + public AccountPreferences(final Context context, final AccountId accountId) { mContext = context; mAccountId = accountId; final String name = ACCOUNT_PREFERENCES_NAME_PREFIX + accountId; mPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE); } - public long getAccountId() { + public AccountId getAccountId() { return mAccountId; } public int getDefaultNotificationLightColor() { - final ParcelableAccount a = DataStoreUtils.getAccount(mContext, mAccountId); + final ParcelableAccount a = ParcelableAccountUtils.getAccount(mContext, mAccountId); if (a != null) { return a.color; } else { @@ -130,14 +130,14 @@ public class AccountPreferences implements Constants { return mPreferences.getBoolean(KEY_NOTIFICATION, DEFAULT_NOTIFICATION); } - public static AccountPreferences getAccountPreferences(final AccountPreferences[] prefs, final long accountId) { + public static AccountPreferences getAccountPreferences(final AccountPreferences[] prefs, final AccountId accountId) { for (final AccountPreferences pref : prefs) { if (pref.getAccountId() == accountId) return pref; } return null; } - public static AccountPreferences[] getAccountPreferences(final Context context, final long[] accountIds) { + public static AccountPreferences[] getAccountPreferences(final Context context, final AccountId[] accountIds) { if (context == null || accountIds == null) return null; final AccountPreferences[] preferences = new AccountPreferences[accountIds.length]; for (int i = 0, j = preferences.length; i < j; i++) { @@ -147,26 +147,26 @@ public class AccountPreferences implements Constants { } @NonNull - public static long[] getAutoRefreshEnabledAccountIds(final Context context, final long[] accountIds) { - if (context == null || accountIds == null) return new long[0]; - final long[] temp = new long[accountIds.length]; + public static AccountId[] getAutoRefreshEnabledAccountIds(final Context context, final AccountId[] accountIds) { + if (context == null || accountIds == null) return new AccountId[0]; + final AccountId[] temp = new AccountId[accountIds.length]; int i = 0; - for (final long accountId : accountIds) { + for (final AccountId accountId : accountIds) { if (new AccountPreferences(context, accountId).isAutoRefreshEnabled()) { temp[i++] = accountId; } } - final long[] enabledIds = new long[i]; + final AccountId[] enabledIds = new AccountId[i]; System.arraycopy(temp, 0, enabledIds, 0, i); return enabledIds; } @NonNull - public static AccountPreferences[] getNotificationEnabledPreferences(final Context context, final long[] accountIds) { + public static AccountPreferences[] getNotificationEnabledPreferences(final Context context, final AccountId[] accountIds) { if (context == null || accountIds == null) return new AccountPreferences[0]; final AccountPreferences[] temp = new AccountPreferences[accountIds.length]; int i = 0; - for (final long accountId : accountIds) { + for (final AccountId accountId : accountIds) { final AccountPreferences preference = new AccountPreferences(context, accountId); if (preference.isNotificationEnabled()) { temp[i++] = preference; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/BaseRefreshTaskParam.java b/twidere/src/main/java/org/mariotaku/twidere/model/BaseRefreshTaskParam.java index 62324f747..e54477759 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/BaseRefreshTaskParam.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/BaseRefreshTaskParam.java @@ -8,11 +8,13 @@ import android.support.annotation.Nullable; */ public class BaseRefreshTaskParam implements RefreshTaskParam { - private final long[] accountIds, maxIds, sinceIds; + private final org.mariotaku.twidere.model.AccountId[] accountIds; + private final long[] maxIds; + private final long[] sinceIds; @NonNull @Override - public long[] getAccountIds() { + public org.mariotaku.twidere.model.AccountId[] getAccountIds() { return accountIds; } @@ -28,9 +30,10 @@ public class BaseRefreshTaskParam implements RefreshTaskParam { return sinceIds; } - public BaseRefreshTaskParam(long[] accountIds, long[] maxIds, long[] sinceIds) { + public BaseRefreshTaskParam(org.mariotaku.twidere.model.AccountId[] accountIds, long[] maxIds, long[] sinceIds) { this.accountIds = accountIds; this.maxIds = maxIds; this.sinceIds = sinceIds; } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/RefreshTaskParam.java b/twidere/src/main/java/org/mariotaku/twidere/model/RefreshTaskParam.java index 08cc9ad78..cdffa1829 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/RefreshTaskParam.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/RefreshTaskParam.java @@ -8,11 +8,12 @@ import android.support.annotation.Nullable; */ public interface RefreshTaskParam { @NonNull - long[] getAccountIds(); + org.mariotaku.twidere.model.AccountId[] getAccountIds(); @Nullable long[] getMaxIds(); @Nullable long[] getSinceIds(); + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FavoriteTaskEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FavoriteTaskEvent.java index 9e793e7ad..1d27c1005 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/FavoriteTaskEvent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/message/FavoriteTaskEvent.java @@ -22,6 +22,7 @@ package org.mariotaku.twidere.model.message; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableStatus; /** @@ -30,7 +31,7 @@ import org.mariotaku.twidere.model.ParcelableStatus; public class FavoriteTaskEvent { private int action; - private long accountId; + private AccountId accountId; private long statusId; @Nullable @@ -38,7 +39,7 @@ public class FavoriteTaskEvent { private boolean finished; private boolean succeeded; - public FavoriteTaskEvent(@Action final int action, final long accountId, final long statusId) { + public FavoriteTaskEvent(@Action final int action, final AccountId accountId, final long statusId) { this.action = action; this.accountId = accountId; this.statusId = statusId; @@ -48,7 +49,7 @@ public class FavoriteTaskEvent { return action; } - public long getAccountId() { + public AccountId getAccountId() { return accountId; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java index 6eee7a3c3..b185943e4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/message/FollowRequestTaskEvent.java @@ -2,6 +2,8 @@ package org.mariotaku.twidere.model.message; import android.support.annotation.IntDef; +import org.mariotaku.twidere.model.AccountId; + /** * Created by mariotaku on 16/2/15. */ @@ -11,10 +13,10 @@ public class FollowRequestTaskEvent { private int action; private boolean finished; private boolean succeeded; - private long accountId; + private AccountId accountId; private long userId; - public FollowRequestTaskEvent(@Action int action, long accountId, long userId) { + public FollowRequestTaskEvent(@Action int action, AccountId accountId, long userId) { this.action = action; this.accountId = accountId; this.userId = userId; @@ -33,7 +35,7 @@ public class FollowRequestTaskEvent { this.finished = finished; } - public long getAccountId() { + public AccountId getAccountId() { return accountId; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUpdatedEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUpdatedEvent.java index 7e3661f42..66d09e52c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUpdatedEvent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/message/FriendshipUpdatedEvent.java @@ -22,18 +22,20 @@ package org.mariotaku.twidere.model.message; import android.support.annotation.NonNull; import org.mariotaku.twidere.api.twitter.model.Relationship; +import org.mariotaku.twidere.model.AccountId; /** * Created by mariotaku on 14/12/7. */ public class FriendshipUpdatedEvent { - public final long accountId; + @NonNull + public final AccountId accountId; public final long userId; @NonNull public final Relationship relationship; - public FriendshipUpdatedEvent(long accountId, long userId,@NonNull Relationship relationship) { + public FriendshipUpdatedEvent(@NonNull AccountId accountId, long userId, @NonNull Relationship relationship) { this.accountId = accountId; this.userId = userId; this.relationship = relationship; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/message/SavedSearchDestroyedEvent.java b/twidere/src/main/java/org/mariotaku/twidere/model/message/SavedSearchDestroyedEvent.java index f55f1dad8..adb513bde 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/message/SavedSearchDestroyedEvent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/message/SavedSearchDestroyedEvent.java @@ -1,17 +1,20 @@ package org.mariotaku.twidere.model.message; +import org.mariotaku.twidere.model.AccountId; + /** * Created by mariotaku on 16/2/26. */ public class SavedSearchDestroyedEvent { - private final long accountId, searchId; + private final AccountId accountId; + private final long searchId; - public SavedSearchDestroyedEvent(long accountId, long searchId) { + public SavedSearchDestroyedEvent(AccountId accountId, long searchId) { this.accountId = accountId; this.searchId = searchId; } - public long getAccountId() { + public AccountId getAccountId() { return accountId; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java index 1af553b51..15cbd073e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableAccountUtils.java @@ -1,8 +1,25 @@ package org.mariotaku.twidere.model.util; +import android.content.Context; +import android.database.Cursor; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import org.mariotaku.sqliteqb.library.Columns; +import org.mariotaku.sqliteqb.library.Expression; +import org.mariotaku.sqliteqb.library.RawItemArray; +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.api.twitter.model.UserList; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccountCursorIndices; +import org.mariotaku.twidere.model.ParcelableUserList; +import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; +import org.mariotaku.twidere.util.DataStoreUtils; +import org.mariotaku.twidere.util.TwitterContentUtils; + +import java.util.List; /** * Created by mariotaku on 16/2/20. @@ -17,4 +34,73 @@ public class ParcelableAccountUtils { return ids; } + @Nullable + public static ParcelableAccount getAccount(final Context context, final long accountId, + final String accountHost) { + if (context == null || accountId < 0) return null; + final Expression where = Expression.equals(Accounts.ACCOUNT_ID, accountId); + Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, + Accounts.COLUMNS_NO_CREDENTIALS, where.getSQL(), null, null); + if (cur == null) return null; + try { + ParcelableAccountCursorIndices i = new ParcelableAccountCursorIndices(cur); + cur.moveToFirst(); + while (!cur.isAfterLast()) { + if (TextUtils.equals(cur.getString(i.account_host), accountHost)) { + return i.newObject(cur); + } + cur.moveToNext(); + } + if (cur.moveToFirst()) { + return i.newObject(cur); + } + } finally { + cur.close(); + } + return null; + } + + public static ParcelableAccount getAccount(final Context context, final AccountId accountId) { + return getAccount(context, accountId.getId(), accountId.getHost()); + } + + @NonNull + public static ParcelableAccount[] getAccounts(final Context context, final boolean activatedOnly, + final boolean officialKeyOnly) { + final List list = DataStoreUtils.getAccountsList(context, activatedOnly, officialKeyOnly); + return list.toArray(new ParcelableAccount[list.size()]); + } + + @NonNull + public static ParcelableAccount[] getAccounts(@Nullable final Context context, @Nullable final long... 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; + 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)); + } + + @NonNull + public static ParcelableAccount[] getAccounts(@Nullable final Cursor cursor) { + if (cursor == null) return new ParcelableAccount[0]; + return getAccounts(cursor, new ParcelableAccountCursorIndices(cursor)); + } + + @NonNull + public static ParcelableAccount[] getAccounts(@Nullable final Cursor cursor, @Nullable final ParcelableAccountCursorIndices indices) { + if (cursor == null || indices == null) return new ParcelableAccount[0]; + try { + cursor.moveToFirst(); + final ParcelableAccount[] names = new ParcelableAccount[cursor.getCount()]; + while (!cursor.isAfterLast()) { + names[cursor.getPosition()] = indices.newObject(cursor); + cursor.moveToNext(); + } + return names; + } finally { + cursor.close(); + } + } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java index 8873e4438..319151ccd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableActivityUtils.java @@ -5,7 +5,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.model.ParcelableUser; -import org.mariotaku.twidere.model.ParcelableUserList; /** * Created by mariotaku on 16/1/2. @@ -55,19 +54,21 @@ public class ParcelableActivityUtils { return activity.after_filtered_sources = result; } - public static ParcelableActivity fromActivity(final Activity activity, final long accountId, boolean isGap) { + public static ParcelableActivity fromActivity(final Activity activity, final long accountId, + final String accountHost, final boolean isGap) { ParcelableActivity result = new ParcelableActivity(); result.account_id = accountId; + result.account_host = accountHost; result.timestamp = activity.getCreatedAt().getTime(); result.action = activity.getAction(); result.max_position = activity.getMaxPosition(); result.min_position = activity.getMinPosition(); result.sources = ParcelableUserUtils.fromUsers(activity.getSources(), accountId); result.target_users = ParcelableUserUtils.fromUsers(activity.getTargetUsers(), accountId); - result.target_user_lists = ParcelableUserList.fromUserLists(activity.getTargetUserLists(), accountId); - result.target_statuses = ParcelableStatusUtils.fromStatuses(activity.getTargetStatuses(), accountId); - result.target_object_statuses = ParcelableStatusUtils.fromStatuses(activity.getTargetObjectStatuses(), accountId); - result.target_object_user_lists = ParcelableUserList.fromUserLists(activity.getTargetObjectUserLists(), accountId); + result.target_user_lists = ParcelableUserListUtils.fromUserLists(activity.getTargetUserLists(), accountId); + result.target_statuses = ParcelableStatusUtils.fromStatuses(activity.getTargetStatuses(), accountId, accountHost); + result.target_object_statuses = ParcelableStatusUtils.fromStatuses(activity.getTargetObjectStatuses(), accountId, accountHost); + result.target_object_user_lists = ParcelableUserListUtils.fromUserLists(activity.getTargetObjectUserLists(), accountId); result.target_object_users = ParcelableUserUtils.fromUsers(activity.getTargetObjectUsers(), accountId); if (result.sources != null) { result.source_ids = new long[result.sources.length]; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableCardEntityUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableCardEntityUtils.java index 6c9112398..2d9f30c65 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableCardEntityUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableCardEntityUtils.java @@ -9,6 +9,7 @@ import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.mariotaku.twidere.TwidereConstants; import org.mariotaku.twidere.api.twitter.model.CardEntity; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableCardEntity; import java.text.ParseException; @@ -21,13 +22,13 @@ import java.util.Map; public class ParcelableCardEntityUtils implements TwidereConstants { @Nullable - public static ParcelableCardEntity fromCardEntity(@Nullable CardEntity card, long accountId) { + public static ParcelableCardEntity fromCardEntity(@Nullable CardEntity card, AccountId accountId) { if (card == null) return null; final ParcelableCardEntity obj = new ParcelableCardEntity(); obj.name = card.getName(); obj.url = card.getUrl(); obj.users = ParcelableUserUtils.fromUsers(card.getUsers(), accountId); - obj.account_id = accountId; + obj.account_id = accountId.getId(); obj.values = from(card.getBindingValues()); return obj; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUpdateUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUpdateUtils.java index ad03de437..9f5fb9df7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUpdateUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUpdateUtils.java @@ -6,7 +6,6 @@ import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.model.Draft; import org.mariotaku.twidere.model.ParcelableStatusUpdate; import org.mariotaku.twidere.model.draft.UpdateStatusActionExtra; -import org.mariotaku.twidere.util.DataStoreUtils; /** * Created by mariotaku on 16/2/12. @@ -15,7 +14,7 @@ public class ParcelableStatusUpdateUtils implements Constants { public static ParcelableStatusUpdate fromDraftItem(final Context context, final Draft draft) { ParcelableStatusUpdate statusUpdate = new ParcelableStatusUpdate(); - statusUpdate.accounts = DataStoreUtils.getAccounts(context, draft.account_ids); + statusUpdate.accounts = ParcelableAccountUtils.getAccounts(context, draft.account_ids); statusUpdate.text = draft.text; statusUpdate.location = draft.location; statusUpdate.media = draft.media; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java index 28b531804..dd2f7f820 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java @@ -6,6 +6,7 @@ import android.support.annotation.Nullable; import org.mariotaku.twidere.api.twitter.model.Place; import org.mariotaku.twidere.api.twitter.model.Status; import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableUserMention; @@ -31,10 +32,12 @@ public class ParcelableStatusUtils { status.retweet_id = -1; } - public static ParcelableStatus fromStatus(final Status orig, final long accountId, final boolean isGap) { + public static ParcelableStatus fromStatus(final Status orig, final AccountId accountId, + final boolean isGap) { final ParcelableStatus result = new ParcelableStatus(); result.is_gap = isGap; - result.account_id = accountId; + result.account_id = accountId.getId(); + result.account_host = accountId.getHost(); result.id = orig.getId(); result.timestamp = getTime(orig.getCreatedAt()); result.extras = new ParcelableStatus.Extras(); @@ -116,7 +119,11 @@ public class ParcelableStatusUtils { result.location = ParcelableLocation.fromGeoLocation(status.getGeoLocation()); result.is_favorite = status.isFavorited(); result.text_unescaped = HtmlEscapeHelper.toPlainText(result.text_html); - result.my_retweet_id = result.retweeted_by_user_id == accountId ? result.id : status.getCurrentUserRetweet(); + if (result.retweeted_by_user_id == result.account_id) { + result.my_retweet_id = result.id; + } else { + result.my_retweet_id = status.getCurrentUserRetweet(); + } result.is_possibly_sensitive = status.isPossiblySensitive(); result.mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities()); result.card = ParcelableCardEntityUtils.fromCardEntity(status.getCard(), accountId); @@ -126,7 +133,7 @@ public class ParcelableStatusUtils { return result; } - public static ParcelableStatus[] fromStatuses(Status[] statuses, long accountId) { + public static ParcelableStatus[] fromStatuses(Status[] statuses, AccountId accountId) { if (statuses == null) return null; int size = statuses.length; final ParcelableStatus[] result = new ParcelableStatus[size]; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserListUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserListUtils.java new file mode 100644 index 000000000..fb93c07d1 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserListUtils.java @@ -0,0 +1,46 @@ +package org.mariotaku.twidere.model.util; + +import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.api.twitter.model.UserList; +import org.mariotaku.twidere.model.AccountId; +import org.mariotaku.twidere.model.ParcelableUserList; +import org.mariotaku.twidere.util.TwitterContentUtils; + +/** + * Created by mariotaku on 16/3/5. + */ +public class ParcelableUserListUtils { + public static ParcelableUserList from(UserList list, AccountId accountId) { + return from(list, accountId, 0, false); + } + + public static ParcelableUserList from(UserList list, AccountId accountId, long position, boolean isFollowing) { + ParcelableUserList obj = new ParcelableUserList(); + final User user = list.getUser(); + obj.position = position; + obj.account_id = accountId.getId(); + obj.account_host = accountId.getHost(); + obj.id = list.getId(); + obj.is_public = UserList.Mode.PUBLIC.equals(list.getMode()); + obj.is_following = isFollowing; + obj.name = list.getName(); + obj.description = list.getDescription(); + obj.user_id = user.getId(); + obj.user_name = user.getName(); + obj.user_screen_name = user.getScreenName(); + obj.user_profile_image_url = TwitterContentUtils.getProfileImageUrl(user); + obj.members_count = list.getMemberCount(); + obj.subscribers_count = list.getSubscriberCount(); + return obj; + } + + public static ParcelableUserList[] fromUserLists(UserList[] userLists, long accountId) { + if (userLists == null) return null; + int size = userLists.length; + final ParcelableUserList[] result = new ParcelableUserList[size]; + for (int i = 0; i < size; i++) { + result[i] = new ParcelableUserList(userLists[i], accountId); + } + return result; + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java index c45e9f91d..6614608f4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableUserUtils.java @@ -1,11 +1,13 @@ package org.mariotaku.twidere.model.util; import android.database.Cursor; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import org.mariotaku.twidere.TwidereConstants; import org.mariotaku.twidere.api.twitter.model.UrlEntity; import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages; import org.mariotaku.twidere.util.HtmlEscapeHelper; @@ -19,15 +21,18 @@ import org.mariotaku.twidere.util.media.preview.PreviewMediaExtractor; */ public class ParcelableUserUtils implements TwidereConstants { - public static ParcelableUser fromUser(User user, long accountId) { + public static ParcelableUser fromUser(@NonNull User user, @Nullable AccountId accountId) { return fromUser(user, accountId, 0); } - public static ParcelableUser fromUser(User user, long accountId, long position) { + public static ParcelableUser fromUser(@NonNull User user, @Nullable AccountId accountId, long position) { final UrlEntity[] urlEntities = user.getUrlEntities(); final ParcelableUser obj = new ParcelableUser(); obj.position = position; - obj.account_id = accountId; + if (accountId != null) { + obj.account_id = accountId.getId(); + obj.account_host = accountId.getHost(); + } obj.id = user.getId(); obj.created_at = user.getCreatedAt().getTime(); obj.is_protected = user.isProtected(); @@ -89,7 +94,7 @@ public class ParcelableUserUtils implements TwidereConstants { return new ParcelableUser(accountId, id, name, screenName, profileImageUrl); } - public static ParcelableUser[] fromUsers(final User[] users, long accountId) { + public static ParcelableUser[] fromUsers(final User[] users, AccountId accountId) { if (users == null) return null; int size = users.length; final ParcelableUser[] result = new ParcelableUser[size]; diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java index faf59d7ee..72c1c3be1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java @@ -445,7 +445,7 @@ public class BackgroundOperationService extends IntentService implements Constan final long accountId, final long recipientId, final String text, final String imageUri) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(this, accountId, true, true); - final TwitterUpload twitterUpload = TwitterAPIFactory.getTwitterInstance(this, accountId, true, true, TwitterUpload.class); + final TwitterUpload twitterUpload = TwitterAPIFactory.getTwitterInstance(this, accountId, accountHost, true, true, TwitterUpload.class); if (twitter == null || twitterUpload == null) return SingleResponse.getInstance(); try { final ParcelableDirectMessage directMessage; @@ -586,7 +586,7 @@ public class BackgroundOperationService extends IntentService implements Constan final Twitter twitter = TwitterAPIFactory.getTwitterInstance(this, account.account_id, true, true); final TwitterUpload upload = TwitterAPIFactory.getTwitterInstance(this, account.account_id, - true, true, TwitterUpload.class); + accountHost, true, true, TwitterUpload.class); // Shouldn't happen if (twitter == null || upload == null || credentials == null) { @@ -701,7 +701,7 @@ public class BackgroundOperationService extends IntentService implements Constan notReplyToOther = true; } } - final ParcelableStatus result = ParcelableStatusUtils.fromStatus(resultStatus, account.account_id, false); + final ParcelableStatus result = ParcelableStatusUtils.fromStatus(resultStatus, account.account_id, accountHost, false); if (shouldShorten && shortener != null && shortenedResult != null) { shortener.callback(shortenedResult, result); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/StreamingService.java b/twidere/src/main/java/org/mariotaku/twidere/service/StreamingService.java index 29fba006a..0afb93ea4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/StreamingService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/StreamingService.java @@ -332,7 +332,8 @@ public class StreamingService extends Service implements Constants { @Override public void onStatus(final Status status) { - final ContentValues values = ContentValuesCreator.createStatus(status, account.account_id); + final ContentValues values = ContentValuesCreator.createStatus(status, account.account_id, + account.account_host); if (!statusStreamStarted) { statusStreamStarted = true; values.put(Statuses.IS_GAP, true); diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java index 451a55a1b..47ee9a641 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java @@ -27,6 +27,8 @@ import com.twitter.Extractor; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.api.twitter.model.Status; +import org.mariotaku.twidere.model.AccountId; +import org.mariotaku.twidere.model.RefreshTaskParam; import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags; import org.mariotaku.twidere.provider.TwidereDataStore.CachedStatuses; import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers; @@ -64,7 +66,9 @@ public class CacheUsersStatusesTask extends AbstractTask statusesValues = new HashSet<>(); final Set hashTagValues = new HashSet<>(); - statusesValues.add(ContentValuesCreator.createStatus(status, params.accountId)); + final AccountId accountId = params.accountId; + statusesValues.add(ContentValuesCreator.createStatus(status, accountId.getId(), + accountId.getHost())); final String text = InternalTwitterContentUtils.unescapeTwitterStatusText(status.getText()); for (final String hashtag : extractor.extractHashtags(text)) { final ContentValues values = new ContentValues(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java index 6c02ab104..f9d288677 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java @@ -16,6 +16,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.model.DirectMessage; import org.mariotaku.twidere.api.twitter.model.Paging; import org.mariotaku.twidere.api.twitter.model.ResponseList; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.RefreshTaskParam; import org.mariotaku.twidere.model.message.GetMessagesTaskEvent; import org.mariotaku.twidere.util.AsyncTwitterWrapper; @@ -62,12 +63,12 @@ public abstract class GetDirectMessagesTask extends AbstractTask doLongOperation(final RefreshTaskParam param) { - final long[] accountIds = param.getAccountIds(); + final AccountId[] accountIds = param.getAccountIds(); final long[] sinceIds = param.getSinceIds(), maxIds = param.getMaxIds(); final List result = new ArrayList<>(); int idx = 0; final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT); - for (final long accountId : accountIds) { + for (final AccountId accountId : accountIds) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true); if (twitter == null) continue; try { @@ -108,14 +109,15 @@ public abstract class GetDirectMessagesTask extends AbstractTask messages, boolean isOutgoing, boolean notify) { + private boolean storeMessages(AccountId accountId, List messages, boolean isOutgoing, boolean notify) { if (messages == null) return true; final Uri uri = getDatabaseUri(); final ContentValues[] valuesArray = new ContentValues[messages.size()]; for (int i = 0, j = messages.size(); i < j; i++) { final DirectMessage message = messages.get(i); - valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountId, isOutgoing); + valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountId.getId(), + accountId.getHost(), isOutgoing); } // Delete all rows conflicting before new data inserted. diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java index 9f812ffb2..b7ec2f27d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java @@ -12,8 +12,9 @@ import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.model.ResponseList; import org.mariotaku.twidere.api.twitter.model.SavedSearch; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.SingleResponse; -import org.mariotaku.twidere.provider.TwidereDataStore; +import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches; import org.mariotaku.twidere.util.ContentValuesCreator; import org.mariotaku.twidere.util.TwitterAPIFactory; import org.mariotaku.twidere.util.content.ContentResolverUtils; @@ -21,7 +22,7 @@ import org.mariotaku.twidere.util.content.ContentResolverUtils; /** * Created by mariotaku on 16/2/13. */ -public class GetSavedSearchesTask extends AbstractTask, Object> +public class GetSavedSearchesTask extends AbstractTask, Object> implements Constants { private final Context mContext; @@ -31,17 +32,21 @@ public class GetSavedSearchesTask extends AbstractTask doLongOperation(long[] params) { + public SingleResponse doLongOperation(AccountId[] params) { final ContentResolver cr = mContext.getContentResolver(); - for (long accountId : params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, true); + for (AccountId accountId : params) { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId.getId(), + accountId.getHost(), true); if (twitter == null) continue; try { final ResponseList searches = twitter.getSavedSearches(); - final ContentValues[] values = ContentValuesCreator.createSavedSearches(searches, accountId); - final Expression where = Expression.equals(TwidereDataStore.SavedSearches.ACCOUNT_ID, accountId); - cr.delete(TwidereDataStore.SavedSearches.CONTENT_URI, where.getSQL(), null); - ContentResolverUtils.bulkInsert(cr, TwidereDataStore.SavedSearches.CONTENT_URI, values); + final ContentValues[] values = ContentValuesCreator.createSavedSearches(searches, + accountId.getId(), accountId.getHost()); + final Expression where = Expression.and(Expression.equalsArgs(SavedSearches.ACCOUNT_ID), + Expression.equalsArgs(SavedSearches.ACCOUNT_HOST)); + final String[] whereArgs = {String.valueOf(accountId.getId()), accountId.getHost()}; + cr.delete(SavedSearches.CONTENT_URI, where.getSQL(), whereArgs); + ContentResolverUtils.bulkInsert(cr, SavedSearches.CONTENT_URI, values); } catch (TwitterException e) { if (BuildConfig.DEBUG) { Log.w(LOGTAG, e); diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java index 080fd3ca4..e2137bd8d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java @@ -34,7 +34,7 @@ public abstract class GetTrendsTask extends AbstractTask @Override public Object doLongOperation(final Object param) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, accountHost, false); if (twitter == null) return null; try { final List trends = getTrends(twitter); diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java index 295351d1e..a78c2c755 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/twitter/GetActivitiesTask.java @@ -70,7 +70,7 @@ public abstract class GetActivitiesTask extends AbstractTask activities = getActivities(twitter, accountId, paging); - storeActivities(cr, accountId, noItemsBefore, activities); + storeActivities(cr, loadItemLimit, accountId, noItemsBefore, activities); // if (saveReadPosition && TwitterAPIFactory.isOfficialTwitterInstance(context, twitter)) { if (saveReadPosition) { saveReadPosition(accountId, twitter); @@ -112,13 +112,13 @@ public abstract class GetActivitiesTask extends AbstractTask activities) { + private void storeActivities(ContentResolver cr, int loadItemLimit, long accountId, + boolean noItemsBefore, ResponseList activities) { long[] deleteBound = new long[2]; Arrays.fill(deleteBound, -1); List valuesList = new ArrayList<>(); for (Activity activity : activities) { - final ParcelableActivity parcelableActivity = ParcelableActivityUtils.fromActivity(activity, accountId, false); + final ParcelableActivity parcelableActivity = ParcelableActivityUtils.fromActivity(activity, accountId, accountHost, false); if (deleteBound[0] < 0) { deleteBound[0] = parcelableActivity.min_position; } else { @@ -140,7 +140,8 @@ public abstract class GetActivitiesTask extends AbstractTask= loadItemLimit && !noItemsBefore + && rowsDeleted <= 0; if (insertGap && !valuesList.isEmpty()) { valuesList.get(valuesList.size() - 1).put(Activities.IS_GAP, true); } @@ -165,4 +166,4 @@ public abstract class GetActivitiesTask extends AbstractTask statuses, - long sinceId, long maxId, boolean notify) { + private void storeStatus(final long accountId, final String accountHost, + final List statuses, + final long sinceId, final long maxId, final boolean notify) { if (statuses == null || statuses.isEmpty() || accountId <= 0) { return; } @@ -92,7 +94,7 @@ public abstract class GetStatusesTask extends AbstractTask 0 && id <= sinceId) { @@ -157,13 +159,15 @@ public abstract class GetStatusesTask extends AbstractTask doLongOperation(final RefreshTaskParam param) { - final long[] accountIds = param.getAccountIds(), maxIds = param.getMaxIds(), sinceIds = param.getSinceIds(); + final AccountId[] accountIds = param.getAccountIds(); + final long[] maxIds = param.getMaxIds(); + final long[] sinceIds = param.getSinceIds(); final List result = new ArrayList<>(); - if (accountIds == null) return result; int idx = 0; final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT); - for (final long accountId : accountIds) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true); + for (final AccountId accountId : accountIds) { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId.getId(), + accountId.getHost(), true); if (twitter == null) continue; try { final Paging paging = new Paging(); @@ -186,18 +190,18 @@ public abstract class GetStatusesTask extends AbstractTask statuses = getStatuses(twitter, paging); InternalTwitterContentUtils.getStatusesWithQuoteData(twitter, statuses); - storeStatus(accountId, statuses, sinceId, maxId, true); + storeStatus(accountId.getId(), accountId.getHost(), statuses, sinceId, maxId, true); // TODO cache related data and preload final CacheUsersStatusesTask cacheTask = new CacheUsersStatusesTask(context); cacheTask.setParams(new TwitterWrapper.StatusListResponse(accountId, statuses)); TaskStarter.execute(cacheTask); - errorInfoStore.remove(getErrorInfoKey(), accountId); + errorInfoStore.remove(getErrorInfoKey(), accountId.getId()); } catch (final TwitterException e) { if (BuildConfig.DEBUG) { Log.w(LOGTAG, e); } if (e.isCausedByNetworkIssue()) { - errorInfoStore.put(getErrorInfoKey(), accountId, + errorInfoStore.put(getErrorInfoKey(), accountId.getId(), ErrorInfoStore.CODE_NETWORK_ERROR); } result.add(new TwitterWrapper.StatusListResponse(accountId, e)); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index f38a33f74..8bbab5a36 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -26,7 +26,6 @@ import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.AsyncTask; -import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.util.LongSparseArray; import android.util.Log; @@ -53,6 +52,7 @@ import org.mariotaku.twidere.api.twitter.model.SavedSearch; import org.mariotaku.twidere.api.twitter.model.User; import org.mariotaku.twidere.api.twitter.model.UserList; import org.mariotaku.twidere.api.twitter.model.UserListUpdate; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.BaseRefreshTaskParam; import org.mariotaku.twidere.model.ListResponse; import org.mariotaku.twidere.model.ParcelableStatus; @@ -73,6 +73,7 @@ import org.mariotaku.twidere.model.message.StatusRetweetedEvent; import org.mariotaku.twidere.model.message.UserListCreatedEvent; import org.mariotaku.twidere.model.message.UserListDestroyedEvent; import org.mariotaku.twidere.model.util.ParcelableStatusUtils; +import org.mariotaku.twidere.model.util.ParcelableUserListUtils; import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.provider.TwidereDataStore; import org.mariotaku.twidere.provider.TwidereDataStore.Activities; @@ -93,12 +94,10 @@ import org.mariotaku.twidere.task.ManagedAsyncTask; import org.mariotaku.twidere.task.twitter.GetActivitiesTask; import org.mariotaku.twidere.task.util.TaskStarter; import org.mariotaku.twidere.util.collection.LongSparseMap; -import org.mariotaku.twidere.util.content.ContentResolverUtils; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.Set; import edu.tsinghua.hotmobi.HotMobiLogger; @@ -113,8 +112,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private final AsyncTaskManager mAsyncTaskManager; private final SharedPreferencesWrapper mPreferences; private final Bus mBus; - private final UserColorNameManager mUserColorNameManager; - private final ErrorInfoStore mErrorInfoStore; private LongSparseMap mCreatingFavoriteIds = new LongSparseMap<>(); private LongSparseMap mDestroyingFavoriteIds = new LongSparseMap<>(); @@ -124,19 +121,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private final LongList mSendingDraftIds = new ArrayLongList(); - public AsyncTwitterWrapper(Context context, UserColorNameManager userColorNameManager, - Bus bus, SharedPreferencesWrapper preferences, - AsyncTaskManager asyncTaskManager, ErrorInfoStore errorInfoStore) { + public AsyncTwitterWrapper(Context context, Bus bus, SharedPreferencesWrapper preferences, + AsyncTaskManager asyncTaskManager) { mContext = context; mResolver = context.getContentResolver(); - mUserColorNameManager = userColorNameManager; mBus = bus; mPreferences = preferences; mAsyncTaskManager = asyncTaskManager; - mErrorInfoStore = errorInfoStore; } - public int acceptFriendshipAsync(final long accountId, final long userId) { + public int acceptFriendshipAsync(final AccountId accountId, final long userId) { final AcceptFriendshipTask task = new AcceptFriendshipTask(mContext, accountId, userId); return mAsyncTaskManager.add(task, true); } @@ -148,16 +142,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } } - public int addUserListMembersAsync(final long accountId, final long listId, final ParcelableUser... users) { + public int addUserListMembersAsync(final AccountId accountId, final long listId, final ParcelableUser... users) { final AddUserListMembersTask task = new AddUserListMembersTask(accountId, listId, users); return mAsyncTaskManager.add(task, true); } - public int cancelRetweetAsync(long account_id, long status_id, long my_retweet_id) { - if (my_retweet_id > 0) - return destroyStatusAsync(account_id, my_retweet_id); - else if (status_id > 0) - return destroyStatusAsync(account_id, status_id); + public int cancelRetweetAsync(AccountId accountId, long statusId, long myRetweetId) { + if (myRetweetId > 0) + return destroyStatusAsync(accountId, myRetweetId); + else if (statusId > 0) + return destroyStatusAsync(accountId, statusId); return -1; } @@ -175,104 +169,104 @@ public class AsyncTwitterWrapper extends TwitterWrapper { AsyncTaskUtils.executeTask(task); } - public int createBlockAsync(final long accountId, final long user_id) { + public int createBlockAsync(final AccountId accountId, final long user_id) { final CreateBlockTask task = new CreateBlockTask(accountId, user_id); return mAsyncTaskManager.add(task, true); } - public int createFavoriteAsync(final long accountId, final long status_id) { - final CreateFavoriteTask task = new CreateFavoriteTask(accountId, status_id); + public int createFavoriteAsync(final AccountId accountId, final long statusId) { + final CreateFavoriteTask task = new CreateFavoriteTask(accountId, statusId); return mAsyncTaskManager.add(task, true); } - public int createFriendshipAsync(final long accountId, final long userId) { + public int createFriendshipAsync(final AccountId accountId, final long userId) { final CreateFriendshipTask task = new CreateFriendshipTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int createMultiBlockAsync(final long accountId, final long[] userIds) { + public int createMultiBlockAsync(final AccountId accountId, final long[] userIds) { final CreateMultiBlockTask task = new CreateMultiBlockTask(accountId, userIds); return mAsyncTaskManager.add(task, true); } - public int createMuteAsync(final long accountId, final long user_id) { + public int createMuteAsync(final AccountId accountId, final long user_id) { final CreateMuteTask task = new CreateMuteTask(accountId, user_id); return mAsyncTaskManager.add(task, true); } - public int createSavedSearchAsync(final long accountId, final String query) { + public int createSavedSearchAsync(final AccountId accountId, final String query) { final CreateSavedSearchTask task = new CreateSavedSearchTask(accountId, query); return mAsyncTaskManager.add(task, true); } - public int createUserListAsync(final long accountId, final String listName, final boolean isPublic, + public int createUserListAsync(final AccountId accountId, final String listName, final boolean isPublic, final String description) { final CreateUserListTask task = new CreateUserListTask(mContext, accountId, listName, isPublic, description); return mAsyncTaskManager.add(task, true); } - public int createUserListSubscriptionAsync(final long accountId, final long listId) { + public int createUserListSubscriptionAsync(final AccountId accountId, final long listId) { final CreateUserListSubscriptionTask task = new CreateUserListSubscriptionTask(accountId, listId); return mAsyncTaskManager.add(task, true); } - public int deleteUserListMembersAsync(final long accountId, final long listId, final ParcelableUser... users) { + public int deleteUserListMembersAsync(final AccountId accountId, final long listId, final ParcelableUser... users) { final DeleteUserListMembersTask task = new DeleteUserListMembersTask(accountId, listId, users); return mAsyncTaskManager.add(task, true); } - public int denyFriendshipAsync(final long accountId, final long userId) { + public int denyFriendshipAsync(final AccountId accountId, final long userId) { final DenyFriendshipTask task = new DenyFriendshipTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int destroyBlockAsync(final long accountId, final long user_id) { - final DestroyBlockTask task = new DestroyBlockTask(accountId, user_id); + public int destroyBlockAsync(final AccountId accountId, final long userId) { + final DestroyBlockTask task = new DestroyBlockTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int destroyDirectMessageAsync(final long accountId, final long message_id) { - final DestroyDirectMessageTask task = new DestroyDirectMessageTask(accountId, message_id); + public int destroyDirectMessageAsync(final AccountId accountId, final long messageId) { + final DestroyDirectMessageTask task = new DestroyDirectMessageTask(accountId, messageId); return mAsyncTaskManager.add(task, true); } - public int destroyMessageConversationAsync(final long accountId, final long userId) { + public int destroyMessageConversationAsync(final AccountId accountId, final long userId) { final DestroyMessageConversationTask task = new DestroyMessageConversationTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int destroyFavoriteAsync(final long accountId, final long status_id) { - final DestroyFavoriteTask task = new DestroyFavoriteTask(accountId, status_id); + public int destroyFavoriteAsync(final AccountId accountId, final long statusId) { + final DestroyFavoriteTask task = new DestroyFavoriteTask(accountId, statusId); return mAsyncTaskManager.add(task, true); } - public int destroyFriendshipAsync(final long accountId, final long user_id) { - final DestroyFriendshipTask task = new DestroyFriendshipTask(accountId, user_id); + public int destroyFriendshipAsync(final AccountId accountId, final long userId) { + final DestroyFriendshipTask task = new DestroyFriendshipTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int destroyMuteAsync(final long accountId, final long user_id) { - final DestroyMuteTask task = new DestroyMuteTask(accountId, user_id); + public int destroyMuteAsync(final AccountId accountId, final long userId) { + final DestroyMuteTask task = new DestroyMuteTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int destroySavedSearchAsync(final long accountId, final long searchId) { + public int destroySavedSearchAsync(final AccountId accountId, final long searchId) { final DestroySavedSearchTask task = new DestroySavedSearchTask(accountId, searchId); return mAsyncTaskManager.add(task, true); } - public int destroyStatusAsync(final long accountId, final long status_id) { - final DestroyStatusTask task = new DestroyStatusTask(accountId, status_id); + public int destroyStatusAsync(final AccountId accountId, final long statusId) { + final DestroyStatusTask task = new DestroyStatusTask(accountId, statusId); return mAsyncTaskManager.add(task, true); } - public int destroyUserListAsync(final long accountId, final long listId) { + public int destroyUserListAsync(final AccountId accountId, final long listId) { final DestroyUserListTask task = new DestroyUserListTask(mContext, accountId, listId); return mAsyncTaskManager.add(task, true); } - public int destroyUserListSubscriptionAsync(final long accountId, final long listId) { + public int destroyUserListSubscriptionAsync(final AccountId accountId, final long listId) { final DestroyUserListSubscriptionTask task = new DestroyUserListSubscriptionTask(accountId, listId); return mAsyncTaskManager.add(task, true); } @@ -281,7 +275,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mContext; } - public boolean getHomeTimelineAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) { + public boolean getHomeTimelineAsync(final AccountId[] accountIds, final long[] maxIds, final long[] sinceIds) { return getHomeTimelineAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds)); } @@ -297,7 +291,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { TaskStarter.execute(task); } - public void getReceivedDirectMessagesAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) { + public void getReceivedDirectMessagesAsync(final AccountId[] accountIds, + final long[] maxIds, final long[] sinceIds) { getActivitiesAboutMeAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds)); } @@ -307,13 +302,14 @@ public class AsyncTwitterWrapper extends TwitterWrapper { TaskStarter.execute(task); } - public void getSentDirectMessagesAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) { + public void getSentDirectMessagesAsync(final AccountId[] accountIds, + final long[] maxIds, final long[] sinceIds) { final GetSentDirectMessagesTask task = new GetSentDirectMessagesTask(mContext); task.setParams(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds)); TaskStarter.execute(task); } - public int getSavedSearchesAsync(long[] accountIds) { + public int getSavedSearchesAsync(AccountId[] accountIds) { final GetSavedSearchesTask task = new GetSavedSearchesTask(mContext); task.setParams(accountIds); TaskStarter.execute(task); @@ -325,36 +321,24 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mSendingDraftIds.toArray(); } - public AsyncTaskManager getTaskManager() { - return mAsyncTaskManager; - } - public boolean isCreatingFavorite(final long accountId, final long statusId) { return mCreatingFavoriteIds.has(accountId, statusId); } - public boolean isCreatingFriendship(final long accountId, final long userId) { - for (final ManagedAsyncTask task : mAsyncTaskManager.getTaskSpecList()) { - if (task instanceof CreateFriendshipTask) { - final CreateFriendshipTask createFriendshipTask = (CreateFriendshipTask) task; - if (createFriendshipTask.getStatus() == AsyncTask.Status.RUNNING - && createFriendshipTask.getAccountId() == accountId - && createFriendshipTask.getUserId() == userId) - return true; - } - } + public boolean isCreatingFriendship(final AccountId accountId, final long userId) { + // TODO implementation return false; } - public boolean isCreatingRetweet(final long accountId, final long statusId) { - return mCreatingRetweetIds.has(accountId, statusId); + public boolean isCreatingRetweet(final AccountId accountId, final long statusId) { + return mCreatingRetweetIds.has(accountId.getId(), statusId); } - public boolean isDestroyingFavorite(final long accountId, final long statusId) { - return mDestroyingFavoriteIds.has(accountId, statusId); + public boolean isDestroyingFavorite(final AccountId accountId, final long statusId) { + return mDestroyingFavoriteIds.has(accountId.getId(), statusId); } - public boolean isDestroyingFriendship(final long accountId, final long userId) { + public boolean isDestroyingFriendship(final AccountId accountId, final long userId) { for (final ManagedAsyncTask task : mAsyncTaskManager.getTaskSpecList()) { if (task instanceof DestroyFriendshipTask) { final DestroyFriendshipTask destroyFriendshipTask = (DestroyFriendshipTask) task; @@ -393,10 +377,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { refreshAll(DataStoreUtils.getActivatedAccountIds(mContext)); } - public boolean refreshAll(final long[] accountIds) { - AsyncTaskUtils.executeTask(new AsyncTask() { + public boolean refreshAll(final AccountId[] accountIds) { + AsyncTaskUtils.executeTask(new AsyncTask() { @Override - protected Object[] doInBackground(long[][] params) { + protected Object[] doInBackground(AccountId... accountIds) { final Object[] result = new Object[8]; result[0] = DataStoreUtils.getNewestStatusIds(mContext, Statuses.CONTENT_URI, accountIds); if (Boolean.TRUE.equals(result[1] = mPreferences.getBoolean(KEY_HOME_REFRESH_MENTIONS))) { @@ -444,18 +428,17 @@ public class AsyncTwitterWrapper extends TwitterWrapper { AsyncTaskUtils.executeTask(task); } - public int reportMultiSpam(final long accountId, final long[] user_ids) { - final ReportMultiSpamTask task = new ReportMultiSpamTask(accountId, user_ids); + public void reportMultiSpam(final long accountId, final long[] userIds) { + // TODO implementation + } + + public int reportSpamAsync(final AccountId accountId, final long userId) { + final ReportSpamTask task = new ReportSpamTask(accountId, userId); return mAsyncTaskManager.add(task, true); } - public int reportSpamAsync(final long accountId, final long user_id) { - final ReportSpamTask task = new ReportSpamTask(accountId, user_id); - return mAsyncTaskManager.add(task, true); - } - - public int retweetStatusAsync(final long accountId, final long status_id) { - final RetweetStatusTask task = new RetweetStatusTask(accountId, status_id); + public int retweetStatusAsync(final AccountId accountId, final long statusId) { + final RetweetStatusTask task = new RetweetStatusTask(accountId, statusId); return mAsyncTaskManager.add(task, true); } @@ -471,8 +454,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return 0; } - public int updateUserListDetails(final long accountId, final long listId, final UserListUpdate update) { - final UpdateUserListDetailsTask task = new UpdateUserListDetailsTask(mContext, accountId, listId, update); + public int updateUserListDetails(final AccountId accountId, final long listId, + final UserListUpdate update) { + final UpdateUserListDetailsTask task = new UpdateUserListDetailsTask(mContext, accountId, + listId, update); return mAsyncTaskManager.add(task, true); } @@ -483,7 +468,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return null; } - public void updateFriendship(final long accountId, final long userId, final FriendshipUpdate update) { + public void updateFriendship(final AccountId accountId, final long userId, final FriendshipUpdate update) { final Bus bus = mBus; if (bus == null) return; TaskStarter.execute(new AbstractTask, Bus>() { @@ -510,7 +495,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { }.setResultHandler(bus)); } - public void getActivitiesAboutMeAsync(final long[] accountIds, long[] maxIds, long[] sinceIds) { + public void getActivitiesAboutMeAsync(final AccountId[] accountIds, + long[] maxIds, long[] sinceIds) { getActivitiesAboutMeAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds)); } @@ -520,12 +506,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper { TaskStarter.execute(task); } - public void setActivitiesAboutMeUnreadAsync(final long[] accountIds, final long cursor) { + public void setActivitiesAboutMeUnreadAsync(final AccountId[] accountIds, final long cursor) { AbstractTask task = new AbstractTask() { @Override public Object doLongOperation(Object o) { - for (long accountId : accountIds) { + for (AccountId accountId : accountIds) { Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, false); if (!Utils.isOfficialCredentials(mContext, accountId)) continue; try { @@ -542,12 +528,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper { TaskStarter.execute(task); } - private void addProcessingFriendshipRequestId(long accountId, long userId) { - mProcessingFriendshipRequestIds.add(ParcelableUser.calculateHashCode(accountId, userId)); + private void addProcessingFriendshipRequestId(AccountId accountId, long userId) { + mProcessingFriendshipRequestIds.add(ParcelableUser.calculateHashCode(accountId.getId(), userId)); } - private void removeProcessingFriendshipRequestId(long accountId, long userId) { - mProcessingFriendshipRequestIds.removeElement(ParcelableUser.calculateHashCode(accountId, userId)); + private void removeProcessingFriendshipRequestId(AccountId accountId, long userId) { + mProcessingFriendshipRequestIds.removeElement(ParcelableUser.calculateHashCode(accountId.getId(), userId)); } public boolean isProcessingFollowRequest(long accountId, long userId) { @@ -556,18 +542,18 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public static class UpdateProfileBannerImageTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final Uri mImageUri; private final boolean mDeleteImage; private final Context mContext; - public UpdateProfileBannerImageTask(final Context context, final AsyncTaskManager manager, - final long account_id, final Uri image_uri, final boolean delete_image) { + public UpdateProfileBannerImageTask(final Context context, final AccountId accountId, + final Uri imageUri, final boolean deleteImage) { super(context); mContext = context; - mAccountId = account_id; - mImageUri = image_uri; - mDeleteImage = delete_image; + mAccountId = accountId; + mImageUri = imageUri; + mDeleteImage = deleteImage; } @Override @@ -575,8 +561,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { super.onPostExecute(result); if (result.hasData()) { Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false); - - bus.post(new ProfileUpdatedEvent(result.getData())); } else { Utils.showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(), @@ -587,7 +571,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected SingleResponse doInBackground(final Object... params) { try { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, true); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, + true); TwitterWrapper.updateProfileBannerImage(mContext, twitter, mImageUri, mDeleteImage); // Wait for 5 seconds, see // https://dev.twitter.com/docs/api/1.1/post/account/update_profile_image @@ -596,7 +581,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } catch (InterruptedException e) { Log.w(LOGTAG, e); } - final User user = TwitterWrapper.tryShowUser(twitter, mAccountId, null); + final User user = TwitterWrapper.tryShowUser(twitter, mAccountId.getId(), null); return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountId)); } catch (TwitterException | FileNotFoundException e) { return SingleResponse.getInstance(e); @@ -608,18 +593,19 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public static class UpdateProfileImageTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final Uri mImageUri; private final boolean mDeleteImage; private final Context mContext; - public UpdateProfileImageTask(final Context context, final long account_id, - final Uri image_uri, final boolean delete_image) { + public UpdateProfileImageTask(final Context context, final AccountId accountId, + String accountHost, final Uri imageUri, + final boolean deleteImage) { super(context); this.mContext = context; - this.mAccountId = account_id; - this.mImageUri = image_uri; - this.mDeleteImage = delete_image; + this.mAccountId = accountId; + this.mImageUri = imageUri; + this.mDeleteImage = deleteImage; } @Override @@ -634,7 +620,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } catch (InterruptedException e) { Log.w(LOGTAG, e); } - final User user = TwitterWrapper.tryShowUser(twitter, mAccountId, null); + final User user = TwitterWrapper.tryShowUser(twitter, mAccountId.getId(), null); return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountId)); } catch (TwitterException | FileNotFoundException e) { return SingleResponse.getInstance(e); @@ -656,16 +642,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { static class AcceptFriendshipTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mUserId; - public AcceptFriendshipTask(final Context context, final long accountId, final long userId) { + public AcceptFriendshipTask(final Context context, final AccountId accountId, final long userId) { super(context); mAccountId = accountId; mUserId = userId; } - public long getAccountId() { + public AccountId getAccountId() { return mAccountId; } @@ -723,11 +709,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class AddUserListMembersTask extends ManagedAsyncTask> { - private final long accountId; + private final AccountId accountId; private final long listId; private final ParcelableUser[] users; - public AddUserListMembersTask(final long accountId, final long listId, final ParcelableUser[] users) { + public AddUserListMembersTask(final AccountId accountId, final long listId, final ParcelableUser[] users) { super(mContext); this.accountId = accountId; this.listId = listId; @@ -743,8 +729,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { for (int i = 0, j = users.length; i < j; i++) { userIds[i] = users[i].id; } - final ParcelableUserList list = new ParcelableUserList(twitter.addUserListMembers(listId, userIds), - accountId); + final UserList result = twitter.addUserListMembers(listId, userIds); + final ParcelableUserList list = ParcelableUserListUtils.from(result, accountId); return SingleResponse.getInstance(list, null); } catch (final TwitterException e) { return SingleResponse.getInstance(null, e); @@ -812,34 +798,40 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateBlockTask extends ManagedAsyncTask> { - private final long account_id, user_id; + private final AccountId mAccountId; + private final long mUserId; - public CreateBlockTask(final long account_id, final long user_id) { + public CreateBlockTask(final AccountId accountId, final long userId) { super(mContext); - this.account_id = account_id; - this.user_id = user_id; + this.mAccountId = accountId; + this.mUserId = userId; } @Override protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter == null) return SingleResponse.getInstance(); try { - final User user = twitter.createBlock(user_id); + final User user = twitter.createBlock(mUserId); Utils.setLastSeen(mContext, user.getId(), -1); for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), - Expression.equals(Statuses.USER_ID, user_id)); - mResolver.delete(uri, where.getSQL(), null); + final Expression where = Expression.and( + Utils.getAccountCompareExpression(), + Expression.equalsArgs(Statuses.USER_ID) + ); + final String[] whereArgs = {String.valueOf(mAccountId.getId()), + mAccountId.getHost(), String.valueOf(mUserId)}; + mResolver.delete(uri, where.getSQL(), whereArgs); } // I bet you don't want to see this user in your auto complete list. final ContentValues values = new ContentValues(); - values.put(CachedRelationships.ACCOUNT_ID, account_id); - values.put(CachedRelationships.USER_ID, user_id); + values.put(CachedRelationships.ACCOUNT_ID, mAccountId.getId()); + values.put(CachedRelationships.ACCOUNT_HOST, mAccountId.getHost()); + values.put(CachedRelationships.USER_ID, mUserId); values.put(CachedRelationships.BLOCKING, true); mResolver.insert(CachedRelationships.CONTENT_URI, values); - return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, account_id), null); + return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountId), null); } catch (final TwitterException e) { return SingleResponse.getInstance(null, e); } @@ -865,32 +857,35 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateFavoriteTask extends ManagedAsyncTask> { - private final long mAccountId, mStatusId; + private final AccountId mAccountId; + private final long mStatusId; - public CreateFavoriteTask(final long account_id, final long mStatusId) { + public CreateFavoriteTask(final AccountId accountId, final long statusId) { super(mContext); - this.mAccountId = account_id; - this.mStatusId = mStatusId; + this.mAccountId = accountId; + this.mStatusId = statusId; } @Override protected SingleResponse doInBackground(final Object... params) { - if (mAccountId < 0) return SingleResponse.getInstance(); final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, true); if (twitter == null) return SingleResponse.getInstance(); try { - final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.createFavorite(mStatusId), mAccountId, false); + final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.createFavorite(mStatusId), + mAccountId, false); Utils.setLastSeen(mContext, status.mentions, System.currentTimeMillis()); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, true); values.put(Statuses.REPLY_COUNT, status.reply_count); values.put(Statuses.RETWEET_COUNT, status.retweet_count); values.put(Statuses.FAVORITE_COUNT, status.favorite_count); - final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, mAccountId), + final Expression where = Expression.and(Utils.getAccountCompareExpression(), Expression.or(Expression.equals(Statuses.STATUS_ID, mStatusId), Expression.equals(Statuses.RETWEET_ID, mStatusId))); + final String[] whereArgs = {String.valueOf(mAccountId.getId()), mAccountId.getHost(), + String.valueOf(mStatusId), String.valueOf(mStatusId)}; for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - mResolver.update(uri, values, where.getSQL(), null); + mResolver.update(uri, values, where.getSQL(), whereArgs); } return SingleResponse.getInstance(status); } catch (final TwitterException e) { @@ -904,13 +899,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPreExecute() { super.onPreExecute(); - mCreatingFavoriteIds.put(mAccountId, mStatusId); + mCreatingFavoriteIds.put(mAccountId.getId(), mStatusId); bus.post(new StatusListChangedEvent()); } @Override protected void onPostExecute(final SingleResponse result) { - mCreatingFavoriteIds.remove(mAccountId, mStatusId); + mCreatingFavoriteIds.remove(mAccountId.getId(), mStatusId); final FavoriteTaskEvent taskEvent = new FavoriteTaskEvent(FavoriteTaskEvent.Action.CREATE, mAccountId, mStatusId); taskEvent.setFinished(true); @@ -921,7 +916,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { // BEGIN HotMobi final TweetEvent tweetEvent = TweetEvent.create(getContext(), status, TimelineType.OTHER); tweetEvent.setAction(TweetEvent.Action.FAVORITE); - HotMobiLogger.getInstance(getContext()).log(mAccountId, tweetEvent); + HotMobiLogger.getInstance(getContext()).log(mAccountId.getId(), tweetEvent); // END HotMobi } else { taskEvent.setSucceeded(false); @@ -936,16 +931,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateFriendshipTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long user_id; - public CreateFriendshipTask(final long accountId, final long user_id) { + public CreateFriendshipTask(final AccountId accountId, final long userId) { super(mContext); this.mAccountId = accountId; - this.user_id = user_id; + this.user_id = userId; } - public long getAccountId() { + public AccountId getAccountId() { return mAccountId; } @@ -994,18 +989,20 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateMultiBlockTask extends ManagedAsyncTask> { - private final long account_id; - private final long[] user_ids; + private final AccountId mAccountId; + private final long[] mUserIds; - public CreateMultiBlockTask(final long account_id, final long[] user_ids) { + public CreateMultiBlockTask(final AccountId accountId, final long[] userIds) { super(mContext); - this.account_id = account_id; - this.user_ids = user_ids; + this.mAccountId = accountId; + this.mUserIds = userIds; } private void deleteCaches(final List list) { for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - ContentResolverUtils.bulkDelete(mResolver, uri, Statuses.USER_ID, list, Statuses.ACCOUNT_ID + " = " + account_id, false); + // TODO delete caches + // ContentResolverUtils.bulkDelete(mResolver, uri, Statuses.USER_ID, list, + // Statuses.ACCOUNT_ID + " = " + mAccountId, false); } // I bet you don't want to see these users in your auto complete list. //TODO insert to blocked users data @@ -1021,9 +1018,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected ListResponse doInBackground(final Object... params) { final List blocked_users = new ArrayList<>(); - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter != null) { - for (final long user_id : user_ids) { + for (final long user_id : mUserIds) { try { final User user = twitter.createBlock(user_id); if (user == null || user.getId() <= 0) { @@ -1048,7 +1045,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { Utils.showErrorMessage(mContext, R.string.action_blocking, result.getException(), true); } final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED); - intent.putExtra(EXTRA_USER_ID, user_ids); + intent.putExtra(EXTRA_USER_ID, mUserIds); mContext.sendBroadcast(intent); super.onPostExecute(result); } @@ -1058,9 +1055,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateMuteTask extends ManagedAsyncTask> { - private final long mAccountId, mUserId; + private final AccountId mAccountId; + private final long mUserId; - public CreateMuteTask(final long accountId, final long userId) { + public CreateMuteTask(final AccountId accountId, final long userId) { super(mContext); this.mAccountId = accountId; this.mUserId = userId; @@ -1103,10 +1101,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateSavedSearchTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final String mQuery; - CreateSavedSearchTask(final long accountId, final String query) { + CreateSavedSearchTask(final AccountId accountId, final String query) { super(mContext); mAccountId = accountId; mQuery = query; @@ -1145,10 +1143,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class CreateUserListSubscriptionTask extends ManagedAsyncTask> { - private final long accountId; + private final AccountId accountId; private final long listId; - public CreateUserListSubscriptionTask(final long accountId, final long listId) { + public CreateUserListSubscriptionTask(final AccountId accountId, final long listId) { super(mContext); this.accountId = accountId; this.listId = listId; @@ -1158,10 +1156,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { protected SingleResponse doInBackground(final Object... params) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, false); if (twitter == null) return SingleResponse.getInstance(); - try { - final ParcelableUserList list = new ParcelableUserList(twitter.createUserListSubscription(listId), - accountId); + final UserList userList = twitter.createUserListSubscription(listId); + final ParcelableUserList list = ParcelableUserListUtils.from(userList, accountId); return SingleResponse.getInstance(list); } catch (final TwitterException e) { return SingleResponse.getInstance(e); @@ -1187,30 +1184,31 @@ public class AsyncTwitterWrapper extends TwitterWrapper { static class CreateUserListTask extends ManagedAsyncTask> { - private final long accountId; - private final String listName, description; - private final boolean isPublic; + private final AccountId mAccountId; + private final String mListName, mDescription; + private final boolean mIsPublic; - public CreateUserListTask(Context context, final long accountId, final String listName, final boolean isPublic, - final String description) { + public CreateUserListTask(Context context, final AccountId accountId, final String listName, + final boolean isPublic, final String description) { super(context); - this.accountId = accountId; - this.listName = listName; - this.description = description; - this.isPublic = isPublic; + this.mAccountId = accountId; + this.mListName = listName; + this.mDescription = description; + this.mIsPublic = isPublic; } @Override protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), accountId, false); - if (twitter == null || listName == null) return SingleResponse.getInstance(); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, + false); + if (twitter == null || mListName == null) return SingleResponse.getInstance(); try { final UserListUpdate userListUpdate = new UserListUpdate(); - userListUpdate.setName(listName); - userListUpdate.setMode(isPublic ? UserList.Mode.PUBLIC : UserList.Mode.PRIVATE); - userListUpdate.setDescription(description); + userListUpdate.setName(mListName); + userListUpdate.setMode(mIsPublic ? UserList.Mode.PUBLIC : UserList.Mode.PRIVATE); + userListUpdate.setDescription(mDescription); final UserList list = twitter.createUserList(userListUpdate); - return SingleResponse.getInstance(new ParcelableUserList(list, accountId), null); + return SingleResponse.getInstance(ParcelableUserListUtils.from(list, mAccountId), null); } catch (final TwitterException e) { return SingleResponse.getInstance(null, e); } @@ -1234,11 +1232,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DeleteUserListMembersTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mUserListId; private final ParcelableUser[] users; - public DeleteUserListMembersTask(final long accountId, final long userListId, final ParcelableUser[] users) { + public DeleteUserListMembersTask(final AccountId accountId, final long userListId, final ParcelableUser[] users) { super(mContext); mAccountId = accountId; mUserListId = userListId; @@ -1254,8 +1252,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { for (int i = 0, j = users.length; i < j; i++) { userIds[i] = users[i].id; } - final ParcelableUserList list = new ParcelableUserList(twitter.deleteUserListMembers(mUserListId, - userIds), mAccountId); + final UserList userList = twitter.deleteUserListMembers(mUserListId, userIds); + final ParcelableUserList list = ParcelableUserListUtils.from(userList, mAccountId); return SingleResponse.getInstance(list, null); } catch (final TwitterException e) { return SingleResponse.getInstance(null, e); @@ -1294,16 +1292,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DenyFriendshipTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mUserId; - public DenyFriendshipTask(final long accountId, final long userId) { + public DenyFriendshipTask(final AccountId accountId, final long userId) { super(mContext); mAccountId = accountId; mUserId = userId; } - public long getAccountId() { + public AccountId getAccountId() { return mAccountId; } @@ -1359,10 +1357,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyBlockTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mUserId; - public DestroyBlockTask(final long accountId, final long userId) { + public DestroyBlockTask(final AccountId accountId, final long userId) { super(mContext); mAccountId = accountId; mUserId = userId; @@ -1402,14 +1400,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyDirectMessageTask extends ManagedAsyncTask> { - private final long message_id; - private final long account_id; + private final AccountId mAccountId; + private final long mMessageId; - public DestroyDirectMessageTask(final long account_id, final long message_id) { + public DestroyDirectMessageTask(final AccountId accountId, final long messageId) { super(mContext); - - this.account_id = account_id; - this.message_id = message_id; + mAccountId = accountId; + mMessageId = messageId; } private void deleteMessages(final long message_id) { @@ -1427,15 +1424,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected SingleResponse doInBackground(final Object... args) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter == null) return SingleResponse.getInstance(); try { - final DirectMessage message = twitter.destroyDirectMessage(message_id); - deleteMessages(message_id); + final DirectMessage message = twitter.destroyDirectMessage(mMessageId); + deleteMessages(mMessageId); return SingleResponse.getInstance(message, null); } catch (final TwitterException e) { if (isMessageNotFound(e)) { - deleteMessages(message_id); + deleteMessages(mMessageId); } return SingleResponse.getInstance(null, e); } @@ -1459,17 +1456,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyMessageConversationTask extends ManagedAsyncTask> { - private final long userId; - private final long accountId; + private final long mUserId; + private final AccountId mAccountId; - public DestroyMessageConversationTask(final long accountId, final long userId) { + public DestroyMessageConversationTask(final AccountId accountId, final long userId) { super(mContext); - - this.accountId = accountId; - this.userId = userId; + mAccountId = accountId; + mUserId = userId; } - private void deleteMessages(final long accountId, final long userId) { + private void deleteMessages(final AccountId accountId, final long userId) { mResolver.delete(DirectMessages.Inbox.CONTENT_URI, Expression.and(Expression.equals(Inbox.ACCOUNT_ID, accountId), Expression.equals(Inbox.SENDER_ID, userId)).getSQL(), null); mResolver.delete(DirectMessages.Outbox.CONTENT_URI, Expression.and(Expression.equals(Outbox.ACCOUNT_ID, accountId), @@ -1485,15 +1481,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected SingleResponse doInBackground(final Object... args) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter == null) return SingleResponse.getInstance(); try { - twitter.destroyDirectMessagesConversation(accountId, userId); - deleteMessages(accountId, userId); + twitter.destroyDirectMessagesConversation(mAccountId.getId(), mUserId); + deleteMessages(mAccountId, mUserId); return SingleResponse.getInstance(); } catch (final TwitterException e) { if (isMessageNotFound(e)) { - deleteMessages(accountId, userId); + deleteMessages(mAccountId, mUserId); } return SingleResponse.getInstance(e); } @@ -1517,38 +1513,39 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyFavoriteTask extends ManagedAsyncTask> { - private final long mAccountId; - + @NonNull + private final AccountId mAccountId; private final long mStatusId; - public DestroyFavoriteTask(final long account_id, final long status_id) { + public DestroyFavoriteTask(@NonNull final AccountId accountId, final long statusId) { super(mContext); - this.mAccountId = account_id; - this.mStatusId = status_id; + this.mAccountId = accountId; + this.mStatusId = statusId; } @Override protected SingleResponse doInBackground(final Object... params) { - if (mAccountId < 0) return SingleResponse.getInstance(); final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, true); - if (twitter != null) { - try { - final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.destroyFavorite(mStatusId), mAccountId, false); - final ContentValues values = new ContentValues(); - values.put(Statuses.IS_FAVORITE, false); - values.put(Statuses.FAVORITE_COUNT, status.favorite_count - 1); - final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, mAccountId), - Expression.or(Expression.equals(Statuses.STATUS_ID, mStatusId), - Expression.equals(Statuses.RETWEET_ID, mStatusId))); - for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - mResolver.update(uri, values, where.getSQL(), null); - } - return SingleResponse.getInstance(status); - } catch (final TwitterException e) { - return SingleResponse.getInstance(e); - } + + if (twitter == null) { + return SingleResponse.getInstance(); + } + try { + final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.destroyFavorite(mStatusId), + mAccountId, false); + final ContentValues values = new ContentValues(); + values.put(Statuses.IS_FAVORITE, false); + values.put(Statuses.FAVORITE_COUNT, status.favorite_count - 1); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, mAccountId), + Expression.or(Expression.equals(Statuses.STATUS_ID, mStatusId), + Expression.equals(Statuses.RETWEET_ID, mStatusId))); + for (final Uri uri : TwidereDataStore.STATUSES_URIS) { + mResolver.update(uri, values, where.getSQL(), null); + } + return SingleResponse.getInstance(status); + } catch (final TwitterException e) { + return SingleResponse.getInstance(e); } - return SingleResponse.getInstance(); } @Override @@ -1587,21 +1584,21 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyFriendshipTask extends ManagedAsyncTask> { - private final long mAccountId; - private final long user_id; + private final AccountId mAccountId; + private final long mUserId; - public DestroyFriendshipTask(final long accountId, final long user_id) { + public DestroyFriendshipTask(final AccountId accountId, final long userId) { super(mContext); mAccountId = accountId; - this.user_id = user_id; + mUserId = userId; } - public long getAccountId() { + public AccountId getAccountId() { return mAccountId; } public long getUserId() { - return user_id; + return mUserId; } @Override @@ -1610,12 +1607,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter != null) { try { - final User user = twitter.destroyFriendship(user_id); + final User user = twitter.destroyFriendship(mUserId); // remove user tweets and retweets Utils.setLastSeen(mContext, user.getId(), -1); final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, mAccountId), - Expression.or(Expression.equals(Statuses.USER_ID, user_id), - Expression.equals(Statuses.RETWEETED_BY_USER_ID, user_id))); + Expression.or(Expression.equals(Statuses.USER_ID, mUserId), + Expression.equals(Statuses.RETWEETED_BY_USER_ID, mUserId))); mResolver.delete(Statuses.CONTENT_URI, where.getSQL(), null); return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountId), null); } catch (final TwitterException e) { @@ -1643,10 +1640,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyMuteTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mUserId; - public DestroyMuteTask(final long accountId, final long userId) { + public DestroyMuteTask(final AccountId accountId, final long userId) { super(mContext); mAccountId = accountId; mUserId = userId; @@ -1686,10 +1683,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroySavedSearchTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mSearchId; - DestroySavedSearchTask(final long accountId, final long searchId) { + DestroySavedSearchTask(final AccountId accountId, final long searchId) { super(mContext); mAccountId = accountId; mSearchId = searchId; @@ -1722,24 +1719,24 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyStatusTask extends ManagedAsyncTask> { - private final long account_id; + private final AccountId mAccountId; + private final long mStatusId; - private final long status_id; - - public DestroyStatusTask(final long account_id, final long status_id) { + public DestroyStatusTask(final AccountId accountId, final long statusId) { super(mContext); - this.account_id = account_id; - this.status_id = status_id; + this.mAccountId = accountId; + this.mStatusId = statusId; } @Override protected SingleResponse doInBackground(final Object... params) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false); + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter == null) return SingleResponse.getInstance(); ParcelableStatus status = null; TwitterException exception = null; try { - status = ParcelableStatusUtils.fromStatus(twitter.destroyStatus(status_id), account_id, false); + status = ParcelableStatusUtils.fromStatus(twitter.destroyStatus(mStatusId), + mAccountId, false); } catch (final TwitterException e) { exception = e; } @@ -1750,8 +1747,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { values.put(Statuses.RETWEET_COUNT, status.retweet_count - 1); } for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - mResolver.delete(uri, Statuses.STATUS_ID + " = " + status_id, null); - mResolver.update(uri, values, Statuses.MY_RETWEET_ID + " = " + status_id, null); + mResolver.delete(uri, Statuses.STATUS_ID + " = " + mStatusId, null); + mResolver.update(uri, values, Statuses.MY_RETWEET_ID + " = " + mStatusId, null); } } return SingleResponse.getInstance(status, exception); @@ -1760,13 +1757,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPreExecute() { super.onPreExecute(); - mDestroyingStatusIds.put(account_id, status_id); + mDestroyingStatusIds.put(mAccountId.getId(), mStatusId); bus.post(new StatusListChangedEvent()); } @Override protected void onPostExecute(final SingleResponse result) { - mDestroyingStatusIds.remove(account_id, status_id); + mDestroyingStatusIds.remove(mAccountId.getId(), mStatusId); if (result.hasData()) { final ParcelableStatus status = result.getData(); if (status.retweet_id > 0) { @@ -1785,10 +1782,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class DestroyUserListSubscriptionTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mListId; - public DestroyUserListSubscriptionTask(final long accountId, final long listId) { + public DestroyUserListSubscriptionTask(@NonNull final AccountId accountId, final long listId) { super(mContext); mAccountId = accountId; mListId = listId; @@ -1798,16 +1795,14 @@ public class AsyncTwitterWrapper extends TwitterWrapper { protected SingleResponse doInBackground(final Object... params) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); - if (twitter != null) { - try { - final ParcelableUserList list = new ParcelableUserList( - twitter.destroyUserListSubscription(mListId), mAccountId); - return SingleResponse.getInstance(list, null); - } catch (final TwitterException e) { - return SingleResponse.getInstance(null, e); - } + if (twitter == null) return SingleResponse.getInstance(); + try { + final UserList userList = twitter.destroyUserListSubscription(mListId); + final ParcelableUserList list = ParcelableUserListUtils.from(userList, mAccountId); + return SingleResponse.getInstance(list, null); + } catch (final TwitterException e) { + return SingleResponse.getInstance(null, e); } - return SingleResponse.getInstance(); } @Override @@ -1829,10 +1824,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { static class DestroyUserListTask extends ManagedAsyncTask> { - private final long mAccountId; + private final AccountId mAccountId; private final long mListId; - public DestroyUserListTask(Context context, final long accountId, final long listId) { + public DestroyUserListTask(Context context, final AccountId accountId, final long listId) { super(context); mAccountId = accountId; mListId = listId; @@ -1840,20 +1835,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected SingleResponse doInBackground(final Object... params) { - - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, false); - if (twitter != null) { - try { - if (mListId > 0) { - final ParcelableUserList list = new ParcelableUserList(twitter.destroyUserList(mListId), - mAccountId); - return SingleResponse.getInstance(list); - } - } catch (final TwitterException e) { - return SingleResponse.getInstance(e); - } + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, + false); + if (twitter == null) return SingleResponse.getInstance(); + try { + final UserList userList = twitter.destroyUserList(mListId); + final ParcelableUserList list = ParcelableUserListUtils.from(userList, mAccountId); + return SingleResponse.getInstance(list); + } catch (final TwitterException e) { + return SingleResponse.getInstance(e); } - return SingleResponse.getInstance(); } @Override @@ -1947,69 +1938,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - class ReportMultiSpamTask extends ManagedAsyncTask> { - - private final long account_id; - private final long[] user_ids; - - public ReportMultiSpamTask(final long account_id, final long[] user_ids) { - super(mContext); - this.account_id = account_id; - this.user_ids = user_ids; - } - - @Override - protected ListResponse doInBackground(final Object... params) { - - final Bundle extras = new Bundle(); - extras.putLong(EXTRA_ACCOUNT_ID, account_id); - final List reported_users = new ArrayList<>(); - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, account_id, false); - if (twitter != null) { - for (final long user_id : user_ids) { - try { - final User user = twitter.reportSpam(user_id); - if (user == null || user.getId() <= 0) { - continue; - } - reported_users.add(user.getId()); - } catch (final TwitterException e) { - return new ListResponse<>(null, e, extras); - } - } - } - return new ListResponse<>(reported_users, null, extras); - } - - @Override - protected void onPostExecute(final ListResponse result) { - if (result != null) { - final String user_id_where = TwidereListUtils.toString(result.getData(), ',', false); - for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), - new Expression(String.format(Locale.ROOT, "%s IN (%s)", Statuses.USER_ID, user_id_where))); - mResolver.delete(uri, where.getSQL(), null); - } - Utils.showInfoMessage(mContext, R.string.reported_users_for_spam, false); - final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED); - intent.putExtra(EXTRA_USER_IDS, user_ids); - intent.putExtra(EXTRA_ACCOUNT_ID, account_id); - mContext.sendBroadcast(intent); - } - super.onPostExecute(result); - } - - } - class ReportSpamTask extends ManagedAsyncTask> { - private final long mAccountId; - private final long user_id; + private final AccountId mAccountId; + private final long mUserId; - public ReportSpamTask(final long accountId, final long user_id) { + public ReportSpamTask(final AccountId accountId, final long userId) { super(mContext); this.mAccountId = accountId; - this.user_id = user_id; + this.mUserId = userId; } @Override @@ -2017,7 +1954,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountId, false); if (twitter != null) { try { - final User user = twitter.reportSpam(user_id); + final User user = twitter.reportSpam(mUserId); return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountId), null); } catch (final TwitterException e) { return SingleResponse.getInstance(null, e); @@ -2029,11 +1966,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPostExecute(final SingleResponse result) { if (result.hasData()) { - for (final Uri uri : TwidereDataStore.STATUSES_URIS) { - final String where = Statuses.ACCOUNT_ID + " = " + mAccountId + " AND " + Statuses.USER_ID + " = " - + user_id; - mResolver.delete(uri, where, null); - } + // TODO delete cached status Utils.showInfoMessage(mContext, R.string.reported_user_for_spam, false); @@ -2048,10 +1981,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper { class RetweetStatusTask extends ManagedAsyncTask> { - private final long accountId; + private final AccountId accountId; private final long statusId; - public RetweetStatusTask(final long accountId, final long statusId) { + public RetweetStatusTask(@NonNull final AccountId accountId, final long statusId) { super(mContext); this.accountId = accountId; this.statusId = statusId; @@ -2059,13 +1992,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected SingleResponse doInBackground(final Object... params) { - if (accountId < 0) return SingleResponse.getInstance(); final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, true); if (twitter == null) { return SingleResponse.getInstance(); } try { - final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.retweetStatus(statusId), accountId, false); + final ParcelableStatus status = ParcelableStatusUtils.fromStatus(twitter.retweetStatus(statusId), + accountId, false); Utils.setLastSeen(mContext, status.mentions, System.currentTimeMillis()); final ContentValues values = new ContentValues(); values.put(Statuses.MY_RETWEET_ID, status.id); @@ -2088,19 +2021,19 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPreExecute() { super.onPreExecute(); - mCreatingRetweetIds.put(accountId, statusId); + mCreatingRetweetIds.put(accountId.getId(), statusId); bus.post(new StatusListChangedEvent()); } @Override protected void onPostExecute(final SingleResponse result) { - mCreatingRetweetIds.remove(accountId, statusId); + mCreatingRetweetIds.remove(accountId.getId(), statusId); if (result.hasData()) { final ParcelableStatus status = result.getData(); // BEGIN HotMobi final TweetEvent event = TweetEvent.create(getContext(), status, TimelineType.OTHER); event.setAction(TweetEvent.Action.RETWEET); - HotMobiLogger.getInstance(getContext()).log(accountId, event); + HotMobiLogger.getInstance(getContext()).log(accountId.getId(), event); // END HotMobi bus.post(new StatusRetweetedEvent(status)); @@ -2115,12 +2048,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { static class UpdateUserListDetailsTask extends ManagedAsyncTask> { - private final long accountId; + private final AccountId accountId; private final long listId; private final UserListUpdate update; private Context mContext; - public UpdateUserListDetailsTask(Context context, final long accountId, final long listId, UserListUpdate update) { + public UpdateUserListDetailsTask(Context context, final AccountId accountId, + final long listId, UserListUpdate update) { super(context); this.accountId = accountId; this.listId = listId; @@ -2135,7 +2069,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (twitter != null) { try { final UserList list = twitter.updateUserList(listId, update); - return SingleResponse.getInstance(new ParcelableUserList(list, accountId)); + return SingleResponse.getInstance(ParcelableUserListUtils.from(list, accountId)); } catch (final TwitterException e) { return SingleResponse.getInstance(e); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java b/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java index 68e6e73ae..0f106ea69 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java @@ -32,6 +32,7 @@ import org.mariotaku.twidere.api.twitter.model.Status; import org.mariotaku.twidere.api.twitter.model.Trend; import org.mariotaku.twidere.api.twitter.model.Trends; import org.mariotaku.twidere.api.twitter.model.User; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.Draft; import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.model.ParcelableActivityValuesCreator; @@ -146,12 +147,12 @@ public final class ContentValuesCreator implements TwidereConstants { public static ContentValues createCachedUser(final User user) { if (user == null) return null; final ContentValues values = new ContentValues(); - ParcelableUserValuesCreator.writeTo(ParcelableUserUtils.fromUser(user, -1), values); + ParcelableUserValuesCreator.writeTo(ParcelableUserUtils.fromUser(user, null), values); return values; } public static ContentValues createDirectMessage(final DirectMessage message, final long accountId, - final boolean isOutgoing) { + final String accountHost, final boolean isOutgoing) { if (message == null) return null; final ContentValues values = new ContentValues(); final User sender = message.getSender(), recipient = message.getRecipient(); @@ -159,6 +160,7 @@ public final class ContentValuesCreator implements TwidereConstants { final String sender_profile_image_url = TwitterContentUtils.getProfileImageUrl(sender); final String recipient_profile_image_url = TwitterContentUtils.getProfileImageUrl(recipient); values.put(DirectMessages.ACCOUNT_ID, accountId); + values.put(DirectMessages.ACCOUNT_HOST, accountHost); values.put(DirectMessages.MESSAGE_ID, message.getId()); values.put(DirectMessages.MESSAGE_TIMESTAMP, message.getCreatedAt().getTime()); values.put(DirectMessages.SENDER_ID, sender.getId()); @@ -237,9 +239,11 @@ public final class ContentValuesCreator implements TwidereConstants { return values; } - public static ContentValues createSavedSearch(final SavedSearch savedSearch, final long accountId) { + public static ContentValues createSavedSearch(final SavedSearch savedSearch, final long accountId, + final String accountHost) { final ContentValues values = new ContentValues(); values.put(SavedSearches.ACCOUNT_ID, accountId); + values.put(SavedSearches.ACCOUNT_HOST, accountHost); values.put(SavedSearches.SEARCH_ID, savedSearch.getId()); values.put(SavedSearches.CREATED_AT, savedSearch.getCreatedAt().getTime()); values.put(SavedSearches.NAME, savedSearch.getName()); @@ -247,17 +251,19 @@ public final class ContentValuesCreator implements TwidereConstants { return values; } - public static ContentValues[] createSavedSearches(final List savedSearches, long accountId) { + public static ContentValues[] createSavedSearches(final List savedSearches, + final long accountId, final String accountHost) { final ContentValues[] resultValuesArray = new ContentValues[savedSearches.size()]; for (int i = 0, j = savedSearches.size(); i < j; i++) { - resultValuesArray[i] = createSavedSearch(savedSearches.get(i), accountId); + resultValuesArray[i] = createSavedSearch(savedSearches.get(i), accountId, accountHost); } return resultValuesArray; } @NonNull - public static ContentValues createStatus(final Status orig, final long accountId) { - return ParcelableStatusValuesCreator.create(ParcelableStatusUtils.fromStatus(orig, accountId, false)); + public static ContentValues createStatus(final Status orig, final AccountId accountId) { + return ParcelableStatusValuesCreator.create(ParcelableStatusUtils.fromStatus(orig, + accountId, false)); } @NonNull diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java index 75211f7d1..868d53127 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/DataStoreUtils.java @@ -49,8 +49,8 @@ import org.mariotaku.sqliteqb.library.query.SQLSelectQuery; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.TwidereConstants; import org.mariotaku.twidere.api.twitter.model.Activity; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableAccount; -import org.mariotaku.twidere.model.ParcelableAccountCursorIndices; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableCredentialsCursorIndices; import org.mariotaku.twidere.model.UserFollowState; @@ -197,44 +197,46 @@ public class DataStoreUtils implements Constants { @NonNull public static long[] getNewestMessageIds(@NonNull final Context context, @NonNull final Uri uri, - @NonNull final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, DirectMessages.ACCOUNT_ID, DirectMessages.MESSAGE_ID, + @NonNull final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), + DirectMessages.ACCOUNT_ID, DirectMessages.MESSAGE_ID, new OrderBy(SQLFunctions.MAX(DirectMessages.MESSAGE_TIMESTAMP))); } @NonNull public static long[] getNewestStatusIds(@NonNull final Context context, @NonNull final Uri uri, - @NonNull final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, Statuses.ACCOUNT_ID, Statuses.STATUS_ID, + @NonNull final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), Statuses.ACCOUNT_ID, Statuses.STATUS_ID, new OrderBy(SQLFunctions.MAX(Statuses.STATUS_TIMESTAMP))); } @NonNull public static long[] getOldestMessageIds(@NonNull final Context context, @NonNull final Uri uri, - @NonNull final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, DirectMessages.ACCOUNT_ID, + @NonNull final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), DirectMessages.ACCOUNT_ID, DirectMessages.MESSAGE_ID, new OrderBy(SQLFunctions.MIN(DirectMessages.MESSAGE_TIMESTAMP))); } @NonNull public static long[] getOldestStatusIds(@NonNull final Context context, @NonNull final Uri uri, - @NonNull final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, Statuses.ACCOUNT_ID, Statuses.STATUS_ID, + @NonNull final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), Statuses.ACCOUNT_ID, Statuses.STATUS_ID, new OrderBy(SQLFunctions.MIN(Statuses.STATUS_TIMESTAMP))); } @NonNull - public static long[] getNewestActivityMaxPositions(final Context context, final Uri uri, final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, Activities.ACCOUNT_ID, + public static long[] getNewestActivityMaxPositions(final Context context, final Uri uri, + final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), Activities.ACCOUNT_ID, Activities.MAX_POSITION, new OrderBy(SQLFunctions.MAX(Activities.TIMESTAMP))); } @NonNull public static long[] getOldestActivityMaxPositions(@NonNull final Context context, @NonNull final Uri uri, - @NonNull final long[] accountIds) { - return getLongFieldArray(context, uri, accountIds, Activities.ACCOUNT_ID, + @NonNull final AccountId[] accountIds) { + return getLongFieldArray(context, uri, AccountId.getIds(accountIds), Activities.ACCOUNT_ID, Activities.MAX_POSITION, new OrderBy(SQLFunctions.MIN(Activities.TIMESTAMP))); } @@ -327,7 +329,9 @@ public class DataStoreUtils implements Constants { if (context == null) return null; final String cached = sAccountScreenNames.get(accountId); if (!isEmpty(cached)) return cached; - final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{Accounts.SCREEN_NAME}, Accounts.ACCOUNT_ID + " = " + accountId, null, null); + final String[] projection = {Accounts.SCREEN_NAME}; + final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, projection, + Accounts.ACCOUNT_ID + " = " + accountId, null, null); if (cur == null) return null; try { if (cur.getCount() > 0 && cur.moveToFirst()) { @@ -345,7 +349,7 @@ public class DataStoreUtils implements Constants { return getAccountScreenNames(context, null); } - public static String[] getAccountScreenNames(final Context context, final long[] accountIds) { + public static String[] getAccountScreenNames(final Context context, @Nullable final AccountId[] accountIds) { if (context == null) return new String[0]; final String[] cols = new String[]{Accounts.SCREEN_NAME}; final String where = accountIds != null ? Expression.in(new Column(Accounts.ACCOUNT_ID), @@ -367,16 +371,17 @@ public class DataStoreUtils implements Constants { } @NonNull - public static long[] getActivatedAccountIds(final Context context) { - if (context == null) return new long[0]; - final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{Accounts.ACCOUNT_ID}, Accounts.IS_ACTIVATED + " = 1", null, null); - if (cur == null) return new long[0]; + public static AccountId[] getActivatedAccountIds(final Context context) { + if (context == null) return new AccountId[0]; + final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, + new String[]{Accounts.ACCOUNT_ID,Accounts.ACCOUNT_HOST}, Accounts.IS_ACTIVATED + " = 1", null, null); + if (cur == null) return new AccountId[0]; try { cur.moveToFirst(); - final long[] ids = new long[cur.getCount()]; + final AccountId[] ids = new AccountId[cur.getCount()]; int i = 0; while (!cur.isAfterLast()) { - ids[i++] = cur.getLong(0); + ids[i++] = new AccountId(cur.getLong(0), cur.getString(1)); cur.moveToNext(); } return ids; @@ -634,16 +639,18 @@ public class DataStoreUtils implements Constants { } @NonNull - public static long[] getAccountIds(final Context context) { - if (context == null) return new long[0]; - final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, new String[]{Accounts.ACCOUNT_ID}, null, null, null); - if (cur == null) return new long[0]; + public static AccountId[] getAccountIds(final Context context) { + if (context == null) return new AccountId[0]; + final String[] projection = {Accounts.ACCOUNT_ID, Accounts.ACCOUNT_HOST}; + final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, projection, + null, null, null); + if (cur == null) return new AccountId[0]; try { cur.moveToFirst(); - final long[] ids = new long[cur.getCount()]; + final AccountId[] ids = new AccountId[cur.getCount()]; int i = 0; while (!cur.isAfterLast()) { - ids[i++] = cur.getLong(0); + ids[i++] = new AccountId(cur.getLong(0), cur.getString(1)); cur.moveToNext(); } return ids; @@ -688,49 +695,61 @@ public class DataStoreUtils implements Constants { final int itemLimit = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).getInt( KEY_DATABASE_ITEM_LIMIT, DEFAULT_DATABASE_ITEM_LIMIT); - for (final long accountId : getAccountIds(context)) { + for (final AccountId accountId : getAccountIds(context)) { // Clean statuses. for (final Uri uri : STATUSES_URIS) { if (CachedStatuses.CONTENT_URI.equals(uri)) { continue; } final String table = getTableNameByUri(uri); - final Expression accountWhere = new Expression(Statuses.ACCOUNT_ID + " = " + accountId); + final Expression accountWhere = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_ID), + Expression.equalsArgs(Statuses.ACCOUNT_HOST)); final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder(); qb.select(new Column(Statuses._ID)) .from(new Tables(table)) - .where(Expression.equals(Statuses.ACCOUNT_ID, accountId)) + .where(accountWhere) .orderBy(new OrderBy(Statuses.STATUS_ID, false)) .limit(itemLimit); final Expression where = Expression.and(Expression.lesserThan(new Column(Statuses._ID), - SQLQueryBuilder.select(SQLFunctions.MIN(new Column(Statuses._ID))).from(qb.build()).build()), accountWhere); - resolver.delete(uri, where.getSQL(), null); + SQLQueryBuilder.select(SQLFunctions.MIN(new Column(Statuses._ID))).from(qb.build()).build()), + accountWhere); + final String[] whereArgs = {String.valueOf(accountId.getId()), accountId.getHost(), + String.valueOf(accountId.getId()), accountId.getHost()}; + resolver.delete(uri, where.getSQL(), whereArgs); } for (final Uri uri : ACTIVITIES_URIS) { final String table = getTableNameByUri(uri); - final Expression accountWhere = new Expression(Activities.ACCOUNT_ID + " = " + accountId); + final Expression accountWhere = Expression.and(Expression.equalsArgs(Accounts.ACCOUNT_ID), + Expression.equalsArgs(Accounts.ACCOUNT_HOST)); final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder(); qb.select(new Column(Activities._ID)) .from(new Tables(table)) - .where(Expression.equals(Activities.ACCOUNT_ID, accountId)) + .where(accountWhere) .orderBy(new OrderBy(Activities.TIMESTAMP, false)) .limit(itemLimit); final Expression where = Expression.and(Expression.lesserThan(new Column(Activities._ID), - SQLQueryBuilder.select(SQLFunctions.MIN(new Column(Activities._ID))).from(qb.build()).build()), accountWhere); - resolver.delete(uri, where.getSQL(), null); + SQLQueryBuilder.select(SQLFunctions.MIN(new Column(Activities._ID))) + .from(qb.build()).build()), accountWhere); + final String[] whereArgs = {String.valueOf(accountId.getId()), accountId.getHost(), + String.valueOf(accountId.getId()), accountId.getHost()}; + resolver.delete(uri, where.getSQL(), whereArgs); } for (final Uri uri : DIRECT_MESSAGES_URIS) { final String table = getTableNameByUri(uri); - final Expression accountWhere = new Expression(DirectMessages.ACCOUNT_ID + " = " + accountId); + final Expression accountWhere = Expression.and(Expression.equalsArgs(DirectMessages.ACCOUNT_ID), + Expression.equalsArgs(DirectMessages.ACCOUNT_HOST)); final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder(); qb.select(new Column(DirectMessages._ID)) .from(new Tables(table)) - .where(Expression.equals(DirectMessages.ACCOUNT_ID, accountId)) + .where(accountWhere) .orderBy(new OrderBy(DirectMessages.MESSAGE_ID, false)) .limit(itemLimit * 10); final Expression where = Expression.and(Expression.lesserThan(new Column(DirectMessages._ID), - SQLQueryBuilder.select(SQLFunctions.MIN(new Column(DirectMessages._ID))).from(qb.build()).build()), accountWhere); - resolver.delete(uri, where.getSQL(), null); + SQLQueryBuilder.select(SQLFunctions.MIN(new Column(DirectMessages._ID))) + .from(qb.build()).build()), accountWhere); + final String[] whereArgs = {String.valueOf(accountId.getId()), accountId.getHost(), + String.valueOf(accountId.getId()), accountId.getHost()}; + resolver.delete(uri, where.getSQL(), whereArgs); } } // Clean cached values. @@ -787,7 +806,8 @@ public class DataStoreUtils implements Constants { if (sortExpression != null) { builder.orderBy(sortExpression); } - final Cursor cur = resolver.query(Uri.withAppendedPath(TwidereDataStore.CONTENT_URI_RAW_QUERY, builder.buildSQL()), null, null, selectionArgs, null); + final Cursor cur = resolver.query(Uri.withAppendedPath(TwidereDataStore.CONTENT_URI_RAW_QUERY, + builder.buildSQL()), null, null, selectionArgs, null); if (cur == null) return messageIds; try { while (cur.moveToNext()) { @@ -818,20 +838,6 @@ public class DataStoreUtils implements Constants { } } - public static ParcelableAccount getAccount(final Context context, final long accountId) { - if (context == null) return null; - final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, Accounts.COLUMNS, Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(), null, null); - if (cur == null) return null; - try { - if (cur.moveToFirst()) { - return ParcelableAccountCursorIndices.fromCursor(cur); - } - } finally { - cur.close(); - } - return null; - } - @NonNull public static long[] getAccountIds(final ParcelableAccount[] accounts) { final long[] ids = new long[accounts.length]; @@ -841,45 +847,6 @@ public class DataStoreUtils implements Constants { return ids; } - @NonNull - public static ParcelableAccount[] getAccounts(final Context context, final boolean activatedOnly, - final boolean officialKeyOnly) { - final List list = getAccountsList(context, activatedOnly, officialKeyOnly); - return list.toArray(new ParcelableAccount[list.size()]); - } - - @NonNull - public static ParcelableAccount[] getAccounts(@Nullable final Context context, @Nullable final long... accountIds) { - if (context == null) return new ParcelableAccount[0]; - final String where = accountIds != null ? Expression.in(new Column(Accounts.ACCOUNT_ID), - new RawItemArray(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)); - } - - @NonNull - public static ParcelableAccount[] getAccounts(@Nullable final Cursor cursor) { - if (cursor == null) return new ParcelableAccount[0]; - return getAccounts(cursor, new ParcelableAccountCursorIndices(cursor)); - } - - @NonNull - public static ParcelableAccount[] getAccounts(@Nullable final Cursor cursor, @Nullable final ParcelableAccountCursorIndices indices) { - if (cursor == null || indices == null) return new ParcelableAccount[0]; - try { - cursor.moveToFirst(); - final ParcelableAccount[] names = new ParcelableAccount[cursor.getCount()]; - while (!cursor.isAfterLast()) { - names[cursor.getPosition()] = indices.newObject(cursor); - cursor.moveToNext(); - } - return names; - } finally { - cursor.close(); - } - } - public static List getAccountsList(final Context context, final boolean activatedOnly) { return getAccountsList(context, activatedOnly, false); } @@ -910,14 +877,27 @@ public class DataStoreUtils implements Constants { } @Nullable - public static ParcelableCredentials getCredentials(final Context context, final long accountId) { - if (context == null || accountId < 0) return null; + public static ParcelableCredentials getCredentials(@NonNull final Context context, final AccountId accountId) { + return getCredentials(context, accountId.getId(), accountId.getHost()); + } + + @Nullable + public static ParcelableCredentials getCredentials(@NonNull final Context context, final long accountId, + final String accountHost) { Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, Accounts.COLUMNS, Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(), null, null); if (cur == null) return null; try { + ParcelableCredentialsCursorIndices i = new ParcelableCredentialsCursorIndices(cur); + cur.moveToFirst(); + while (!cur.isAfterLast()) { + if (TextUtils.equals(cur.getString(i.account_host), accountHost)) { + return i.newObject(cur); + } + cur.moveToNext(); + } if (cur.moveToFirst()) { - return ParcelableCredentialsCursorIndices.fromCursor(cur); + return i.newObject(cur); } } finally { cur.close(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java b/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java index 6be252330..f88d8a16c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ErrorInfoStore.java @@ -7,6 +7,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.model.AccountId; /** @@ -45,6 +46,15 @@ public class ErrorInfoStore { put(key + "_" + extraId, code); } + public void put(String key, AccountId extraId, int code) { + final String host = extraId.getHost(); + if (host == null) { + put(key, extraId.getId(), code); + } else { + put(key + "_" + extraId.getId() + "_" + host, code); + } + } + @Nullable public static DisplayErrorInfo getErrorInfo(@NonNull Context context, int code) { switch (code) { @@ -68,6 +78,15 @@ public class ErrorInfoStore { remove(key + "_" + extraId); } + public void remove(String key, AccountId extraId) { + final String host = extraId.getHost(); + if (host == null) { + remove(key, extraId.getId()); + } else { + remove(key + "_" + extraId.getId() + "_" + host); + } + } + public void remove(String key) { mPreferences.edit().remove(key).apply(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java index b29188032..f031b91b7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java @@ -21,6 +21,7 @@ import org.mariotaku.twidere.TwidereConstants; 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.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; @@ -48,7 +49,8 @@ public class IntentUtils implements Constants { } public static void openUserProfile(final Context context, final ParcelableUser user, - final Bundle activityOptions, final boolean newDocument) { + final Bundle activityOptions, final boolean newDocument, + @UserFragment.Referral final String referral) { if (context == null || user == null) return; final Bundle extras = new Bundle(); extras.putParcelable(EXTRA_USER, user); @@ -65,6 +67,7 @@ public class IntentUtils implements Constants { final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); intent.setExtrasClassLoader(context.getClassLoader()); intent.putExtras(extras); + intent.putExtra(EXTRA_REFERRAL, referral); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); } @@ -77,10 +80,12 @@ public class IntentUtils implements Constants { public static void openUserProfile(final Context context, final long accountId, final long userId, final String screenName, final Bundle activityOptions, - final boolean newDocument) { + final boolean newDocument, + @UserFragment.Referral final String referral) { if (context == null || accountId <= 0 || userId <= 0 && isEmpty(screenName)) return; final Uri uri = LinkCreator.getTwidereUserLink(accountId, userId, screenName); final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra(EXTRA_REFERRAL, referral); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java index a9002b47f..8cdbf5a81 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java @@ -55,6 +55,7 @@ import org.mariotaku.twidere.graphic.ActionIconDrawable; import org.mariotaku.twidere.graphic.PaddingDrawable; import org.mariotaku.twidere.menu.SupportStatusShareProvider; import org.mariotaku.twidere.menu.support.FavoriteItemProvider; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.util.menu.TwidereMenuInfo; @@ -137,7 +138,8 @@ public class MenuUtils implements Constants { @NonNull final ParcelableStatus status, @NonNull UserColorNameManager manager, @NonNull final AsyncTwitterWrapper twitter) { - final ParcelableCredentials account = DataStoreUtils.getCredentials(context, status.account_id); + final ParcelableCredentials account = DataStoreUtils.getCredentials(context, new AccountId(status.account_id, + status.account_host)); if (account == null) return; setupForStatus(context, preferences, menu, status, account, manager, twitter); } @@ -255,9 +257,11 @@ public class MenuUtils implements Constants { } case R.id.retweet: { if (Utils.isMyRetweet(status)) { - twitter.cancelRetweetAsync(status.account_id, status.id, status.my_retweet_id); + twitter.cancelRetweetAsync(new AccountId(status.account_id, status.account_host), + status.id, status.my_retweet_id); } else { - twitter.retweetStatusAsync(status.account_id, status.id); + twitter.retweetStatusAsync(new AccountId(status.account_id, status.account_host), + status.id); } break; } @@ -282,7 +286,8 @@ public class MenuUtils implements Constants { ((FavoriteItemProvider) provider).invokeItem(item, new AbsStatusesFragment.DefaultOnLikedListener(twitter, status)); } else { - twitter.createFavoriteAsync(status.account_id, status.id); + twitter.createFavoriteAsync(new AccountId(status.account_id, status.account_host), + status.id); } } break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java b/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java index 4bd30f408..6d000cdcf 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java @@ -28,6 +28,7 @@ import android.support.annotation.Nullable; import org.apache.commons.lang3.math.NumberUtils; import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.fragment.support.UserFragment; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.util.ParcelableMediaUtils; import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener; @@ -62,7 +63,8 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants { switch (type) { case TwidereLinkify.LINK_TYPE_MENTION: { - IntentUtils.openUserProfile(context, accountId, -1, link, null, true); + IntentUtils.openUserProfile(context, accountId, -1, link, null, true, + UserFragment.Referral.USER_MENTION); break; } case TwidereLinkify.LINK_TYPE_HASHTAG: { @@ -90,7 +92,8 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants { break; } case TwidereLinkify.LINK_TYPE_USER_ID: { - IntentUtils.openUserProfile(context, accountId, NumberUtils.toLong(link, -1), null, null, true); + IntentUtils.openUserProfile(context, accountId, NumberUtils.toLong(link, -1), null, + null, true, UserFragment.Referral.USER_MENTION); break; } case TwidereLinkify.LINK_TYPE_STATUS: { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java index b9710509a..150332e9f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java @@ -148,8 +148,10 @@ public final class TwidereLinkify implements Constants { return applyUserProfileLink(text, accountId, extraId, userId, screenName, highlightOption, mOnLinkClickListener); } - public final SpannableString applyUserProfileLink(final CharSequence text, final long accountId, final long extraId, - final long userId, final String screenName, final int highlightOption, final OnLinkClickListener listener) { + public final SpannableString applyUserProfileLink(final CharSequence text, final long accountId, + final long extraId, final long userId, + final String screenName, final int highlightOption, + final OnLinkClickListener listener) { final SpannableString string = SpannableString.valueOf(text); final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); for (final URLSpan span : spans) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java index bc075b4e7..0c0ea5d5e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java @@ -39,6 +39,7 @@ import org.mariotaku.twidere.api.twitter.auth.OAuthAuthorization; import org.mariotaku.twidere.api.twitter.auth.OAuthEndpoint; import org.mariotaku.twidere.api.twitter.auth.OAuthToken; import org.mariotaku.twidere.api.twitter.util.TwitterConverterFactory; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ConsumerKeyType; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; @@ -87,18 +88,20 @@ public class TwitterAPIFactory implements TwidereConstants { public static Twitter getDefaultTwitterInstance(final Context context, final boolean includeEntities, final boolean includeRetweets) { if (context == null) return null; - return getTwitterInstance(context, Utils.getDefaultAccountId(context), includeEntities, includeRetweets); + final AccountId accountId = Utils.getDefaultAccountId(context); + if (accountId == null) return null; + return getTwitterInstance(context, accountId, includeEntities, includeRetweets); } @WorkerThread - public static Twitter getTwitterInstance(final Context context, final long accountId, + public static Twitter getTwitterInstance(final Context context, final AccountId accountId, final boolean includeEntities) { return getTwitterInstance(context, accountId, includeEntities, true); } @Nullable @WorkerThread - public static Twitter getTwitterInstance(final Context context, final long accountId, + public static Twitter getTwitterInstance(final Context context, final AccountId accountId, final boolean includeEntities, final boolean includeRetweets) { return getTwitterInstance(context, accountId, includeEntities, includeRetweets, Twitter.class); @@ -106,11 +109,12 @@ public class TwitterAPIFactory implements TwidereConstants { @Nullable @WorkerThread - public static T getTwitterInstance(final Context context, final long accountId, - final boolean includeEntities, - final boolean includeRetweets, Class cls) { + public static T getTwitterInstance(final Context context, final AccountId accountId, + final boolean includeEntities, final boolean includeRetweets, + Class cls) { if (context == null) return null; - final ParcelableCredentials credentials = DataStoreUtils.getCredentials(context, accountId); + final ParcelableCredentials credentials = DataStoreUtils.getCredentials(context, + accountId.getId(), accountId.getHost()); final HashMap extraParams = new HashMap<>(); extraParams.put("include_entities", String.valueOf(includeEntities)); extraParams.put("include_retweets", String.valueOf(includeRetweets)); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java index 3d218b758..00a3bf3cf 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java @@ -29,13 +29,14 @@ import org.mariotaku.restfu.http.mime.FileBody; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; -import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.api.twitter.model.DirectMessage; 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.model.User; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.ListResponse; +import org.mariotaku.twidere.model.RefreshTaskParam; import org.mariotaku.twidere.model.SingleResponse; import org.mariotaku.twidere.provider.TwidereDataStore.Notifications; import org.mariotaku.twidere.provider.TwidereDataStore.UnreadCounts; @@ -63,8 +64,9 @@ public class TwitterWrapper implements Constants { return context.getContentResolver().delete(uri, null, null); } - public static SingleResponse deleteProfileBannerImage(final Context context, final long account_id) { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, account_id, false); + public static SingleResponse deleteProfileBannerImage(final Context context, + final AccountId accountId) { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, false); if (twitter == null) return new SingleResponse<>(false, null); try { twitter.removeProfileBannerImage(); @@ -159,13 +161,6 @@ public class TwitterWrapper implements Constants { } } - public static void updateProfileBannerImage(final Context context, final long accountId, - final Uri imageUri, final boolean deleteImage) - throws FileNotFoundException, TwitterException { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, false); - updateProfileBannerImage(context, twitter, imageUri, deleteImage); - } - public static void updateProfileBannerImage(final Context context, final Twitter twitter, final Uri imageUri, final boolean deleteImage) throws FileNotFoundException, TwitterException { @@ -202,31 +197,24 @@ public class TwitterWrapper implements Constants { } } - public static User updateProfileImage(final Context context, final long accountId, - final Uri imageUri, final boolean deleteImage) - throws FileNotFoundException, TwitterException { - final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true); - return updateProfileImage(context, twitter, imageUri, deleteImage); - } - public static final class MessageListResponse extends TwitterListResponse { public final boolean truncated; - public MessageListResponse(final long accountId, final Exception exception) { + public MessageListResponse(final AccountId accountId, final Exception exception) { this(accountId, -1, -1, null, false, exception); } - public MessageListResponse(final long accountId, final List list) { + public MessageListResponse(final AccountId accountId, final List list) { this(accountId, -1, -1, list, false, null); } - public MessageListResponse(final long accountId, final long maxId, final long sinceId, + public MessageListResponse(final AccountId accountId, final long maxId, final long sinceId, final List list, final boolean truncated) { this(accountId, maxId, sinceId, list, truncated, null); } - MessageListResponse(final long accountId, final long maxId, final long sinceId, + MessageListResponse(final AccountId accountId, final long maxId, final long sinceId, final List list, final boolean truncated, final Exception exception) { super(accountId, maxId, sinceId, list, exception); this.truncated = truncated; @@ -238,20 +226,20 @@ public class TwitterWrapper implements Constants { public final boolean truncated; - public StatusListResponse(final long accountId, final Exception exception) { + public StatusListResponse(final AccountId accountId, final Exception exception) { this(accountId, -1, -1, null, false, exception); } - public StatusListResponse(final long accountId, final List list) { + public StatusListResponse(final AccountId accountId, final List list) { this(accountId, -1, -1, list, false, null); } - public StatusListResponse(final long accountId, final long maxId, final long sinceId, + public StatusListResponse(final AccountId accountId, final long maxId, final long sinceId, final List list, final boolean truncated) { this(accountId, maxId, sinceId, list, truncated, null); } - StatusListResponse(final long accountId, final long maxId, final long sinceId, final List list, + StatusListResponse(final AccountId accountId, final long maxId, final long sinceId, final List list, final boolean truncated, final Exception exception) { super(accountId, maxId, sinceId, list, exception); this.truncated = truncated; @@ -259,45 +247,24 @@ public class TwitterWrapper implements Constants { } - public static final class ActivityListResponse extends TwitterListResponse { - - public final boolean truncated; - - public ActivityListResponse(final long accountId, final Exception exception) { - this(accountId, -1, -1, null, false, exception); - } - - public ActivityListResponse(final long accountId, final List list) { - this(accountId, -1, -1, list, false, null); - } - - public ActivityListResponse(final long accountId, final long maxId, final long sinceId, - final List list, final boolean truncated) { - this(accountId, maxId, sinceId, list, truncated, null); - } - - ActivityListResponse(final long accountId, final long maxId, final long sinceId, final List list, - final boolean truncated, final Exception exception) { - super(accountId, maxId, sinceId, list, exception); - this.truncated = truncated; - } - - } - public static class TwitterListResponse extends ListResponse { - public final long accountId, maxId, sinceId; + public final AccountId accountId; + public final long maxId; + public final long sinceId; - public TwitterListResponse(final long accountId, final Exception exception) { + public TwitterListResponse(final AccountId accountId, + final Exception exception) { this(accountId, -1, -1, null, exception); } - public TwitterListResponse(final long accountId, final long maxId, final long sinceId, final List list) { + public TwitterListResponse(final AccountId accountId, final long maxId, + final long sinceId, final List list) { this(accountId, maxId, sinceId, list, null); } - TwitterListResponse(final long accountId, final long maxId, final long sinceId, final List list, - final Exception exception) { + TwitterListResponse(final AccountId accountId, final long maxId, + final long sinceId, final List list, final Exception exception) { super(list, exception); this.accountId = accountId; this.maxId = maxId; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java index 980349e1b..dcd9b91cd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -162,6 +162,7 @@ import org.mariotaku.twidere.fragment.support.UserProfileEditorFragment; import org.mariotaku.twidere.fragment.support.UserTimelineFragment; import org.mariotaku.twidere.fragment.support.UsersListFragment; import org.mariotaku.twidere.graphic.PaddingDrawable; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.model.AccountPreferences; import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableCredentials; @@ -503,6 +504,7 @@ public final class Utils implements Constants { if (!args.containsKey(EXTRA_USER_ID)) { args.putLong(EXTRA_USER_ID, NumberUtils.toLong(param_user_id, -1)); } + args.putString(EXTRA_REFERRAL, intent.getStringExtra(EXTRA_REFERRAL)); break; } case LINK_ID_USER_LIST_MEMBERSHIPS: { @@ -765,9 +767,9 @@ public final class Utils implements Constants { if (paramAccountName != null) { args.putLong(EXTRA_ACCOUNT_ID, DataStoreUtils.getAccountId(context, paramAccountName)); } else if (isAccountIdRequired) { - final long accountId = getDefaultAccountId(context); + final AccountId accountId = getDefaultAccountId(context); if (isMyAccount(context, accountId)) { - args.putLong(EXTRA_ACCOUNT_ID, accountId); + args.putLong(EXTRA_ACCOUNT_ID, accountId.getId()); } } } @@ -786,11 +788,11 @@ public final class Utils implements Constants { public static String getReadPositionTagWithAccounts(@ReadPositionTag String tag, Bundle args) { - final long[] accountIds = getAccountIds(args); + final AccountId[] accountIds = getAccountIds(args); return getReadPositionTagWithAccounts(tag, accountIds); } - public static long[] getAccountIds(Bundle args) { + public static AccountId[] getAccountIds(Bundle args) { final long[] accountIds; if (args.containsKey(EXTRA_ACCOUNT_IDS)) { accountIds = args.getLongArray(EXTRA_ACCOUNT_IDS); @@ -804,11 +806,10 @@ public final class Utils implements Constants { @Nullable public static String getReadPositionTagWithAccounts(@Nullable final String tag, - final long... accountIds) { + final AccountId... accountIds) { if (tag == null) return null; - if (accountIds == null || accountIds.length == 0 || (accountIds.length == 1 && accountIds[0] < 0)) - return tag; - final long[] accountIdsClone = accountIds.clone(); + if (ArrayUtils.isEmpty(accountIds)) return tag; + final AccountId[] accountIdsClone = accountIds.clone(); Arrays.sort(accountIdsClone); return tag + "_" + TwidereArrayUtils.toString(accountIdsClone, '_', false); } @@ -819,7 +820,7 @@ public final class Utils implements Constants { long... accountIds) { if (tag == null) return null; if (accountIds == null || accountIds.length == 0 || (accountIds.length == 1 && accountIds[0] < 0)) { - final long[] activatedIds = DataStoreUtils.getActivatedAccountIds(context); + final AccountId[] activatedIds = DataStoreUtils.getActivatedAccountIds(context); Arrays.sort(activatedIds); return tag + "_" + TwidereArrayUtils.toString(activatedIds, '_', false); } @@ -871,7 +872,8 @@ public final class Utils implements Constants { } @NonNull - public static ParcelableStatus findStatus(final Context context, final long accountId, final long statusId) + public static ParcelableStatus findStatus(final Context context, final AccountId accountId, + final String accountHost, final long statusId) throws TwitterException { if (context == null) throw new NullPointerException(); final ParcelableStatus cached = findStatusInDatabases(context, accountId, statusId); @@ -879,7 +881,7 @@ public final class Utils implements Constants { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true); if (twitter == null) throw new TwitterException("Account does not exist"); final Status status = twitter.showStatus(statusId); - final String where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId), + final String where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId.getId()), Expression.equals(Statuses.STATUS_ID, statusId)).getSQL(); final ContentResolver resolver = context.getContentResolver(); resolver.delete(CachedStatuses.CONTENT_URI, where, null); @@ -888,12 +890,12 @@ public final class Utils implements Constants { } @Nullable - public static ParcelableStatus findStatusInDatabases(final Context context, final long accountId, + public static ParcelableStatus findStatusInDatabases(final Context context, final AccountId accountId, final long statusId) { if (context == null) return null; final ContentResolver resolver = context.getContentResolver(); ParcelableStatus status = null; - final String where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId), + final String where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId.getId()), Expression.equals(Statuses.STATUS_ID, statusId)).getSQL(); for (final Uri uri : STATUSES_URIS) { final Cursor cur = resolver.query(uri, Statuses.COLUMNS, where, null, null); @@ -970,7 +972,7 @@ public final class Utils implements Constants { return hasNavBar(context); } - public static boolean isOfficialCredentials(@NonNull final Context context, final long accountId) { + public static boolean isOfficialCredentials(@NonNull final Context context, final AccountId accountId) { final ParcelableCredentials credentials = DataStoreUtils.getCredentials(context, accountId); if (credentials == null) return false; return isOfficialCredentials(context, credentials); @@ -1115,21 +1117,30 @@ public final class Utils implements Constants { return new Columns(columns); } - public static long getDefaultAccountId(final Context context) { - if (context == null) return -1; - final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + @Nullable + public static AccountId getDefaultAccountId(final Context context) { + if (context == null) return null; + final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, + Context.MODE_PRIVATE); final long accountId = prefs.getLong(KEY_DEFAULT_ACCOUNT_ID, -1); - final long[] accountIds = DataStoreUtils.getAccountIds(context); + final String accountHost = prefs.getString(KEY_DEFAULT_ACCOUNT_HOST, null); + final AccountId[] accountIds = DataStoreUtils.getAccountIds(context); + int idMatchIdx = -1; + for (int i = 0, accountIdsLength = accountIds.length; i < accountIdsLength; i++) { + AccountId id = accountIds[i]; + if (accountId == id.getId()) { + idMatchIdx = i; + if (TextUtils.equals(accountHost, id.getHost())) return id; + } + } + if (idMatchIdx != -1) { + return accountIds[idMatchIdx]; + } if (accountIds.length > 0 && !ArrayUtils.contains(accountIds, accountId)) { /* TODO: this is just a quick fix */ return accountIds[0]; } - return accountId; - } - - public static String getDefaultAccountScreenName(final Context context) { - if (context == null) return null; - return DataStoreUtils.getAccountScreenName(context, getDefaultAccountId(context)); + return null; } public static int getDefaultTextSize(final Context context) { @@ -1537,7 +1548,7 @@ public final class Utils implements Constants { } public static boolean hasAutoRefreshAccounts(final Context context) { - final long[] accountIds = DataStoreUtils.getAccountIds(context); + final AccountId[] accountIds = DataStoreUtils.getAccountIds(context); return !ArrayUtils.isEmpty(AccountPreferences.getAutoRefreshEnabledAccountIds(context, accountIds)); } @@ -1588,10 +1599,10 @@ public final class Utils implements Constants { } } - public static boolean isMyAccount(final Context context, final long accountId) { - if (context == null) return false; + public static boolean isMyAccount(final Context context, @Nullable final AccountId accountId) { + if (context == null || accountId == null) return false; final ContentResolver resolver = context.getContentResolver(); - final String where = Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(); + final String where = Expression.equals(Accounts.ACCOUNT_ID, accountId.getId()).getSQL(); final String[] projection = new String[0]; final Cursor cur = resolver.query(Accounts.CONTENT_URI, projection, where, null, null); try { @@ -1647,9 +1658,9 @@ public final class Utils implements Constants { public static boolean isUserLoggedIn(final Context context, final long accountId) { if (context == null) return false; - final long[] ids = DataStoreUtils.getAccountIds(context); - for (final long id : ids) { - if (id == accountId) return true; + final AccountId[] ids = DataStoreUtils.getAccountIds(context); + for (final AccountId id : ids) { + if (id.getId() == accountId) return true; } return false; } @@ -2674,6 +2685,12 @@ public final class Utils implements Constants { return !ConnectivityManagerCompat.isActiveNetworkMetered(cm) || !preferences.getBoolean(KEY_BANDWIDTH_SAVING_MODE); } + public static Expression getAccountCompareExpression() { + return Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_ID), + Expression.or(Expression.isNull(new Column(Statuses.ACCOUNT_HOST)), + Expression.equalsArgs(Statuses.ACCOUNT_HOST))); + } + static class UtilsL { @TargetApi(Build.VERSION_CODES.LOLLIPOP) diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java index 22d7e5daf..b03fb0d0a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/ApplicationModule.java @@ -188,12 +188,9 @@ public class ApplicationModule implements Constants { @Provides @Singleton - public AsyncTwitterWrapper asyncTwitterWrapper(UserColorNameManager userColorNameManager, - ReadStateManager readStateManager, - Bus bus, SharedPreferencesWrapper preferences, - AsyncTaskManager asyncTaskManager, ErrorInfoStore errorInfoStore) { - return new AsyncTwitterWrapper(application, userColorNameManager, bus, - preferences, asyncTaskManager, errorInfoStore); + public AsyncTwitterWrapper asyncTwitterWrapper(Bus bus, SharedPreferencesWrapper preferences, + AsyncTaskManager asyncTaskManager) { + return new AsyncTwitterWrapper(application, bus, preferences, asyncTaskManager); } @Provides diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ComposeEditText.java b/twidere/src/main/java/org/mariotaku/twidere/view/ComposeEditText.java index 26e159a67..2c437efc6 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ComposeEditText.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ComposeEditText.java @@ -33,6 +33,7 @@ import android.widget.AdapterView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter; +import org.mariotaku.twidere.model.AccountId; import org.mariotaku.twidere.util.EmojiSupportUtils; import org.mariotaku.twidere.util.widget.StatusTextTokenizer; import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView; @@ -40,7 +41,7 @@ import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView; public class ComposeEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView { private ComposeAutoCompleteAdapter mAdapter; - private long mAccountId; + private AccountId mAccountId; public ComposeEditText(final Context context) { this(context, null); @@ -69,7 +70,7 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView implemen setSupportBackgroundTintList(color); } - public void setAccountId(long accountId) { + public void setAccountId(AccountId accountId) { mAccountId = accountId; updateAccountId(); } diff --git a/twidere/src/main/res/layout/card_item_status_common.xml b/twidere/src/main/res/layout/card_item_status_common.xml index 517356211..2b97bd860 100644 --- a/twidere/src/main/res/layout/card_item_status_common.xml +++ b/twidere/src/main/res/layout/card_item_status_common.xml @@ -80,6 +80,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="@dimen/element_spacing_normal" android:layout_marginRight="@dimen/element_spacing_normal" + android:layout_marginTop="@dimen/element_spacing_xsmall" android:layout_toEndOf="@+id/status_info_space" android:layout_toRightOf="@+id/status_info_space" android:ellipsize="end" diff --git a/twidere/src/main/res/values/themes_base_appcompat.xml b/twidere/src/main/res/values/themes_base_appcompat.xml index 5f6ac7e73..87102bc9e 100644 --- a/twidere/src/main/res/values/themes_base_appcompat.xml +++ b/twidere/src/main/res/values/themes_base_appcompat.xml @@ -23,6 +23,7 @@