close #755
This commit is contained in:
parent
8ca86a00f9
commit
32fd8f9d87
|
@ -27,6 +27,7 @@ import android.os.Parcelable;
|
|||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
|
||||
|
@ -44,7 +45,6 @@ import org.mariotaku.twidere.model.account.AccountExtras;
|
|||
import org.mariotaku.twidere.model.account.cred.Credentials;
|
||||
import org.mariotaku.twidere.model.util.RGBHexColorConverter;
|
||||
import org.mariotaku.twidere.model.util.UserKeyConverter;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
import org.mariotaku.twidere.util.model.AccountDetailsUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -140,10 +140,10 @@ public class AccountDetails implements Parcelable, Comparable<AccountDetails> {
|
|||
@OnPreJsonSerialize
|
||||
void onPreJsonSerialize() throws IOException {
|
||||
if (credentials != null) {
|
||||
credentials_json = JsonSerializer.serialize(credentials);
|
||||
credentials_json = LoganSquare.serialize(credentials);
|
||||
}
|
||||
if (extras != null) {
|
||||
extras_json = JsonSerializer.serialize(extras);
|
||||
extras_json = LoganSquare.serialize(extras);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated;
|
|||
import org.mariotaku.library.objectcursor.annotation.CursorField;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorObject;
|
||||
import org.mariotaku.twidere.model.draft.ActionExtras;
|
||||
import org.mariotaku.twidere.model.util.DraftExtrasConverter;
|
||||
import org.mariotaku.twidere.model.util.DraftExtrasFieldConverter;
|
||||
import org.mariotaku.twidere.model.util.UserKeysCursorFieldConverter;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
||||
|
@ -73,7 +73,7 @@ public class Draft implements Parcelable {
|
|||
public String action_type;
|
||||
@Nullable
|
||||
@ParcelableThisPlease
|
||||
@CursorField(value = Drafts.ACTION_EXTRAS, converter = DraftExtrasConverter.class)
|
||||
@CursorField(value = Drafts.ACTION_EXTRAS, converter = DraftExtrasFieldConverter.class)
|
||||
public ActionExtras action_extras;
|
||||
@Nullable
|
||||
@ParcelableThisPlease
|
||||
|
|
|
@ -24,12 +24,20 @@ package org.mariotaku.twidere.model;
|
|||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
|
||||
import com.bluelinelabs.logansquare.annotation.OnPreJsonSerialize;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||
|
||||
import org.mariotaku.commons.logansquare.JsonStringConverter;
|
||||
import org.mariotaku.twidere.model.draft.ActionExtras;
|
||||
import org.mariotaku.twidere.model.util.DraftExtrasFieldConverter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ParcelablePlease
|
||||
|
@ -72,6 +80,13 @@ public class ParcelableStatusUpdate implements Parcelable {
|
|||
@ParcelableThisPlease
|
||||
@Draft.Action
|
||||
public String draft_action;
|
||||
@JsonField(name = "draft_extras")
|
||||
@ParcelableThisPlease
|
||||
@Nullable
|
||||
public ActionExtras draft_extras;
|
||||
|
||||
@JsonField(name = "draft_extras", typeConverter = JsonStringConverter.class)
|
||||
String rawDraftExtras;
|
||||
|
||||
public ParcelableStatusUpdate() {
|
||||
}
|
||||
|
@ -100,6 +115,16 @@ public class ParcelableStatusUpdate implements Parcelable {
|
|||
ParcelableStatusUpdateParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@OnJsonParseComplete
|
||||
void onJsonParseComplete() throws IOException {
|
||||
draft_extras = DraftExtrasFieldConverter.parseExtras(draft_action, rawDraftExtras);
|
||||
}
|
||||
|
||||
@OnPreJsonSerialize
|
||||
void onPreJsonSerialize() throws IOException {
|
||||
rawDraftExtras = DraftExtrasFieldConverter.serializeExtras(draft_extras);
|
||||
}
|
||||
|
||||
public static final Creator<ParcelableStatusUpdate> CREATOR = new Creator<ParcelableStatusUpdate>() {
|
||||
@Override
|
||||
public ParcelableStatusUpdate createFromParcel(Parcel source) {
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
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 QuoteStatusActionExtras implements ActionExtras, Parcelable {
|
||||
|
||||
@JsonField(name = "status")
|
||||
ParcelableStatus status;
|
||||
@JsonField(name = "quote_original_status")
|
||||
boolean quoteOriginalStatus;
|
||||
|
||||
public ParcelableStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(final ParcelableStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean isQuoteOriginalStatus() {
|
||||
return quoteOriginalStatus;
|
||||
}
|
||||
|
||||
public void setQuoteOriginalStatus(final boolean quoteOriginalStatus) {
|
||||
this.quoteOriginalStatus = quoteOriginalStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
QuoteStatusActionExtrasParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final Creator<QuoteStatusActionExtras> CREATOR = new Creator<QuoteStatusActionExtras>() {
|
||||
public QuoteStatusActionExtras createFromParcel(Parcel source) {
|
||||
QuoteStatusActionExtras target = new QuoteStatusActionExtras();
|
||||
QuoteStatusActionExtrasParcelablePlease.readFromParcel(target, source);
|
||||
return target;
|
||||
}
|
||||
|
||||
public QuoteStatusActionExtras[] newArray(int size) {
|
||||
return new QuoteStatusActionExtras[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -36,9 +36,17 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
|||
|
||||
@ParcelablePlease
|
||||
@JsonObject
|
||||
public class StatusObjectExtras implements ActionExtras, Parcelable {
|
||||
public class StatusObjectActionExtras implements ActionExtras, Parcelable {
|
||||
@JsonField(name = "status")
|
||||
public ParcelableStatus status;
|
||||
ParcelableStatus status;
|
||||
|
||||
public ParcelableStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(final ParcelableStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
@ -47,18 +55,18 @@ public class StatusObjectExtras implements ActionExtras, Parcelable {
|
|||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
StatusObjectExtrasParcelablePlease.writeToParcel(this, dest, flags);
|
||||
StatusObjectActionExtrasParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final Creator<StatusObjectExtras> CREATOR = new Creator<StatusObjectExtras>() {
|
||||
public StatusObjectExtras createFromParcel(Parcel source) {
|
||||
StatusObjectExtras target = new StatusObjectExtras();
|
||||
StatusObjectExtrasParcelablePlease.readFromParcel(target, source);
|
||||
public static final Creator<StatusObjectActionExtras> CREATOR = new Creator<StatusObjectActionExtras>() {
|
||||
public StatusObjectActionExtras createFromParcel(Parcel source) {
|
||||
StatusObjectActionExtras target = new StatusObjectActionExtras();
|
||||
StatusObjectActionExtrasParcelablePlease.readFromParcel(target, source);
|
||||
return target;
|
||||
}
|
||||
|
||||
public StatusObjectExtras[] newArray(int size) {
|
||||
return new StatusObjectExtras[size];
|
||||
public StatusObjectActionExtras[] newArray(int size) {
|
||||
return new StatusObjectActionExtras[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -25,10 +25,10 @@ import android.os.Parcelable;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableMessage.MessageType;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -42,14 +42,14 @@ public abstract class MessageExtras implements Parcelable {
|
|||
if (json == null) return null;
|
||||
switch (messageType) {
|
||||
case MessageType.STICKER:
|
||||
return JsonSerializer.parse(json, StickerExtras.class);
|
||||
return LoganSquare.parse(json, StickerExtras.class);
|
||||
case MessageType.JOIN_CONVERSATION:
|
||||
case MessageType.PARTICIPANTS_LEAVE:
|
||||
case MessageType.PARTICIPANTS_JOIN:
|
||||
return JsonSerializer.parse(json, UserArrayExtras.class);
|
||||
return LoganSquare.parse(json, UserArrayExtras.class);
|
||||
case MessageType.CONVERSATION_NAME_UPDATE:
|
||||
case MessageType.CONVERSATION_AVATAR_UPDATE:
|
||||
return JsonSerializer.parse(json, ConversationInfoUpdatedExtras.class);
|
||||
return LoganSquare.parse(json, ConversationInfoUpdatedExtras.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,9 @@ import android.os.Parcelable;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableMessageConversation.ExtrasType;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -39,9 +40,9 @@ public abstract class ConversationExtras implements Parcelable {
|
|||
if (json == null) return null;
|
||||
switch (extrasType) {
|
||||
case ExtrasType.TWITTER_OFFICIAL: {
|
||||
return JsonSerializer.parse(json, TwitterOfficialConversationExtras.class);
|
||||
return LoganSquare.parse(json, TwitterOfficialConversationExtras.class);
|
||||
}
|
||||
}
|
||||
return JsonSerializer.parse(json, DefaultConversationExtras.class);
|
||||
return LoganSquare.parse(json, DefaultConversationExtras.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* Remember not to use {@link org.mariotaku.twidere.util.JsonSerializer} because it's single threaded
|
||||
* Such operation may lead to dead lock
|
||||
*/
|
||||
package org.mariotaku.twidere.model;
|
|
@ -26,13 +26,13 @@ import android.support.annotation.CallSuper;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
|
||||
import org.mariotaku.twidere.TwidereConstants;
|
||||
import org.mariotaku.twidere.annotation.CustomTabType;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -102,17 +102,17 @@ public class TabArguments implements TwidereConstants {
|
|||
case CustomTabType.NOTIFICATIONS_TIMELINE:
|
||||
case CustomTabType.DIRECT_MESSAGES:
|
||||
case CustomTabType.TRENDS_SUGGESTIONS: {
|
||||
return JsonSerializer.parse(json, TabArguments.class);
|
||||
return LoganSquare.parse(json, TabArguments.class);
|
||||
}
|
||||
case CustomTabType.USER_TIMELINE:
|
||||
case CustomTabType.FAVORITES: {
|
||||
return JsonSerializer.parse(json, UserArguments.class);
|
||||
return LoganSquare.parse(json, UserArguments.class);
|
||||
}
|
||||
case CustomTabType.LIST_TIMELINE: {
|
||||
return JsonSerializer.parse(json, UserListArguments.class);
|
||||
return LoganSquare.parse(json, UserListArguments.class);
|
||||
}
|
||||
case CustomTabType.SEARCH_STATUSES: {
|
||||
return JsonSerializer.parse(json, TextQueryArguments.class);
|
||||
return LoganSquare.parse(json, TextQueryArguments.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -27,10 +27,10 @@ import android.support.annotation.CallSuper;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
|
||||
import org.mariotaku.twidere.annotation.CustomTabType;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -49,13 +49,13 @@ public abstract class TabExtras implements Parcelable {
|
|||
if (json == null) return null;
|
||||
switch (type) {
|
||||
case CustomTabType.NOTIFICATIONS_TIMELINE: {
|
||||
return JsonSerializer.parse(json, InteractionsTabExtras.class);
|
||||
return LoganSquare.parse(json, InteractionsTabExtras.class);
|
||||
}
|
||||
case CustomTabType.HOME_TIMELINE: {
|
||||
return JsonSerializer.parse(json, HomeTabExtras.class);
|
||||
return LoganSquare.parse(json, HomeTabExtras.class);
|
||||
}
|
||||
case CustomTabType.TRENDS_SUGGESTIONS: {
|
||||
return JsonSerializer.parse(json, TrendsTabExtras.class);
|
||||
return LoganSquare.parse(json, TrendsTabExtras.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -25,10 +25,11 @@ import android.content.ContentValues;
|
|||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
|
||||
import org.mariotaku.twidere.model.message.conversation.ConversationExtras;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -47,6 +48,6 @@ public class ConversationExtrasConverter implements CursorFieldConverter<Convers
|
|||
@Override
|
||||
public void writeField(ContentValues values, ConversationExtras object, String columnName, ParameterizedType fieldType) throws IOException {
|
||||
if (object == null) return;
|
||||
values.put(columnName, JsonSerializer.serialize(object));
|
||||
values.put(columnName, LoganSquare.serialize(object));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,16 +23,19 @@ package org.mariotaku.twidere.model.util;
|
|||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
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.QuoteStatusActionExtras;
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras;
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectExtras;
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras;
|
||||
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -40,35 +43,46 @@ import java.lang.reflect.ParameterizedType;
|
|||
/**
|
||||
* Created by mariotaku on 16/2/20.
|
||||
*/
|
||||
public class DraftExtrasConverter implements CursorFieldConverter<ActionExtras> {
|
||||
public class DraftExtrasFieldConverter implements CursorFieldConverter<ActionExtras> {
|
||||
@Override
|
||||
public ActionExtras parseField(Cursor cursor, int columnIndex, ParameterizedType fieldType) throws IOException {
|
||||
final String actionType = cursor.getString(cursor.getColumnIndex(Drafts.ACTION_TYPE));
|
||||
final String json = cursor.getString(columnIndex);
|
||||
if (TextUtils.isEmpty(actionType) || TextUtils.isEmpty(json)) return null;
|
||||
switch (actionType) {
|
||||
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 JsonSerializer.parse(json, UpdateStatusActionExtras.class);
|
||||
}
|
||||
case Draft.Action.SEND_DIRECT_MESSAGE_COMPAT:
|
||||
case Draft.Action.SEND_DIRECT_MESSAGE: {
|
||||
return JsonSerializer.parse(json, SendDirectMessageActionExtras.class);
|
||||
}
|
||||
case Draft.Action.FAVORITE:
|
||||
case Draft.Action.RETWEET: {
|
||||
return JsonSerializer.parse(json, StatusObjectExtras.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return parseExtras(actionType, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeField(ContentValues values, ActionExtras object, String columnName, ParameterizedType fieldType) throws IOException {
|
||||
if (object == null) return;
|
||||
values.put(columnName, JsonSerializer.serialize(object));
|
||||
values.put(columnName, serializeExtras(object));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ActionExtras parseExtras(final String actionType, final String json) throws IOException {
|
||||
if (TextUtils.isEmpty(actionType) || TextUtils.isEmpty(json)) return null;
|
||||
switch (actionType) {
|
||||
case Draft.Action.UPDATE_STATUS_COMPAT_1:
|
||||
case Draft.Action.UPDATE_STATUS_COMPAT_2:
|
||||
case Draft.Action.UPDATE_STATUS:
|
||||
case Draft.Action.REPLY: {
|
||||
return LoganSquare.parse(json, UpdateStatusActionExtras.class);
|
||||
}
|
||||
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, StatusObjectActionExtras.class);
|
||||
}
|
||||
case Draft.Action.QUOTE: {
|
||||
return LoganSquare.parse(json, QuoteStatusActionExtras.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String serializeExtras(final ActionExtras object) throws IOException {
|
||||
return LoganSquare.serialize(object);
|
||||
}
|
||||
}
|
|
@ -25,10 +25,11 @@ import android.content.ContentValues;
|
|||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
|
||||
import org.mariotaku.twidere.model.message.MessageExtras;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -47,6 +48,6 @@ public class MessageExtrasConverter implements CursorFieldConverter<MessageExtra
|
|||
@Override
|
||||
public void writeField(ContentValues values, MessageExtras object, String columnName, ParameterizedType fieldType) throws IOException {
|
||||
if (object == null) return;
|
||||
values.put(columnName, JsonSerializer.serialize(object));
|
||||
values.put(columnName, LoganSquare.serialize(object));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@ import android.content.ContentValues;
|
|||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
|
||||
import org.mariotaku.twidere.model.Tab;
|
||||
import org.mariotaku.twidere.model.tab.argument.TabArguments;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -50,7 +51,7 @@ public class TabArgumentsFieldConverter implements CursorFieldConverter<TabArgum
|
|||
public void writeField(ContentValues values, TabArguments object, String columnName, ParameterizedType fieldType) {
|
||||
if (object == null) return;
|
||||
try {
|
||||
values.put(columnName, JsonSerializer.serialize(object));
|
||||
values.put(columnName, LoganSquare.serialize(object));
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@ import android.content.ContentValues;
|
|||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
|
||||
import org.mariotaku.twidere.model.Tab;
|
||||
import org.mariotaku.twidere.model.tab.extra.TabExtras;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -48,6 +49,6 @@ public class TabExtrasFieldConverter implements CursorFieldConverter<TabExtras>
|
|||
@Override
|
||||
public void writeField(ContentValues values, TabExtras object, String columnName, ParameterizedType fieldType) throws IOException {
|
||||
if (object == null) return;
|
||||
values.put(columnName, JsonSerializer.serialize(object));
|
||||
values.put(columnName, LoganSquare.serialize(object));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -554,6 +554,9 @@
|
|||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activity.HomeActivity"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.content.RetweetQuoteDialogActivity"
|
||||
android:theme="@style/Theme.Twidere.NoDisplay"/>
|
||||
|
||||
<service
|
||||
android:name=".service.LegacyTaskService"
|
||||
|
|
|
@ -43,7 +43,10 @@ import org.mariotaku.twidere.model.UserKey;
|
|||
import org.mariotaku.twidere.model.tab.DrawableHolder;
|
||||
import org.mariotaku.twidere.model.tab.TabConfiguration;
|
||||
import org.mariotaku.twidere.model.tab.argument.TabArguments;
|
||||
import org.mariotaku.twidere.model.tab.extra.HomeTabExtras;
|
||||
import org.mariotaku.twidere.model.tab.extra.InteractionsTabExtras;
|
||||
import org.mariotaku.twidere.model.tab.extra.TabExtras;
|
||||
import org.mariotaku.twidere.model.tab.extra.TrendsTabExtras;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -116,13 +119,26 @@ public class CustomTabUtils implements Constants {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remember to make this method correspond to {@link TabExtras#parse(String, String)}
|
||||
*
|
||||
* @see TabExtras#parse(String, String)
|
||||
*/
|
||||
@Nullable
|
||||
public static TabExtras newTabExtras(@NonNull @CustomTabType String type) {
|
||||
try {
|
||||
return TabExtras.parse(type, "{}");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
switch (type) {
|
||||
case CustomTabType.NOTIFICATIONS_TIMELINE: {
|
||||
return new InteractionsTabExtras();
|
||||
}
|
||||
case CustomTabType.HOME_TIMELINE: {
|
||||
return new HomeTabExtras();
|
||||
}
|
||||
case CustomTabType.TRENDS_SUGGESTIONS: {
|
||||
return new TrendsTabExtras();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.ktextension
|
||||
|
||||
import android.content.ContentValues
|
||||
|
||||
|
||||
inline fun ContentValues(action: ContentValues.() -> Unit): ContentValues {
|
||||
val bundle = ContentValues()
|
||||
action(bundle)
|
||||
return bundle
|
||||
}
|
||||
|
||||
operator fun ContentValues.set(key: String, value: Boolean) {
|
||||
return put(key, value)
|
||||
}
|
||||
|
||||
operator fun ContentValues.set(key: String, value: Int) {
|
||||
return put(key, value)
|
||||
}
|
||||
|
||||
operator fun ContentValues.set(key: String, value: Long) {
|
||||
return put(key, value)
|
||||
}
|
||||
|
||||
operator fun ContentValues.set(key: String, value: String?) {
|
||||
return put(key, value)
|
||||
}
|
|
@ -34,6 +34,10 @@ fun Menu.setGroupAvailability(groupId: Int, available: Boolean) {
|
|||
setGroupVisible(groupId, available)
|
||||
}
|
||||
|
||||
fun Menu.isItemChecked(id: Int): Boolean {
|
||||
return findItem(id)?.isChecked ?: false
|
||||
}
|
||||
|
||||
fun Menu.setItemChecked(id: Int, checked: Boolean) {
|
||||
findItem(id)?.isChecked = checked
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.mariotaku.twidere.extension.model.textLimit
|
|||
import org.mariotaku.twidere.extension.model.unique_id_non_null
|
||||
import org.mariotaku.twidere.extension.text.twitter.extractReplyTextAndMentions
|
||||
import org.mariotaku.twidere.extension.text.twitter.getTweetLength
|
||||
import org.mariotaku.twidere.extension.withAppendedPath
|
||||
import org.mariotaku.twidere.fragment.*
|
||||
import org.mariotaku.twidere.fragment.PermissionRequestDialog.PermissionRequestCancelCallback
|
||||
import org.mariotaku.twidere.model.*
|
||||
|
@ -873,9 +874,8 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
|
|||
}
|
||||
|
||||
private fun displayNewDraftNotification(draftUri: Uri) {
|
||||
val values = ContentValues()
|
||||
values.put(BaseColumns._ID, draftUri.lastPathSegment)
|
||||
contentResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, values)
|
||||
val notificationUri = Drafts.CONTENT_URI_NOTIFICATIONS.withAppendedPath(draftUri.lastPathSegment)
|
||||
contentResolver.insert(notificationUri, null)
|
||||
}
|
||||
|
||||
private val media: Array<ParcelableMediaUpdate>
|
||||
|
@ -1476,7 +1476,13 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
|
|||
update.media = media
|
||||
update.in_reply_to_status = inReplyToStatus
|
||||
update.is_possibly_sensitive = isPossiblySensitive
|
||||
update.attachment_url = (draft?.action_extras as? UpdateStatusActionExtras)?.attachmentUrl
|
||||
update.draft_extras = UpdateStatusActionExtras().also {
|
||||
it.inReplyToStatus = inReplyToStatus
|
||||
it.isPossiblySensitive = isPossiblySensitive
|
||||
it.displayCoordinates = attachPreciseLocation
|
||||
}
|
||||
|
||||
|
||||
LengthyOperationsService.updateStatusesAsync(this, action, statuses = update,
|
||||
scheduleInfo = scheduleInfo)
|
||||
if (preferences[noCloseAfterTweetSentKey] && inReplyToStatus == null) {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity.content
|
||||
|
||||
import android.os.Bundle
|
||||
import org.mariotaku.twidere.activity.BaseActivity
|
||||
import org.mariotaku.twidere.constant.IntentConstants.*
|
||||
import org.mariotaku.twidere.fragment.RetweetQuoteDialogFragment
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/4/8.
|
||||
*/
|
||||
|
||||
class RetweetQuoteDialogActivity : BaseActivity() {
|
||||
|
||||
private val status: ParcelableStatus
|
||||
get() = intent.getParcelableExtra(EXTRA_STATUS)
|
||||
|
||||
private val accountKey: UserKey?
|
||||
get() = intent.getParcelableExtra(EXTRA_ACCOUNT_KEY)
|
||||
|
||||
private val text: String?
|
||||
get() = intent.getStringExtra(EXTRA_TEXT)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (savedInstanceState == null) {
|
||||
RetweetQuoteDialogFragment.show(supportFragmentManager, status, accountKey, text)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.extension
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
fun Uri.withAppendedPath(path: String) = Uri.withAppendedPath(this, path)
|
|
@ -21,8 +21,6 @@ package org.mariotaku.twidere.fragment
|
|||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.content.Intent
|
||||
|
@ -48,8 +46,10 @@ import org.mariotaku.kpreferences.get
|
|||
import org.mariotaku.ktextension.setItemAvailability
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.sqliteqb.library.OrderBy
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.activity.content.RetweetQuoteDialogActivity
|
||||
import org.mariotaku.twidere.activity.iface.IBaseActivity
|
||||
import org.mariotaku.twidere.adapter.DraftsAdapter
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
|
@ -57,6 +57,7 @@ import org.mariotaku.twidere.constant.textSizeKey
|
|||
import org.mariotaku.twidere.extension.*
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
|
||||
import org.mariotaku.twidere.model.draft.QuoteStatusActionExtras
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||
import org.mariotaku.twidere.util.Analyzer
|
||||
|
@ -197,18 +198,28 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
}
|
||||
|
||||
override fun onItemClick(view: AdapterView<*>, child: View, position: Int, id: Long) {
|
||||
val item = adapter.getDraft(position)
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
editDraft(item)
|
||||
return
|
||||
}
|
||||
when (item.action_type) {
|
||||
"0", "1", Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> {
|
||||
editDraft(item)
|
||||
val draft = adapter.getDraft(position)
|
||||
var deleteDraft = false
|
||||
if (TextUtils.isEmpty(draft.action_type)) {
|
||||
deleteDraft = editUpdateStatusDraft(draft)
|
||||
} else when (draft.action_type) {
|
||||
"0", "1", Draft.Action.UPDATE_STATUS, Draft.Action.REPLY -> {
|
||||
deleteDraft = editUpdateStatusDraft(draft)
|
||||
}
|
||||
Draft.Action.QUOTE -> {
|
||||
deleteDraft = editQuoteStatusDraft(draft)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (deleteDraft) {
|
||||
val draftIdString = draft._id.toString()
|
||||
val where = Expression.equalsArgs(Drafts._ID).sql
|
||||
val whereArgs = arrayOf(draftIdString)
|
||||
|
||||
val cr = context.contentResolver
|
||||
cr.delete(Drafts.CONTENT_URI, where, whereArgs)
|
||||
cr.delete(Drafts.CONTENT_URI_NOTIFICATIONS.withAppendedPath(draftIdString), null, null)
|
||||
}
|
||||
}
|
||||
|
||||
fun setListShown(listShown: Boolean) {
|
||||
listContainer.visibility = if (listShown) View.VISIBLE else View.GONE
|
||||
|
@ -216,11 +227,25 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
emptyView.visibility = if (listShown && adapter.isEmpty) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun editDraft(draft: Draft) {
|
||||
val intent = Intent(INTENT_ACTION_EDIT_DRAFT)
|
||||
intent.putExtra(EXTRA_DRAFT, draft)
|
||||
context.contentResolver.delete(Drafts.CONTENT_URI, Expression.equals(Drafts._ID, draft._id).sql, null)
|
||||
private fun editUpdateStatusDraft(draft: Draft): Boolean {
|
||||
val intent = Intent(INTENT_ACTION_EDIT_DRAFT).apply {
|
||||
`package` = BuildConfig.APPLICATION_ID
|
||||
putExtra(EXTRA_DRAFT, draft)
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_COMPOSE)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun editQuoteStatusDraft(draft: Draft): Boolean {
|
||||
val extras = draft.action_extras as? QuoteStatusActionExtras ?: return false
|
||||
val status = extras.status ?: return false
|
||||
val intent = Intent(context, RetweetQuoteDialogActivity::class.java).apply {
|
||||
putExtra(EXTRA_STATUS, status)
|
||||
putExtra(EXTRA_ACCOUNT_KEY, draft.account_keys?.singleOrNull())
|
||||
putExtra(EXTRA_TEXT, draft.text)
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_COMPOSE)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun sendDrafts(list: LongArray): Boolean {
|
||||
|
@ -247,7 +272,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val args = arguments ?: return
|
||||
AsyncTaskUtils.executeTask(DeleteDraftsTask(activity, args.getLongArray(IntentConstants.EXTRA_IDS)))
|
||||
AsyncTaskUtils.executeTask(DeleteDraftsTask(activity, args.getLongArray(EXTRA_IDS)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +303,10 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
override fun doInBackground(vararg params: Any) {
|
||||
val activity = activityRef.get() ?: return
|
||||
deleteDrafts(activity, ids)
|
||||
ids.forEach { id ->
|
||||
val uri = Drafts.CONTENT_URI_NOTIFICATIONS.withAppendedPath(id.toString())
|
||||
activity.contentResolver.delete(uri, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
|
@ -297,11 +326,6 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
f.dismiss()
|
||||
}
|
||||
}
|
||||
val notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
ids.forEach { id ->
|
||||
val tag = Uri.withAppendedPath(Drafts.CONTENT_URI, id.toString()).toString()
|
||||
notificationManager.cancel(tag, NOTIFICATION_ID_DRAFTS)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.content.DialogInterface
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.BaseColumns
|
||||
import android.support.annotation.CheckResult
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
|
@ -33,16 +34,13 @@ import android.text.Editable
|
|||
import android.text.TextWatcher
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageButton
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.*
|
||||
import com.bumptech.glide.Glide
|
||||
import com.twitter.Validator
|
||||
import org.mariotaku.ktextension.Bundle
|
||||
import org.mariotaku.ktextension.set
|
||||
import org.mariotaku.ktextension.setItemAvailability
|
||||
import org.mariotaku.ktextension.*
|
||||
import org.mariotaku.library.objectcursor.ObjectCursor
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.activity.content.RetweetQuoteDialogActivity
|
||||
import org.mariotaku.twidere.adapter.DummyItemAdapter
|
||||
import org.mariotaku.twidere.annotation.AccountType
|
||||
import org.mariotaku.twidere.constant.IntentConstants.*
|
||||
|
@ -50,7 +48,9 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_QUICK_SEND
|
|||
import org.mariotaku.twidere.extension.applyTheme
|
||||
import org.mariotaku.twidere.extension.model.textLimit
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.draft.QuoteStatusActionExtras
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||
import org.mariotaku.twidere.util.Analyzer
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler
|
||||
|
@ -60,10 +60,30 @@ import org.mariotaku.twidere.view.ColorLabelRelativeLayout
|
|||
import org.mariotaku.twidere.view.ComposeEditText
|
||||
import org.mariotaku.twidere.view.StatusTextCountView
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder
|
||||
import java.util.*
|
||||
|
||||
class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
||||
private lateinit var popupMenu: PopupMenu
|
||||
|
||||
private val PopupMenu.quoteOriginalStatus get() = menu.isItemChecked(R.id.quote_original_status)
|
||||
private val Dialog.itemContent get() = findViewById(R.id.itemContent) as ColorLabelRelativeLayout
|
||||
private val Dialog.textCountView get() = findViewById(R.id.commentTextCount) as StatusTextCountView
|
||||
private val Dialog.itemMenu get() = findViewById(R.id.itemMenu) as ImageButton
|
||||
private val Dialog.actionButtons get() = findViewById(R.id.actionButtons) as LinearLayout
|
||||
private val Dialog.commentContainer get() = findViewById(R.id.commentContainer) as RelativeLayout
|
||||
private val Dialog.editComment get() = findViewById(R.id.editComment) as ComposeEditText
|
||||
private val Dialog.commentMenu get() = findViewById(R.id.commentMenu) as ImageButton
|
||||
|
||||
|
||||
private val status: ParcelableStatus
|
||||
get() = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS)
|
||||
|
||||
private val accountKey: UserKey
|
||||
get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) ?: status.account_key
|
||||
|
||||
private val text: String?
|
||||
get() = arguments.getString(EXTRA_TEXT)
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val accountKey = this.accountKey
|
||||
|
@ -87,34 +107,27 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
|
||||
val dialog = builder.create()
|
||||
dialog.setOnShowListener {
|
||||
it as AlertDialog
|
||||
it.applyTheme()
|
||||
val itemContent = it.findViewById(R.id.itemContent) as ColorLabelRelativeLayout
|
||||
val textCountView = it.findViewById(R.id.commentTextCount) as StatusTextCountView
|
||||
val itemMenu = it.findViewById(R.id.itemMenu) as ImageButton
|
||||
val actionButtons = it.findViewById(R.id.actionButtons) as LinearLayout
|
||||
val commentContainer = it.findViewById(R.id.commentContainer) as RelativeLayout
|
||||
val editComment = it.findViewById(R.id.editComment) as ComposeEditText
|
||||
val commentMenu = it.findViewById(R.id.commentMenu) as ImageButton
|
||||
dialog.setOnShowListener { dialog ->
|
||||
dialog as AlertDialog
|
||||
dialog.applyTheme()
|
||||
|
||||
val adapter = DummyItemAdapter(context, requestManager = Glide.with(this))
|
||||
adapter.setShouldShowAccountsColor(true)
|
||||
val holder = StatusViewHolder(adapter, itemContent)
|
||||
val holder = StatusViewHolder(adapter, dialog.itemContent)
|
||||
holder.displayStatus(status = status, displayInReplyTo = false)
|
||||
|
||||
textCountView.maxLength = details.textLimit
|
||||
dialog.textCountView.maxLength = details.textLimit
|
||||
|
||||
itemMenu.visibility = View.GONE
|
||||
actionButtons.visibility = View.GONE
|
||||
itemContent.isFocusable = false
|
||||
dialog.itemMenu.visibility = View.GONE
|
||||
dialog.actionButtons.visibility = View.GONE
|
||||
dialog.itemContent.isFocusable = false
|
||||
val useQuote = useQuote(!status.user_is_protected, details)
|
||||
|
||||
commentContainer.visibility = if (useQuote) View.VISIBLE else View.GONE
|
||||
editComment.accountKey = details.key
|
||||
dialog.commentContainer.visibility = if (useQuote) View.VISIBLE else View.GONE
|
||||
dialog.editComment.accountKey = details.key
|
||||
|
||||
val sendByEnter = preferences.getBoolean(KEY_QUICK_SEND)
|
||||
val enterHandler = EditTextEnterHandler.attach(editComment, object : EditTextEnterHandler.EnterListener {
|
||||
val enterHandler = EditTextEnterHandler.attach(dialog.editComment, object : EditTextEnterHandler.EnterListener {
|
||||
override fun shouldCallListener(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
@ -141,7 +154,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
})
|
||||
|
||||
popupMenu = PopupMenu(context, commentMenu, Gravity.NO_GRAVITY,
|
||||
popupMenu = PopupMenu(context, dialog.commentMenu, Gravity.NO_GRAVITY,
|
||||
R.attr.actionOverflowMenuStyle, 0).apply {
|
||||
inflate(R.menu.menu_dialog_comment)
|
||||
menu.setItemAvailability(R.id.quote_original_status, status.retweet_id != null || status.quoted_id != null)
|
||||
|
@ -153,13 +166,13 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
false
|
||||
})
|
||||
}
|
||||
commentMenu.setOnClickListener { popupMenu.show() }
|
||||
commentMenu.setOnTouchListener(popupMenu.dragToOpenListener)
|
||||
commentMenu.visibility = if (popupMenu.menu.hasVisibleItems()) View.VISIBLE else View.GONE
|
||||
dialog.commentMenu.setOnClickListener { popupMenu.show() }
|
||||
dialog.commentMenu.setOnTouchListener(popupMenu.dragToOpenListener)
|
||||
dialog.commentMenu.visibility = if (popupMenu.menu.hasVisibleItems()) View.VISIBLE else View.GONE
|
||||
|
||||
it.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
||||
var dismissDialog = false
|
||||
if (editComment.length() > 0) {
|
||||
if (dialog.editComment.length() > 0) {
|
||||
dismissDialog = retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)
|
||||
} else if (isMyRetweet(status)) {
|
||||
twitterWrapper.cancelRetweetAsync(details.key, status.id, status.my_retweet_id)
|
||||
|
@ -174,11 +187,36 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
updateTextCount(it, editComment.text, status, details)
|
||||
if (savedInstanceState == null) {
|
||||
dialog.editComment.setText(text)
|
||||
}
|
||||
dialog.editComment.setSelection(dialog.editComment.length())
|
||||
|
||||
updateTextCount(dialog, dialog.editComment.text, status, details)
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
if (dialog !is Dialog) return
|
||||
if (dialog.editComment.empty) return
|
||||
dialog.saveToDrafts()
|
||||
Toast.makeText(context, R.string.message_toast_status_saved_to_draft, Toast.LENGTH_SHORT).show()
|
||||
finishRetweetQuoteActivity()
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
finishRetweetQuoteActivity()
|
||||
}
|
||||
|
||||
private fun finishRetweetQuoteActivity() {
|
||||
val activity = this.activity
|
||||
if (activity is RetweetQuoteDialogActivity && !activity.isFinishing) {
|
||||
activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTextCount(dialog: DialogInterface, s: CharSequence, status: ParcelableStatus,
|
||||
credentials: AccountDetails) {
|
||||
if (dialog !is AlertDialog) return
|
||||
|
@ -197,16 +235,9 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
positiveButton.isEnabled = !status.user_is_protected
|
||||
}
|
||||
val textCountView = dialog.findViewById(R.id.commentTextCount) as StatusTextCountView
|
||||
val am = AccountManager.get(context)
|
||||
textCountView.textCount = validator.getTweetLength(s.toString())
|
||||
}
|
||||
|
||||
private val status: ParcelableStatus
|
||||
get() = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS)
|
||||
|
||||
private val accountKey: UserKey
|
||||
get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) ?: status.account_key
|
||||
|
||||
@CheckResult
|
||||
private fun retweetOrQuote(account: AccountDetails, status: ParcelableStatus,
|
||||
showProtectedConfirmation: Boolean): Boolean {
|
||||
|
@ -214,10 +245,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
val dialog = dialog ?: return false
|
||||
val editComment = dialog.findViewById(R.id.editComment) as EditText
|
||||
if (useQuote(editComment.length() > 0, account)) {
|
||||
val menu = popupMenu.menu
|
||||
val itemQuoteOriginalStatus = menu.findItem(R.id.quote_original_status)
|
||||
val statusLink: Uri
|
||||
val quoteOriginalStatus = itemQuoteOriginalStatus.isChecked
|
||||
val quoteOriginalStatus = popupMenu.quoteOriginalStatus
|
||||
|
||||
var commentText: String
|
||||
val update = ParcelableStatusUpdate()
|
||||
|
@ -247,10 +275,10 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
}
|
||||
else -> {
|
||||
if (!status.is_quote || !quoteOriginalStatus) {
|
||||
statusLink = LinkCreator.getStatusWebLink(status)
|
||||
val statusLink = if (!status.is_quote || !quoteOriginalStatus) {
|
||||
LinkCreator.getStatusWebLink(status)
|
||||
} else {
|
||||
statusLink = LinkCreator.getQuotedStatusWebLink(status)
|
||||
LinkCreator.getQuotedStatusWebLink(status)
|
||||
}
|
||||
update.attachment_url = statusLink.toString()
|
||||
commentText = editingComment
|
||||
|
@ -258,6 +286,11 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
update.text = commentText
|
||||
update.is_possibly_sensitive = status.is_possibly_sensitive
|
||||
update.draft_action = Draft.Action.QUOTE
|
||||
update.draft_extras = QuoteStatusActionExtras().apply {
|
||||
this.status = status
|
||||
this.isQuoteOriginalStatus = quoteOriginalStatus
|
||||
}
|
||||
LengthyOperationsService.updateStatusesAsync(context, Draft.Action.QUOTE, update)
|
||||
} else {
|
||||
twitter.retweetStatusAsync(account.key, status)
|
||||
|
@ -270,6 +303,33 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
|
||||
|
||||
private fun Dialog.saveToDrafts() {
|
||||
val text = dialog.editComment.text.toString()
|
||||
val draft = Draft()
|
||||
draft.unique_id = UUID.randomUUID().toString()
|
||||
draft.action_type = Draft.Action.QUOTE
|
||||
draft.account_keys = arrayOf(accountKey)
|
||||
draft.text = text
|
||||
draft.timestamp = System.currentTimeMillis()
|
||||
draft.action_extras = QuoteStatusActionExtras().apply {
|
||||
this.status = this@RetweetQuoteDialogFragment.status
|
||||
this.isQuoteOriginalStatus = popupMenu.quoteOriginalStatus
|
||||
}
|
||||
val values = ObjectCursor.valuesCreatorFrom(Draft::class.java).create(draft)
|
||||
val contentResolver = context.contentResolver
|
||||
val draftUri = contentResolver.insert(Drafts.CONTENT_URI, values)
|
||||
displayNewDraftNotification(draftUri)
|
||||
}
|
||||
|
||||
|
||||
private fun displayNewDraftNotification(draftUri: Uri) {
|
||||
val contentResolver = context.contentResolver
|
||||
val values = ContentValues {
|
||||
this[BaseColumns._ID] = draftUri.lastPathSegment
|
||||
}
|
||||
contentResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, values)
|
||||
}
|
||||
|
||||
class QuoteProtectedStatusWarnFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
|
@ -322,11 +382,13 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
|
|||
val FRAGMENT_TAG = "retweet_quote"
|
||||
private val SHOW_PROTECTED_CONFIRM = java.lang.Boolean.parseBoolean("false")
|
||||
|
||||
fun show(fm: FragmentManager, status: ParcelableStatus, accountKey: UserKey? = null): RetweetQuoteDialogFragment {
|
||||
fun show(fm: FragmentManager, status: ParcelableStatus, accountKey: UserKey? = null,
|
||||
text: String? = null): RetweetQuoteDialogFragment {
|
||||
val f = RetweetQuoteDialogFragment()
|
||||
f.arguments = Bundle {
|
||||
this[EXTRA_STATUS] = status
|
||||
this[EXTRA_ACCOUNT_KEY] = accountKey
|
||||
this[EXTRA_TEXT] = text
|
||||
}
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
|
|
|
@ -2,10 +2,15 @@ package org.mariotaku.twidere.model.util
|
|||
|
||||
import android.accounts.AccountManager
|
||||
import android.content.Context
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.annotation.AccountType
|
||||
import org.mariotaku.twidere.extension.model.unique_id_non_null
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate
|
||||
import org.mariotaku.twidere.model.draft.QuoteStatusActionExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
|
||||
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras
|
||||
import org.mariotaku.twidere.util.LinkCreator
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/12.
|
||||
|
@ -20,12 +25,52 @@ object ParcelableStatusUpdateUtils {
|
|||
statusUpdate.text = draft.text
|
||||
statusUpdate.location = draft.location
|
||||
statusUpdate.media = draft.media
|
||||
if (draft.action_extras is UpdateStatusActionExtras) {
|
||||
val extra = draft.action_extras as UpdateStatusActionExtras?
|
||||
statusUpdate.in_reply_to_status = extra!!.inReplyToStatus
|
||||
statusUpdate.is_possibly_sensitive = extra.isPossiblySensitive
|
||||
statusUpdate.display_coordinates = extra.displayCoordinates
|
||||
statusUpdate.attachment_url = extra.attachmentUrl
|
||||
val actionExtras = draft.action_extras
|
||||
when (actionExtras) {
|
||||
is UpdateStatusActionExtras -> {
|
||||
statusUpdate.in_reply_to_status = actionExtras.inReplyToStatus
|
||||
statusUpdate.is_possibly_sensitive = actionExtras.isPossiblySensitive
|
||||
statusUpdate.display_coordinates = actionExtras.displayCoordinates
|
||||
statusUpdate.attachment_url = actionExtras.attachmentUrl
|
||||
}
|
||||
is QuoteStatusActionExtras -> {
|
||||
val onlyAccount = statusUpdate.accounts.singleOrNull()
|
||||
val status = actionExtras.status
|
||||
val quoteOriginalStatus = actionExtras.isQuoteOriginalStatus
|
||||
if (onlyAccount != null) {
|
||||
when (onlyAccount.type) {
|
||||
AccountType.FANFOU -> {
|
||||
if (!status.is_quote || !quoteOriginalStatus) {
|
||||
statusUpdate.repost_status_id = status.id
|
||||
statusUpdate.text = context.getString(R.string.fanfou_repost_format,
|
||||
draft.text, status.user_screen_name, status.text_plain)
|
||||
} else {
|
||||
statusUpdate.text = context.getString(R.string.fanfou_repost_format,
|
||||
draft.text, status.quoted_user_screen_name,
|
||||
status.quoted_text_plain)
|
||||
statusUpdate.repost_status_id = status.quoted_id
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val statusLink = if (!status.is_quote || !quoteOriginalStatus) {
|
||||
LinkCreator.getStatusWebLink(status)
|
||||
} else {
|
||||
LinkCreator.getQuotedStatusWebLink(status)
|
||||
}
|
||||
statusUpdate.attachment_url = statusLink.toString()
|
||||
statusUpdate.text = draft.text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is StatusObjectActionExtras -> {
|
||||
when (draft.action_type) {
|
||||
Draft.Action.QUOTE -> {
|
||||
val link = LinkCreator.getStatusWebLink(actionExtras.status)
|
||||
statusUpdate.attachment_url = link.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
statusUpdate.draft_action = draft.action_type
|
||||
statusUpdate.draft_unique_id = draft.unique_id_non_null
|
||||
|
|
|
@ -19,10 +19,8 @@
|
|||
|
||||
package org.mariotaku.twidere.provider
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.ContentProvider
|
||||
import android.content.ContentValues
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.database.MatrixCursor
|
||||
import android.database.SQLException
|
||||
|
@ -33,35 +31,28 @@ import android.os.Binder
|
|||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Process
|
||||
import android.provider.BaseColumns
|
||||
import android.support.v4.app.NotificationCompat
|
||||
import android.support.v4.text.BidiFormatter
|
||||
import com.squareup.otto.Bus
|
||||
import okhttp3.Dns
|
||||
import org.mariotaku.ktextension.isNullOrEmpty
|
||||
import org.mariotaku.ktextension.toNulls
|
||||
import org.mariotaku.library.objectcursor.ObjectCursor
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.annotation.CustomTabType
|
||||
import org.mariotaku.twidere.annotation.ReadPositionTag
|
||||
import org.mariotaku.twidere.app.TwidereApplication
|
||||
import org.mariotaku.twidere.extension.withAppendedPath
|
||||
import org.mariotaku.twidere.model.AccountPreferences
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.SQLiteDatabaseWrapper.LazyLoadCallback
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import org.mariotaku.twidere.util.database.CachedUsersQueryBuilder
|
||||
import org.mariotaku.twidere.util.database.SuggestionsCursorCreator
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
import javax.inject.Inject
|
||||
|
@ -345,62 +336,21 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
|
|||
|
||||
private fun deleteInternal(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
|
||||
val tableId = DataStoreUtils.getTableId(uri)
|
||||
val table = DataStoreUtils.getTableNameById(tableId) ?: return 0
|
||||
val result = databaseWrapper.delete(table, selection, selectionArgs)
|
||||
if (result > 0) {
|
||||
onDatabaseUpdated(tableId, uri)
|
||||
when (tableId) {
|
||||
VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS -> {
|
||||
notificationManager.cancel(uri.toString(), NOTIFICATION_ID_DRAFTS)
|
||||
return 1
|
||||
}
|
||||
else -> {
|
||||
val table = DataStoreUtils.getTableNameById(tableId) ?: return 0
|
||||
val result = databaseWrapper.delete(table, selection, selectionArgs)
|
||||
if (result > 0) {
|
||||
onDatabaseUpdated(tableId, uri)
|
||||
}
|
||||
onItemDeleted(uri, tableId)
|
||||
return result
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun showDraftNotification(values: ContentValues?): Long {
|
||||
val context = context
|
||||
if (values == null || context == null) return -1
|
||||
val draftId = values.getAsLong(BaseColumns._ID) ?: return -1
|
||||
val where = Expression.equals(Drafts._ID, draftId)
|
||||
val c = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null) ?: return -1
|
||||
val i = ObjectCursor.indicesFrom(c, Draft::class.java)
|
||||
val item: Draft
|
||||
try {
|
||||
if (!c.moveToFirst()) return -1
|
||||
item = i.newObject(c)
|
||||
} catch (e: IOException) {
|
||||
return -1
|
||||
} finally {
|
||||
c.close()
|
||||
}
|
||||
val title = context.getString(R.string.status_not_updated)
|
||||
val message = context.getString(R.string.status_not_updated_summary)
|
||||
val intent = Intent()
|
||||
intent.`package` = BuildConfig.APPLICATION_ID
|
||||
val uriBuilder = Uri.Builder()
|
||||
uriBuilder.scheme(SCHEME_TWIDERE)
|
||||
uriBuilder.authority(AUTHORITY_DRAFTS)
|
||||
intent.data = uriBuilder.build()
|
||||
val nb = NotificationCompat.Builder(context)
|
||||
nb.setTicker(message)
|
||||
nb.setContentTitle(title)
|
||||
nb.setContentText(item.text)
|
||||
nb.setAutoCancel(true)
|
||||
nb.setWhen(System.currentTimeMillis())
|
||||
nb.setSmallIcon(R.drawable.ic_stat_draft)
|
||||
val discardIntent = Intent(context, LengthyOperationsService::class.java)
|
||||
discardIntent.action = INTENT_ACTION_DISCARD_DRAFT
|
||||
val draftUri = Uri.withAppendedPath(Drafts.CONTENT_URI, draftId.toString())
|
||||
discardIntent.data = draftUri
|
||||
nb.addAction(R.drawable.ic_action_delete, context.getString(R.string.discard), PendingIntent.getService(context, 0,
|
||||
discardIntent, PendingIntent.FLAG_ONE_SHOT))
|
||||
|
||||
val sendIntent = Intent(context, LengthyOperationsService::class.java)
|
||||
sendIntent.action = INTENT_ACTION_SEND_DRAFT
|
||||
sendIntent.data = draftUri
|
||||
nb.addAction(R.drawable.ic_action_send, context.getString(R.string.action_send),
|
||||
PendingIntent.getService(context, 0, sendIntent, PendingIntent.FLAG_ONE_SHOT))
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||
nb.setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT))
|
||||
notificationManager.notify(draftUri.toString(), NOTIFICATION_ID_DRAFTS,
|
||||
nb.build())
|
||||
return draftId
|
||||
}
|
||||
|
||||
|
||||
|
@ -452,7 +402,7 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
|
|||
}
|
||||
}
|
||||
VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS -> {
|
||||
rowId = showDraftNotification(values)
|
||||
rowId = contentNotificationManager.showDraft(uri)
|
||||
}
|
||||
else -> {
|
||||
val conflictAlgorithm = getConflictAlgorithm(tableId)
|
||||
|
@ -468,7 +418,7 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
|
|||
}
|
||||
onDatabaseUpdated(tableId, uri)
|
||||
onNewItemsInserted(uri, tableId, arrayOf(values))
|
||||
return Uri.withAppendedPath(uri, rowId.toString())
|
||||
return uri.withAppendedPath(rowId.toString())
|
||||
}
|
||||
|
||||
private fun updateInternal(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
|
||||
|
@ -500,6 +450,9 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
|
|||
notifyContentObserver(uri)
|
||||
}
|
||||
|
||||
private fun onItemDeleted(uri: Uri, tableId: Int) {
|
||||
}
|
||||
|
||||
private fun onNewItemsInserted(uri: Uri, tableId: Int, valuesArray: Array<ContentValues?>?) {
|
||||
val context = context ?: return
|
||||
if (valuesArray.isNullOrEmpty()) return
|
||||
|
|
|
@ -60,7 +60,7 @@ import org.mariotaku.twidere.R
|
|||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
|
||||
import org.mariotaku.twidere.model.schedule.ScheduleInfo
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
|
||||
|
@ -390,7 +390,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||
|
||||
private fun <T> performStatusAction(draft: Draft, action: (accountKey: UserKey, status: ParcelableStatus) -> AbstractTask<*, T, *>): Boolean {
|
||||
val accountKey = draft.account_keys?.firstOrNull() ?: return false
|
||||
val status = (draft.action_extras as? StatusObjectExtras)?.status ?: return false
|
||||
val status = (draft.action_extras as? StatusObjectActionExtras)?.status ?: return false
|
||||
val task = action(accountKey, status)
|
||||
invokeBeforeExecute(task)
|
||||
val result = ManualTaskStarter.invokeExecute(task)
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.mariotaku.twidere.model.Draft
|
|||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.SingleResponse
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
|
||||
import org.mariotaku.twidere.model.event.FavoriteTaskEvent
|
||||
import org.mariotaku.twidere.model.event.StatusListChangedEvent
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
|
@ -45,7 +45,7 @@ class CreateFavoriteTask(
|
|||
override fun doLongOperation(params: Any?): SingleResponse<ParcelableStatus> {
|
||||
val draftId = UpdateStatusTask.saveDraft(context, Draft.Action.FAVORITE) {
|
||||
this@saveDraft.account_keys = arrayOf(accountKey)
|
||||
this@saveDraft.action_extras = StatusObjectExtras().apply {
|
||||
this@saveDraft.action_extras = StatusObjectActionExtras().apply {
|
||||
this@apply.status = this@CreateFavoriteTask.status
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.mariotaku.twidere.model.Draft
|
|||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.SingleResponse
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
|
||||
import org.mariotaku.twidere.model.event.StatusListChangedEvent
|
||||
import org.mariotaku.twidere.model.event.StatusRetweetedEvent
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
|
@ -40,7 +40,7 @@ class RetweetStatusTask(
|
|||
override fun doLongOperation(params: Any?): SingleResponse<ParcelableStatus> {
|
||||
val draftId = UpdateStatusTask.saveDraft(context, Draft.Action.RETWEET) {
|
||||
this@saveDraft.account_keys = arrayOf(accountKey)
|
||||
this@saveDraft.action_extras = StatusObjectExtras().apply {
|
||||
this@saveDraft.action_extras = StatusObjectActionExtras().apply {
|
||||
this@apply.status = this@RetweetStatusTask.status
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.mariotaku.twidere.extension.text.twitter.getTweetLength
|
|||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.account.AccountExtras
|
||||
import org.mariotaku.twidere.model.analyzer.UpdateStatus
|
||||
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras
|
||||
import org.mariotaku.twidere.model.schedule.ScheduleInfo
|
||||
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
|
||||
|
@ -528,13 +527,7 @@ class UpdateStatusTask(
|
|||
this.location = statusUpdate.location
|
||||
this.media = statusUpdate.media
|
||||
this.timestamp = System.currentTimeMillis()
|
||||
this.action_extras = UpdateStatusActionExtras().apply {
|
||||
inReplyToStatus = statusUpdate.in_reply_to_status
|
||||
isPossiblySensitive = statusUpdate.is_possibly_sensitive
|
||||
isRepostStatusId = statusUpdate.repost_status_id
|
||||
displayCoordinates = statusUpdate.display_coordinates
|
||||
attachmentUrl = statusUpdate.attachment_url
|
||||
}
|
||||
this.action_extras = statusUpdate.draft_extras
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.mariotaku.microblog.library.twitter.model.Activity
|
|||
import org.mariotaku.microblog.library.twitter.model.Status
|
||||
import org.mariotaku.sqliteqb.library.*
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.activity.HomeActivity
|
||||
|
@ -50,10 +51,10 @@ import org.mariotaku.twidere.extension.model.notificationDisabled
|
|||
import org.mariotaku.twidere.extension.rawQuery
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||
import org.mariotaku.twidere.receiver.NotificationReceiver
|
||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||
import org.mariotaku.twidere.util.database.FilterQueryBuilder
|
||||
import org.oshkimaadziig.george.androidutils.SpanFormatter
|
||||
import java.io.IOException
|
||||
|
@ -355,6 +356,53 @@ class ContentNotificationManager(
|
|||
notificationManager.notify(tag, NOTIFICATION_ID_USER_NOTIFICATION, builder.build())
|
||||
}
|
||||
|
||||
fun showDraft(draftUri: Uri): Long {
|
||||
val draftId = draftUri.lastPathSegment.toLongOrNull() ?: return -1
|
||||
val where = Expression.equals(Drafts._ID, draftId)
|
||||
val c = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql,
|
||||
null, null) ?: return -1
|
||||
val i = ObjectCursor.indicesFrom(c, Draft::class.java)
|
||||
val item: Draft
|
||||
try {
|
||||
if (!c.moveToFirst()) return -1
|
||||
item = i.newObject(c)
|
||||
} catch (e: IOException) {
|
||||
return -1
|
||||
} finally {
|
||||
c.close()
|
||||
}
|
||||
val title = context.getString(R.string.status_not_updated)
|
||||
val message = context.getString(R.string.status_not_updated_summary)
|
||||
val intent = Intent()
|
||||
intent.`package` = BuildConfig.APPLICATION_ID
|
||||
val uriBuilder = Uri.Builder()
|
||||
uriBuilder.scheme(SCHEME_TWIDERE)
|
||||
uriBuilder.authority(AUTHORITY_DRAFTS)
|
||||
intent.data = uriBuilder.build()
|
||||
val nb = NotificationCompat.Builder(context)
|
||||
nb.setTicker(message)
|
||||
nb.setContentTitle(title)
|
||||
nb.setContentText(item.text)
|
||||
nb.setAutoCancel(true)
|
||||
nb.setWhen(System.currentTimeMillis())
|
||||
nb.setSmallIcon(R.drawable.ic_stat_draft)
|
||||
val discardIntent = Intent(context, LengthyOperationsService::class.java)
|
||||
discardIntent.action = INTENT_ACTION_DISCARD_DRAFT
|
||||
discardIntent.data = draftUri
|
||||
nb.addAction(R.drawable.ic_action_delete, context.getString(R.string.discard),
|
||||
PendingIntent.getService(context, 0, discardIntent, PendingIntent.FLAG_ONE_SHOT))
|
||||
|
||||
val sendIntent = Intent(context, LengthyOperationsService::class.java)
|
||||
sendIntent.action = INTENT_ACTION_SEND_DRAFT
|
||||
sendIntent.data = draftUri
|
||||
nb.addAction(R.drawable.ic_action_send, context.getString(R.string.action_send),
|
||||
PendingIntent.getService(context, 0, sendIntent, PendingIntent.FLAG_ONE_SHOT))
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||
nb.setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT))
|
||||
notificationManager.notify(draftUri.toString(), NOTIFICATION_ID_DRAFTS, nb.build())
|
||||
return draftId
|
||||
}
|
||||
|
||||
fun updatePreferences() {
|
||||
nameFirst = preferences[nameFirstKey]
|
||||
useStarForLikes = preferences[iWantMyStarsBackKey]
|
||||
|
|
|
@ -116,7 +116,7 @@ object DataStoreUtils {
|
|||
VIRTUAL_TABLE_ID_DRAFTS_UNSENT)
|
||||
CONTENT_PROVIDER_URI_MATCHER.addURI(TwidereDataStore.AUTHORITY, Drafts.CONTENT_PATH_NOTIFICATIONS,
|
||||
VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS)
|
||||
CONTENT_PROVIDER_URI_MATCHER.addURI(TwidereDataStore.AUTHORITY, Drafts.CONTENT_PATH_NOTIFICATIONS,
|
||||
CONTENT_PROVIDER_URI_MATCHER.addURI(TwidereDataStore.AUTHORITY, Drafts.CONTENT_PATH_NOTIFICATIONS + "/#",
|
||||
VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS)
|
||||
CONTENT_PROVIDER_URI_MATCHER.addURI(TwidereDataStore.AUTHORITY, Suggestions.AutoComplete.CONTENT_PATH,
|
||||
VIRTUAL_TABLE_ID_SUGGESTIONS_AUTO_COMPLETE)
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.mariotaku.twidere.R
|
|||
import org.mariotaku.twidere.extension.model.getActionName
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.ParcelableMedia
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectExtras
|
||||
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
|
||||
import org.mariotaku.twidere.util.DataStoreUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
|
@ -54,7 +54,7 @@ class DraftViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
|||
media = media)
|
||||
}
|
||||
Draft.Action.FAVORITE, Draft.Action.RETWEET -> {
|
||||
val extras = draft.action_extras as? StatusObjectExtras
|
||||
val extras = draft.action_extras as? StatusObjectActionExtras
|
||||
if (extras != null) {
|
||||
summaryText = extras.status.text_unescaped
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue