diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/Draft.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/Draft.java index fcb5a6953..ccfbf7048 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/Draft.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/Draft.java @@ -120,7 +120,8 @@ public class Draft implements Parcelable { } }; - @StringDef({Action.UPDATE_STATUS, Action.REPLY, Action.QUOTE, Action.SEND_DIRECT_MESSAGE}) + @StringDef({Action.UPDATE_STATUS, Action.REPLY, Action.QUOTE, Action.SEND_DIRECT_MESSAGE, + Action.FAVORITE, Action.RETWEET}) @Retention(RetentionPolicy.SOURCE) public @interface Action { @@ -131,6 +132,8 @@ public class Draft implements Parcelable { String QUOTE = "quote"; String SEND_DIRECT_MESSAGE = "send_direct_message"; String SEND_DIRECT_MESSAGE_COMPAT = "2"; + String FAVORITE = "favorite"; + String RETWEET = "retweet"; } } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/StatusObjectExtras.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/StatusObjectExtras.java new file mode 100644 index 000000000..89834745f --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/StatusObjectExtras.java @@ -0,0 +1,43 @@ +package org.mariotaku.twidere.model.draft; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.bluelinelabs.logansquare.annotation.JsonField; +import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; + +import org.mariotaku.twidere.model.ParcelableStatus; + +/** + * Created by mariotaku on 2017/2/7. + */ + +@ParcelablePlease +@JsonObject +public class StatusObjectExtras implements ActionExtras, Parcelable { + @JsonField(name = "status") + public ParcelableStatus status; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + StatusObjectExtrasParcelablePlease.writeToParcel(this, dest, flags); + } + + public static final Creator CREATOR = new Creator() { + public StatusObjectExtras createFromParcel(Parcel source) { + StatusObjectExtras target = new StatusObjectExtras(); + StatusObjectExtrasParcelablePlease.readFromParcel(target, source); + return target; + } + + public StatusObjectExtras[] newArray(int size) { + return new StatusObjectExtras[size]; + } + }; +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/util/DraftExtrasConverter.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/util/DraftExtrasConverter.java index 70708443b..1700b0ea4 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/util/DraftExtrasConverter.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/util/DraftExtrasConverter.java @@ -10,6 +10,7 @@ import org.mariotaku.library.objectcursor.converter.CursorFieldConverter; import org.mariotaku.twidere.model.Draft; import org.mariotaku.twidere.model.draft.ActionExtras; import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras; +import org.mariotaku.twidere.model.draft.StatusObjectExtras; import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras; import org.mariotaku.twidere.provider.TwidereDataStore.Drafts; @@ -26,17 +27,21 @@ public class DraftExtrasConverter implements CursorFieldConverter final String json = cursor.getString(columnIndex); if (TextUtils.isEmpty(actionType) || TextUtils.isEmpty(json)) return null; switch (actionType) { - case "0": - case "1": + case Draft.Action.UPDATE_STATUS_COMPAT_1: + case Draft.Action.UPDATE_STATUS_COMPAT_2: case Draft.Action.UPDATE_STATUS: case Draft.Action.REPLY: case Draft.Action.QUOTE: { return LoganSquare.parse(json, UpdateStatusActionExtras.class); } - case "2": + case Draft.Action.SEND_DIRECT_MESSAGE_COMPAT: case Draft.Action.SEND_DIRECT_MESSAGE: { return LoganSquare.parse(json, SendDirectMessageActionExtras.class); } + case Draft.Action.FAVORITE: + case Draft.Action.RETWEET: { + return LoganSquare.parse(json, StatusObjectExtras.class); + } } return null; } diff --git a/twidere/build.gradle b/twidere/build.gradle index 946405561..b11df75d4 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -176,7 +176,7 @@ dependencies { compile "com.github.mariotaku.CommonsLibrary:text:$mariotaku_commons_library_version" compile "com.github.mariotaku.CommonsLibrary:text-kotlin:$mariotaku_commons_library_version" compile 'com.github.mariotaku:KPreferences:0.9.5' - compile 'com.github.mariotaku:Chameleon:0.9.13' + compile 'com.github.mariotaku:Chameleon:0.9.14' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'nl.komponents.kovenant:kovenant:3.3.0' compile 'nl.komponents.kovenant:kovenant-android:3.3.0' 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 05abf0b04..2a2a07ffb 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -1341,31 +1341,28 @@ public class AsyncTwitterWrapper extends TwitterWrapper { private class RetweetStatusTask extends ManagedAsyncTask> { - private final UserKey mAccountKey; - private final String mStatusId; + private final UserKey accountKey; + private final String statusId; RetweetStatusTask(@NonNull Context context, @NonNull final UserKey accountKey, final String statusId) { super(context); - this.mAccountKey = accountKey; - this.mStatusId = statusId; + this.accountKey = accountKey; + this.statusId = statusId; } @Override protected SingleResponse doInBackground(final Object... params) { final ContentResolver resolver = getContext().getContentResolver(); final AccountDetails details = AccountUtils.getAccountDetails(AccountManager.get(getContext()), - mAccountKey, true); - if (details == null) return SingleResponse.Companion.getInstance(); + accountKey, true); + if (details == null) + return SingleResponse.Companion.getInstance(new MicroBlogException("No account")); final MicroBlog microBlog = AccountDetailsExtensionsKt.newMicroBlogInstance(details, - getContext(), MicroBlog.class); - if (microBlog == null) { - return SingleResponse.Companion.getInstance(); - } + getContext(), false, false, null, MicroBlog.class); try { - final ParcelableStatus result = ParcelableStatusUtils.INSTANCE.fromStatus(microBlog.retweetStatus(mStatusId), - mAccountKey, false); - ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details - ); + final ParcelableStatus result = ParcelableStatusUtils.INSTANCE.fromStatus(microBlog.retweetStatus(statusId), + accountKey, false); + ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details); Utils.setLastSeen(getContext(), result.mentions, System.currentTimeMillis()); final ContentValues values = new ContentValues(); values.put(Statuses.MY_RETWEET_ID, result.id); @@ -1376,11 +1373,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper { Expression.equalsArgs(Statuses.STATUS_ID), Expression.equalsArgs(Statuses.RETWEET_ID) ); - final String[] whereArgs = {mStatusId, mStatusId}; + final String[] whereArgs = {statusId, statusId}; for (final Uri uri : DataStoreUtils.STATUSES_URIS) { resolver.update(uri, values, where.getSQL(), whereArgs); } - DataStoreUtils.updateActivityStatus(resolver, mAccountKey, mStatusId, new DataStoreUtils.UpdateActivityAction() { + DataStoreUtils.updateActivityStatus(resolver, accountKey, statusId, new DataStoreUtils.UpdateActivityAction() { @Override public void process(ParcelableActivity activity) { ParcelableStatus[][] statusesMatrix = {activity.target_statuses, @@ -1389,8 +1386,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { for (ParcelableStatus[] statusesArray : statusesMatrix) { if (statusesArray == null) continue; for (ParcelableStatus status : statusesArray) { - if (mStatusId.equals(status.id) || mStatusId.equals(status.retweet_id) - || mStatusId.equals(status.my_retweet_id)) { + if (statusId.equals(status.id) || statusId.equals(status.retweet_id) + || statusId.equals(status.my_retweet_id)) { status.my_retweet_id = result.id; status.reply_count = result.reply_count; status.retweet_count = result.retweet_count; @@ -1409,7 +1406,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPreExecute() { super.onPreExecute(); - final int hashCode = calculateHashCode(mAccountKey, mStatusId); + final int hashCode = calculateHashCode(accountKey, statusId); if (!mCreatingRetweetIds.contains(hashCode)) { mCreatingRetweetIds.add(hashCode); } @@ -1418,13 +1415,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper { @Override protected void onPostExecute(final SingleResponse result) { - mCreatingRetweetIds.removeElement(calculateHashCode(mAccountKey, mStatusId)); + mCreatingRetweetIds.removeElement(calculateHashCode(accountKey, 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(mAccountKey, event); + HotMobiLogger.getInstance(getContext()).log(accountKey, event); // END HotMobi getBus().post(new StatusRetweetedEvent(status)); diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt index 788db63ea..c6da55a12 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt @@ -62,7 +62,9 @@ import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras +import org.mariotaku.twidere.model.draft.StatusObjectExtras import org.mariotaku.twidere.model.util.AccountUtils +import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails import org.mariotaku.twidere.model.util.ParcelableDirectMessageUtils import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages @@ -122,28 +124,42 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { if (draftId == -1L) return val where = Expression.equals(Drafts._ID, draftId) @SuppressLint("Recycle") - val item: Draft = contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null)?.useCursor { + val draft: Draft = contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null)?.useCursor { val i = DraftCursorIndices(it) if (!it.moveToFirst()) return@useCursor null return@useCursor i.newObject(it) } ?: return contentResolver.delete(Drafts.CONTENT_URI, where.sql, null) - if (TextUtils.isEmpty(item.action_type)) { - item.action_type = Draft.Action.UPDATE_STATUS + if (TextUtils.isEmpty(draft.action_type)) { + draft.action_type = Draft.Action.UPDATE_STATUS } - when (item.action_type) { - Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> { - updateStatuses(item.action_type, ParcelableStatusUpdateUtils.fromDraftItem(this, item)) + when (draft.action_type) { + Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2, + Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> { + updateStatuses(draft.action_type, ParcelableStatusUpdateUtils.fromDraftItem(this, draft)) } Draft.Action.SEND_DIRECT_MESSAGE_COMPAT, Draft.Action.SEND_DIRECT_MESSAGE -> { - val recipientId = (item.action_extras as? SendDirectMessageActionExtras)?.recipientId ?: return - if (item.account_keys?.isEmpty() ?: true) { - return + val recipientId = (draft.action_extras as? SendDirectMessageActionExtras)?.recipientId ?: return + val accountKey = draft.account_keys?.firstOrNull() ?: return + val imageUri = draft.media.firstOrNull()?.uri + sendMessage(accountKey, recipientId, draft.text, imageUri) + } + Draft.Action.FAVORITE -> { + performStatusAction(draft) { microBlog, account, status -> + if (account.type == AccountType.FANFOU) { + microBlog.createFanfouFavorite(status.id) + } else { + microBlog.createFavorite(status.id) + } + return@performStatusAction true + } + } + Draft.Action.RETWEET -> { + performStatusAction(draft) { microBlog, account, status -> + microBlog.retweetStatus(status.id) + return@performStatusAction true } - val accountKey = item.account_keys!!.first() - val imageUri = item.media.firstOrNull()?.uri - sendMessage(accountKey, recipientId, item.text, imageUri) } } } @@ -426,6 +442,18 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { } } + private fun performStatusAction(draft: Draft, action: (MicroBlog, AccountDetails, ParcelableStatus) -> Boolean): Boolean { + val accountKey = draft.account_keys?.firstOrNull() ?: return false + val extras = draft.action_extras as? StatusObjectExtras ?: return false + val account = getAccountDetails(AccountManager.get(this), accountKey, true) ?: return false + val microBlog = account.newMicroBlogInstance(this, cls = MicroBlog::class.java) + try { + return action(microBlog, account, extras.status) + } catch (e: MicroBlogException) { + return false + } + } + internal class MessageMediaUploadListener(private val context: Context, private val manager: NotificationManagerWrapper, builder: NotificationCompat.Builder, private val message: String) : ReadListener {