diff --git a/build.gradle b/build.gradle index df022d09d..b58f3e952 100644 --- a/build.gradle +++ b/build.gradle @@ -6,9 +6,9 @@ buildscript { jcenter() } dependencies { - classpath 'com.github.ben-manes:gradle-versions-plugin:0.9' + classpath 'com.github.ben-manes:gradle-versions-plugin:0.11.3' classpath 'com.android.tools.build:gradle:1.2.3' - classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.5.1' classpath('fr.avianey.androidsvgdrawable:gradle-plugin:1.0.2') { // should be excluded to avoid conflict exclude group: 'xerces' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 819314ff3..3580a6200 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java index f63ca9b85..889fd1555 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java @@ -83,6 +83,7 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String AUTHORITY_DIRECT_MESSAGES_CONVERSATION = "direct_messages_conversation"; String AUTHORITY_SEARCH = "search"; String AUTHORITY_MAP = "map"; + String AUTHORITY_SCHEDULED_STATUSES = "scheduled_statuses"; String AUTHORITY_USER_LIST = "user_list"; String AUTHORITY_USER_LIST_TIMELINE = "user_list_timeline"; String AUTHORITY_USER_LIST_MEMBERS = "user_list_members"; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/PrivateScheduleResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/PrivateScheduleResources.java index 975c3602b..7bf234c22 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/PrivateScheduleResources.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/PrivateScheduleResources.java @@ -20,13 +20,19 @@ package org.mariotaku.twidere.api.twitter.api; import org.mariotaku.restfu.annotation.method.DELETE; +import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.POST; import org.mariotaku.restfu.annotation.method.PUT; import org.mariotaku.restfu.annotation.param.Body; import org.mariotaku.restfu.annotation.param.Form; +import org.mariotaku.restfu.annotation.param.MethodExtra; import org.mariotaku.restfu.annotation.param.Path; +import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.http.BodyType; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.Paging; import org.mariotaku.twidere.api.twitter.model.ScheduledStatus; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatusesList; import org.mariotaku.twidere.api.twitter.model.StatusSchedule; /** @@ -36,13 +42,17 @@ public interface PrivateScheduleResources { @POST("/schedule/status/tweet.json") @Body(BodyType.FORM) - ScheduledStatus scheduleTweet(@Form StatusSchedule schedule); + ScheduledStatus scheduleTweet(@Form StatusSchedule schedule) throws TwitterException; @DELETE("/schedule/status/{id}.json") - ScheduledStatus destroyScheduleTweet(@Path("id") long id); + ScheduledStatus destroyScheduleTweet(@Path("id") long id) throws TwitterException; @PUT("/schedule/status/{id}.json") @Body(BodyType.FORM) - ScheduledStatus updateScheduleTweet(@Path("id") long id, @Form StatusSchedule schedule); + ScheduledStatus updateScheduleTweet(@Path("id") long id, @Form StatusSchedule schedule) throws TwitterException; + + @GET("/schedule/status/list.json") + @MethodExtra(name = "extra_params", values = {"include_entities", "include_cards", "cards_platform"}) + ScheduledStatusesList getScheduledStatusesList(@Query Paging paging, @Query("state") ScheduledStatus.State[] states) throws TwitterException; } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ExtendedProfile.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ExtendedProfile.java new file mode 100644 index 000000000..9bcd83984 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ExtendedProfile.java @@ -0,0 +1,53 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.api.twitter.model; + +/** + * Created by mariotaku on 15/7/8. + */ +public interface ExtendedProfile { + + long getId(); + + Birthdate getBirthdate(); + + interface Birthdate { + int getDay(); + + int getMonth(); + + int getYear(); + + Visibility getVisibility(); + + Visibility getYearVisibility(); + + enum Visibility { + MUTUALFOLLOW, PUBLIC, UNKNOWN; + + public static Visibility parse(String s) { + if ("mutualfollow".equals(s)) return MUTUALFOLLOW; + if ("public".equals(s)) return PUBLIC; + return UNKNOWN; + } + } + } + +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatus.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatus.java index cbd6223e3..df2a3809f 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatus.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatus.java @@ -26,6 +26,12 @@ import java.util.Date; */ public interface ScheduledStatus { + long getUserId(); + + boolean isPossiblySensitive(); + + long getId(); + long[] getMediaIds(); Date getUpdatedAt(); @@ -35,4 +41,32 @@ public interface ScheduledStatus { Date getExecuteAt(); String getText(); + + State getState(); + + enum State { + SCHEDULED("scheduled"), FAILED("failed"), CANCELED("canceled"); + + private final String value; + + State(String value) { + this.value = value; + } + + public static State parse(String value) { + if (SCHEDULED.value.equalsIgnoreCase(value)) { + return SCHEDULED; + } else if (FAILED.value.equalsIgnoreCase(value)) { + return FAILED; + } else if (CANCELED.value.equalsIgnoreCase(value)) { + return CANCELED; + } + return null; + } + + @Override + public String toString() { + return value; + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ErrorLogger.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatusesList.java similarity index 63% rename from twidere/src/main/java/org/mariotaku/twidere/util/ErrorLogger.java rename to twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatusesList.java index e3d501f6a..72b678f87 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ErrorLogger.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/ScheduledStatusesList.java @@ -17,25 +17,10 @@ * along with this program. If not, see . */ -package org.mariotaku.twidere.util; - -import org.acra.ACRA; -import org.mariotaku.twidere.activity.TwitterLinkHandlerActivity; +package org.mariotaku.twidere.api.twitter.model; /** - * Created by mariotaku on 15/5/25. + * Created by mariotaku on 15/7/9. */ -public class ErrorLogger { - - private static boolean sEnabled; - - public static void setEnabled(boolean enabled) { - sEnabled = enabled; - } - - public static void exception(final Throwable t) { - if (!sEnabled) return; - ACRA.getErrorReporter().handleSilentException(t); - } - +public interface ScheduledStatusesList extends ResponseList { } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ExtendedProfileImpl.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ExtendedProfileImpl.java new file mode 100644 index 000000000..7dbd4cfe6 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ExtendedProfileImpl.java @@ -0,0 +1,87 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.api.twitter.model.impl; + +import com.bluelinelabs.logansquare.annotation.JsonField; +import com.bluelinelabs.logansquare.annotation.JsonObject; + +import org.mariotaku.twidere.api.twitter.model.ExtendedProfile; + +/** + * Created by mariotaku on 15/7/8. + */ +@JsonObject +public class ExtendedProfileImpl implements ExtendedProfile { + + @JsonField(name = "id") + long id; + @JsonField(name = "birthdate") + BirthdateImpl birthdate; + + @Override + public long getId() { + return id; + } + + @Override + public Birthdate getBirthdate() { + return birthdate; + } + + @JsonObject + public static class BirthdateImpl implements Birthdate { + + @JsonField(name = "day") + int day; + @JsonField(name = "month") + int month; + @JsonField(name = "year") + int year; + @JsonField(name = "visibility") + Visibility visibility; + @JsonField(name = "year_visibility") + Visibility yearVisibility; + + @Override + public int getDay() { + return day; + } + + @Override + public int getMonth() { + return month; + } + + @Override + public int getYear() { + return year; + } + + @Override + public Visibility getVisibility() { + return visibility; + } + + @Override + public Visibility getYearVisibility() { + return yearVisibility; + } + } +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusImpl.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusImpl.java index 84580b32c..41fefb31b 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusImpl.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusImpl.java @@ -43,6 +43,29 @@ public class ScheduledStatusImpl implements ScheduledStatus { String text; @JsonField(name = "media_ids") long[] mediaIds; + @JsonField(name = "id") + long id; + @JsonField(name = "possiblySensitive") + boolean possiblySensitive; + @JsonField(name = "user_id") + long userId; + @JsonField(name = "state") + State state; + + @Override + public long getUserId() { + return userId; + } + + @Override + public boolean isPossiblySensitive() { + return possiblySensitive; + } + + @Override + public long getId() { + return id; + } @Override public long[] getMediaIds() { @@ -68,4 +91,9 @@ public class ScheduledStatusImpl implements ScheduledStatus { public String getText() { return text; } + + @Override + public State getState() { + return state; + } } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusesListWrapper.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusesListWrapper.java new file mode 100644 index 000000000..559a25ce2 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/impl/ScheduledStatusesListWrapper.java @@ -0,0 +1,73 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.api.twitter.model.impl; + +import com.bluelinelabs.logansquare.annotation.JsonField; +import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete; + +import org.mariotaku.restfu.http.RestHttpResponse; +import org.mariotaku.twidere.api.twitter.model.RateLimitStatus; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatus; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatusesList; + +import java.util.ArrayList; + +/** + * Created by mariotaku on 15/7/9. + */ +@JsonObject +public class ScheduledStatusesListWrapper implements Wrapper { + + @JsonField(name = "results") + ArrayList list; + private ScheduledStatusesListImpl wrapped; + + @Override + public ScheduledStatusesList getWrapped(Object extra) { + return wrapped; + } + + @Override + public void processResponseHeader(RestHttpResponse resp) { + wrapped.processResponseHeader(resp); + } + + @OnJsonParseComplete + void onParseComplete() { + // Do some fancy post-processing stuff after parsing here + wrapped = new ScheduledStatusesListImpl(); + wrapped.addAll(list); + } + + @Override + public int getAccessLevel() { + return wrapped.getAccessLevel(); + } + + @Override + public RateLimitStatus getRateLimitStatus() { + return wrapped.getRateLimitStatus(); + } + + @JsonObject + public static class ScheduledStatusesListImpl extends ResponseListImpl implements ScheduledStatusesList { + } +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterConverter.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterConverter.java index 9e1a53ce3..6d03f87df 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterConverter.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterConverter.java @@ -37,6 +37,7 @@ import org.mariotaku.twidere.api.twitter.model.Activity; import org.mariotaku.twidere.api.twitter.model.CardEntity; import org.mariotaku.twidere.api.twitter.model.DirectMessage; import org.mariotaku.twidere.api.twitter.model.ErrorInfo; +import org.mariotaku.twidere.api.twitter.model.ExtendedProfile; import org.mariotaku.twidere.api.twitter.model.GeoLocation; import org.mariotaku.twidere.api.twitter.model.HashtagEntity; import org.mariotaku.twidere.api.twitter.model.IDs; @@ -52,6 +53,7 @@ import org.mariotaku.twidere.api.twitter.model.ResponseCode; import org.mariotaku.twidere.api.twitter.model.ResponseList; import org.mariotaku.twidere.api.twitter.model.SavedSearch; import org.mariotaku.twidere.api.twitter.model.ScheduledStatus; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatusesList; import org.mariotaku.twidere.api.twitter.model.Status; import org.mariotaku.twidere.api.twitter.model.StatusActivitySummary; import org.mariotaku.twidere.api.twitter.model.StatusDeletionNotice; @@ -69,6 +71,7 @@ import org.mariotaku.twidere.api.twitter.model.impl.ActivityImpl; import org.mariotaku.twidere.api.twitter.model.impl.CardEntityImpl; import org.mariotaku.twidere.api.twitter.model.impl.DirectMessageImpl; import org.mariotaku.twidere.api.twitter.model.impl.ErrorInfoImpl; +import org.mariotaku.twidere.api.twitter.model.impl.ExtendedProfileImpl; import org.mariotaku.twidere.api.twitter.model.impl.HashtagEntityImpl; import org.mariotaku.twidere.api.twitter.model.impl.IDsImpl; import org.mariotaku.twidere.api.twitter.model.impl.Indices; @@ -84,6 +87,7 @@ import org.mariotaku.twidere.api.twitter.model.impl.RelationshipWrapper; import org.mariotaku.twidere.api.twitter.model.impl.ResponseListImpl; import org.mariotaku.twidere.api.twitter.model.impl.SavedSearchImpl; import org.mariotaku.twidere.api.twitter.model.impl.ScheduledStatusImpl; +import org.mariotaku.twidere.api.twitter.model.impl.ScheduledStatusesListWrapper; import org.mariotaku.twidere.api.twitter.model.impl.StatusActivitySummaryImpl; import org.mariotaku.twidere.api.twitter.model.impl.StatusDeletionNoticeImpl; import org.mariotaku.twidere.api.twitter.model.impl.StatusImpl; @@ -155,6 +159,7 @@ public class TwitterConverter implements Converter { TypeConverterMapper.register(Warning.class, WarningImpl.class); TypeConverterMapper.register(StatusDeletionNotice.class, StatusDeletionNoticeImpl.class); TypeConverterMapper.register(ScheduledStatus.class, ScheduledStatusImpl.class); + TypeConverterMapper.register(ExtendedProfile.class, ExtendedProfileImpl.class); LoganSquare.registerTypeConverter(Indices.class, Indices.CONVERTER); LoganSquare.registerTypeConverter(GeoLocation.class, GeoLocation.CONVERTER); @@ -163,11 +168,13 @@ public class TwitterConverter implements Converter { LoganSquare.registerTypeConverter(MediaEntity.Type.class, EnumConverter.get(MediaEntity.Type.class)); LoganSquare.registerTypeConverter(UserList.Mode.class, EnumConverter.get(UserList.Mode.class)); LoganSquare.registerTypeConverter(Activity.Action.class, EnumConverter.get(Activity.Action.class)); + LoganSquare.registerTypeConverter(ScheduledStatus.State.class, EnumConverter.get(ScheduledStatus.State.class)); registerWrapper(QueryResult.class, QueryResultWrapper.class); registerWrapper(PageableResponseList.class, PageableResponseListWrapper.class); registerWrapper(Relationship.class, RelationshipWrapper.class); registerWrapper(CardEntity.BindingValue.class, CardEntityImpl.BindingValueWrapper.class); + registerWrapper(ScheduledStatusesList.class, ScheduledStatusesListWrapper.class); } @Override diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterDateConverter.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterDateConverter.java index 12dc948cf..fc1831034 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterDateConverter.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/util/TwitterDateConverter.java @@ -19,24 +19,50 @@ package org.mariotaku.twidere.api.twitter.util; -import com.bluelinelabs.logansquare.typeconverters.DateTypeConverter; +import com.bluelinelabs.logansquare.typeconverters.StringBasedTypeConverter; + +import org.mariotaku.twidere.util.AbsLogger; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Locale; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; /** * Created by mariotaku on 15/5/7. */ -public class TwitterDateConverter extends DateTypeConverter { +public class TwitterDateConverter extends StringBasedTypeConverter { + private static final long ONE_MINUTE = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES); private final DateFormat mDateFormat; public TwitterDateConverter() { - mDateFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.ENGLISH); + mDateFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.US); + mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - public DateFormat getDateFormat() { - return mDateFormat; + @Override + public Date getFromString(String string) { + final Date date; + try { + date = mDateFormat.parse(string); + } catch (ParseException e) { + AbsLogger.error("Unrecognized date: " + string, e); + return null; + } + final long currentTime = System.currentTimeMillis(); + if (date.getTime() - currentTime > ONE_MINUTE) { + AbsLogger.error("Tweet date from future: " + string + ", current time is " + currentTime); + } + return date; } + + @Override + public String convertToString(Date date) { + return mDateFormat.format(date); + } + } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ObjectCursor.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ObjectCursor.java index b53dd4c19..255d74a4f 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ObjectCursor.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ObjectCursor.java @@ -50,7 +50,7 @@ public class ObjectCursor extends AbstractList { mCache.put(location, object); return object; } - throw new ArrayIndexOutOfBoundsException(location); + throw new ArrayIndexOutOfBoundsException("length=" + mCursor.getCount() + "; index=" + location); } private void ensureCursor() { 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 3157a8ce5..f4bbe4c3d 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 @@ -250,6 +250,12 @@ public class ParcelableAccount implements Parcelable { return getCredentialsList(context, activatedOnly, false); } + public static ParcelableCredentials[] getCredentialsArray(final Context context, final boolean activatedOnly, + final boolean officialKeyOnly) { + final List credentialsList = getCredentialsList(context, activatedOnly, officialKeyOnly); + return credentialsList.toArray(new ParcelableCredentials[credentialsList.size()]); + } + public static List getCredentialsList(final Context context, final boolean activatedOnly, final boolean officialKeyOnly) { if (context == null) return Collections.emptyList(); 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 63082e4fa..4d8b0a6fd 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 @@ -648,7 +648,12 @@ public class ParcelableStatus implements Parcelable, Comparable + * + * 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 . + */ + +package org.mariotaku.twidere.util; + +import android.app.Application; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * Created by mariotaku on 15/7/8. + */ +public abstract class AbsLogger { + + private static AbsLogger sImplementation; + + public static void setImplementation(AbsLogger impl) { + sImplementation = impl; + } + + public static void log(@Nullable String message, @Nullable Throwable throwable) { + if (sImplementation == null) return; + sImplementation.logImpl(message, throwable); + } + + public static void error(@Nullable String message, @Nullable Throwable throwable) { + if (sImplementation == null) return; + sImplementation.errorImpl(message, throwable); + } + + public static void error(@NonNull String message) { + error(message, null); + } + + public static void init(Application application) { + if (sImplementation == null) return; + sImplementation.initImpl(application); + } + + public static void error(Throwable throwable) { + error(null, throwable); + } + + protected abstract void logImpl(@Nullable String message, @Nullable Throwable throwable); + + protected abstract void errorImpl(@Nullable String message, @Nullable Throwable throwable); + + protected abstract void initImpl(Application application); +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwitterContentUtils.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwitterContentUtils.java index ce4104113..663e59460 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwitterContentUtils.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwitterContentUtils.java @@ -41,6 +41,7 @@ import org.mariotaku.twidere.util.collection.LongSparseMap; import java.nio.charset.Charset; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.CRC32; @@ -53,6 +54,7 @@ import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText; public class TwitterContentUtils { public static final int TWITTER_BULK_QUERY_COUNT = 100; + private static final long ONE_MINUTE = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES); public static String formatDirectMessageText(final DirectMessage message) { if (message == null) return null; @@ -240,4 +242,11 @@ public class TwitterContentUtils { } } } + + public static void checkTime(long that, long current) { + if (that <= 0) return; + if ((that - current) > ONE_MINUTE) { + AbsLogger.error(new Exception("Wrong timestamp " + that + ", current " + current)); + } + } } diff --git a/twidere.donate.nyanwp.wear/build.gradle b/twidere.donate.nyanwp.wear/build.gradle index 7f551661b..e0e435a38 100644 --- a/twidere.donate.nyanwp.wear/build.gradle +++ b/twidere.donate.nyanwp.wear/build.gradle @@ -36,7 +36,7 @@ android { } dependencies { - compile 'com.google.android.support:wearable:1.1.0' + compile 'com.google.android.support:wearable:1.2.0' compile project(':twidere.component.nyan') compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere.wear/build.gradle b/twidere.wear/build.gradle index 2acb1900a..03b52ffd7 100644 --- a/twidere.wear/build.gradle +++ b/twidere.wear/build.gradle @@ -41,5 +41,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.google.android.support:wearable:1.1.0' - compile 'com.google.android.gms:play-services-wearable:7.3.0' + compile 'com.google.android.gms:play-services-wearable:7.5.0' } diff --git a/twidere/build.gradle b/twidere/build.gradle index e85aafe05..36b7c078a 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -63,21 +63,19 @@ dependencies { compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:cardview-v7:22.2.0' compile 'com.android.support:recyclerview-v7:22.2.0' - compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'com.twitter:twitter-text:1.12.1' compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4' compile 'com.squareup:otto:1.3.7' compile 'dnsjava:dnsjava:2.1.7' compile 'com.commonsware.cwac:merge:1.1.1' - compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.1.3' - compile 'com.rengwuxian.materialedittext:library:2.1.3' + compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.1.4' + compile 'com.rengwuxian.materialedittext:library:2.1.4' compile 'com.pnikosis:materialish-progress:1.5' compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.7' compile 'com.github.johnpersano:supertoasts:1.3.4.1@aar' compile 'com.github.mariotaku:MessageBubbleView:1.2' compile 'com.github.mariotaku:DragSortListView:0.6.1' - compile 'com.github.mariotaku:SlidingMenu:1.3' compile 'com.github.uucky:ColorPicker-Android:0.9.7@aar' compile 'com.github.boxme:asyncmanager:1.0.0' compile 'com.sprylab.android.texturevideoview:texturevideoview:1.0.0' @@ -87,7 +85,7 @@ dependencies { compile 'ch.acra:acra:4.6.2' compile 'org.jraf:android-switch-backport:2.0.1' compile 'com.fasterxml.jackson.jr:jackson-jr-objects:2.3.0' - compile 'com.makeramen:roundedimageview:2.1.0' + compile 'com.makeramen:roundedimageview:2.1.1' compile 'com.soundcloud.android:android-crop:1.0.0@aar' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1' compile 'com.github.mariotaku:PickNCrop:44b09cbc69' diff --git a/twidere/src/fdroid/java/org/mariotaku/twidere/fragment/support/OpenStreetMapViewerFragment.java b/twidere/src/fdroid/java/org/mariotaku/twidere/fragment/support/OpenStreetMapViewerFragment.java index fea6c222a..0a3cca86d 100644 --- a/twidere/src/fdroid/java/org/mariotaku/twidere/fragment/support/OpenStreetMapViewerFragment.java +++ b/twidere/src/fdroid/java/org/mariotaku/twidere/fragment/support/OpenStreetMapViewerFragment.java @@ -98,7 +98,7 @@ public class OpenStreetMapViewerFragment extends BaseSupportFragment implements @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_CENTER: { + case R.id.center: { moveToCenter(mLatitude, mLongitude); break; } diff --git a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/GoogleMapFragment.java b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/GoogleMapFragment.java index 97347e4ea..471dfebae 100644 --- a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/GoogleMapFragment.java +++ b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/GoogleMapFragment.java @@ -74,7 +74,7 @@ public class GoogleMapFragment extends SupportMapFragment implements Constants, @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_CENTER: { + case R.id.center: { center(); break; } diff --git a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/WebMapFragment.java b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/WebMapFragment.java index 0aa73e92c..25b6256c4 100644 --- a/twidere/src/google/java/org/mariotaku/twidere/fragment/support/WebMapFragment.java +++ b/twidere/src/google/java/org/mariotaku/twidere/fragment/support/WebMapFragment.java @@ -50,7 +50,7 @@ public class WebMapFragment extends BaseSupportWebViewFragment implements IMapFr @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_CENTER: { + case R.id.center: { center(); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/Constants.java b/twidere/src/main/java/org/mariotaku/twidere/Constants.java index d3f396a43..1924dd7d5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/Constants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/Constants.java @@ -42,82 +42,6 @@ public interface Constants extends TwidereConstants { int MENU_GROUP_USER_LIST_EXTENSION = 14; int MENU_GROUP_STATUS_SHARE = 20; - int MENU_HOME = android.R.id.home; - int MENU_SEARCH = R.id.search; - int MENU_ACTIONS = R.id.actions; - int MENU_COMPOSE = R.id.compose; - int MENU_SEND = R.id.send; - int MENU_EDIT = R.id.edit; - int MENU_INFO = R.id.info; - int MENU_SELECT_ACCOUNT = R.id.select_account; - int MENU_SETTINGS = R.id.settings; - int MENU_ADD_LOCATION = R.id.add_location; - int MENU_TAKE_PHOTO = R.id.take_photo; - int MENU_ADD_IMAGE = R.id.add_image; - int MENU_LOCATION = R.id.location; - int MENU_IMAGE = R.id.image; - int MENU_VIEW = R.id.view; - int MENU_VIEW_PROFILE = R.id.view_profile; - int MENU_DELETE = R.id.delete; - int MENU_DELETE_SUBMENU = R.id.delete_submenu; - int MENU_TOGGLE = R.id.toggle; - int MENU_ADD = R.id.add; - int MENU_PICK_FROM_GALLERY = R.id.pick_from_gallery; - int MENU_PICK_FROM_MAP = R.id.pick_from_map; - int MENU_EDIT_API = R.id.edit_api; - int MENU_OPEN_IN_BROWSER = R.id.open_in_browser; - int MENU_SET_COLOR = R.id.set_color; - int MENU_ADD_ACCOUNT = R.id.add_account; - int MENU_REPLY = R.id.reply; - int MENU_FAVORITE = R.id.favorite; - int MENU_RETWEET = R.id.retweet; - int MENU_QUOTE = R.id.quote; - int MENU_SHARE = R.id.share; - int MENU_DRAFTS = R.id.drafts; - int MENU_DELETE_ALL = R.id.delete_all; - int MENU_SET_AS_DEFAULT = R.id.set_as_default; - int MENU_SAVE = R.id.save; - int MENU_CANCEL = R.id.cancel; - int MENU_BLOCK = R.id.block; - int MENU_REPORT_SPAM = R.id.report_spam; - int MENU_MUTE_SOURCE = R.id.mute_source; - int MENU_MUTE_USER = R.id.mute_user; - int MENU_REFRESH = R.id.refresh; - int MENU_MENTION = R.id.mention; - int MENU_SEND_DIRECT_MESSAGE = R.id.send_direct_message; - int MENU_VIEW_USER_LIST = R.id.view_user_list; - int MENU_UP = R.id.up; - int MENU_DOWN = R.id.down; - int MENU_COPY = R.id.copy; - int MENU_TOGGLE_SENSITIVE = R.id.toggle_sensitive; - int MENU_REVOKE = R.id.revoke; - int MENU_ADD_TO_LIST = R.id.add_to_list; - int MENU_DELETE_FROM_LIST = R.id.delete_from_list; - int MENU_STATUSES = R.id.statuses; - int MENU_FAVORITES = R.id.favorites; - int MENU_LISTS = R.id.lists; - int MENU_LIST_MEMBERSHIPS = R.id.list_memberships; - int MENU_CENTER = R.id.center; - int MENU_FILTERS = R.id.filters; - int MENU_SET_NICKNAME = R.id.set_nickname; - int MENU_CLEAR_NICKNAME = R.id.clear_nickname; - int MENU_ADD_TO_FILTER = R.id.add_to_filter; - int MENU_FOLLOW = R.id.follow; - int MENU_UNFOLLOW = R.id.unfollow; - int MENU_BACK = R.id.back; - int MENU_TRANSLATE = R.id.translate; - int MENU_ACCEPT = R.id.accept; - int MENU_DENY = R.id.deny; - int MENU_IMPORT_SETTINGS = R.id.import_settings; - int MENU_EXPORT_SETTINGS = R.id.export_settings; - int MENU_PROGRESS = R.id.progress; - int MENU_OPEN_WITH_ACCOUNT = R.id.open_with_account; - int MENU_ACCOUNTS = R.id.accounts; - int MENU_INVERSE_SELECTION = R.id.inverse_selection; - int MENU_EDIT_MEDIA = R.id.edit_media; - int MENU_RESET = R.id.reset; - int MENU_ENABLE_RETWEETS = R.id.enable_retweets; - int LINK_ID_STATUS = 1; int LINK_ID_USER = 2; int LINK_ID_USER_TIMELINE = 3; @@ -144,6 +68,7 @@ public interface Constants extends TwidereConstants { int LINK_ID_SEARCH = 28; int LINK_ID_MUTES_USERS = 41; int LINK_ID_MAP = 51; + int LINK_ID_SCHEDULED_STATUSES = 61; int LINK_ID_ACCOUNTS = 101; int LINK_ID_DRAFTS = 102; int LINK_ID_FILTERS = 103; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java index 2deb61d2b..1dd44ba4c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java @@ -198,12 +198,12 @@ public class SettingsActivity extends BasePreferenceActivity { @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_IMPORT_SETTINGS: { + case R.id.import_settings: { final Intent intent = new Intent(this, DataImportActivity.class); startActivity(intent); return true; } - case MENU_EXPORT_SETTINGS: { + case R.id.export_settings: { final Intent intent = new Intent(this, DataExportActivity.class); startActivity(intent); return true; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java index e82e6e970..9199d1e3d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java @@ -14,7 +14,7 @@ import android.text.TextUtils; import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.activity.support.ComposeActivity; -import org.mariotaku.twidere.util.ErrorLogger; +import org.mariotaku.twidere.util.AbsLogger; import org.mariotaku.twidere.util.Utils; import java.util.List; @@ -112,7 +112,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants { if (handledIntent != null) { startActivity(handledIntent); } else { - ErrorLogger.exception(new TwitterLinkException("Unable to handle twitter uri " + uri)); + AbsLogger.error(new TwitterLinkException("Unable to handle twitter uri " + uri)); final String packageName = mPreferences.getString(KEY_FALLBACK_TWITTER_LINK_HANDLER, null); final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri); fallbackIntent.setPackage(packageName); diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseAppCompatActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseAppCompatActivity.java index fcd672524..d7e8a2703 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseAppCompatActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseAppCompatActivity.java @@ -28,6 +28,7 @@ import android.view.KeyEvent; import android.view.MenuItem; import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.iface.IControlBarActivity; import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; @@ -110,7 +111,7 @@ public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Co @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_BACK: { + case R.id.back: { onBackPressed(); return true; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java index ab18a63a8..62c1ae4ed 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java @@ -90,7 +90,7 @@ public class BrowserSignInActivity extends BaseSupportDialogActivity { @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_HOME: { + case android.R.id.home: { finish(); return true; } 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 77a1ed47e..b7a32f4fd 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,8 +95,10 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants; import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment; import org.mariotaku.twidere.fragment.support.SupportProgressDialogFragment; import org.mariotaku.twidere.fragment.support.ViewStatusDialogFragment; +import org.mariotaku.twidere.model.ConsumerKeyType; import org.mariotaku.twidere.model.DraftItem; import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableMediaUpdate; @@ -120,6 +122,7 @@ import org.mariotaku.twidere.util.SharedPreferencesWrapper; import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.TwidereArrayUtils; import org.mariotaku.twidere.util.TwidereValidator; +import org.mariotaku.twidere.util.TwitterContentUtils; import org.mariotaku.twidere.util.UserColorNameManager; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.view.ActionIconView; @@ -398,36 +401,36 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL @Override public boolean onMenuItemClick(final MenuItem item) { switch (item.getItemId()) { - case MENU_TAKE_PHOTO: + case R.id.take_photo: case R.id.take_photo_sub_item: { takePhoto(); break; } - case MENU_ADD_IMAGE: + case R.id.add_image: case R.id.add_image_sub_item: { pickImage(); break; } - case MENU_ADD_LOCATION: { + case R.id.add_location: { toggleLocation(); break; } - case MENU_DRAFTS: { + case R.id.drafts: { Utils.openDrafts(this); break; } - case MENU_DELETE: { + case R.id.delete: { AsyncTaskUtils.executeTask(new DeleteImageTask(this)); break; } - case MENU_TOGGLE_SENSITIVE: { + case R.id.toggle_sensitive: { if (!hasMedia()) return false; mIsPossiblySensitive = !mIsPossiblySensitive; setMenu(); updateTextCount(); break; } - case MENU_VIEW: { + case R.id.view: { if (mInReplyToStatus == null) return false; final DialogFragment fragment = new ViewStatusDialogFragment(); final Bundle args = new Bundle(); @@ -644,7 +647,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL }); mAccountsAdapter = new AccountIconsAdapter(this); mAccountSelector.setAdapter(mAccountsAdapter); - mAccountsAdapter.setAccounts(ParcelableAccount.getAccounts(this, false, false)); + mAccountsAdapter.setAccounts(ParcelableCredentials.getCredentialsArray(this, false, false)); mMediaPreviewAdapter = new MediaPreviewAdapter(this); mMediaPreviewGrid.setAdapter(mMediaPreviewAdapter); @@ -1009,6 +1012,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL final ParcelableAccount[] accounts = mAccountsAdapter.getSelectedAccounts(); setSelectedAccounts(accounts); mEditText.setAccountId(accounts.length > 0 ? accounts[0].account_id : Utils.getDefaultAccountId(this)); + setMenu(); // mAccountActionProvider.setSelectedAccounts(mAccountsAdapter.getSelectedAccounts()); } @@ -1071,23 +1075,34 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL * Has media & Not reply: [Take photo][Media menu][Attach location][Drafts] * Is reply: [Media menu][View status][Attach location][Drafts] */ - MenuUtils.setMenuItemAvailability(menu, MENU_TAKE_PHOTO, !hasInReplyTo); + MenuUtils.setMenuItemAvailability(menu, R.id.take_photo, !hasInReplyTo); MenuUtils.setMenuItemAvailability(menu, R.id.take_photo_sub_item, hasInReplyTo); - MenuUtils.setMenuItemAvailability(menu, MENU_ADD_IMAGE, !hasMedia && !hasInReplyTo); - MenuUtils.setMenuItemAvailability(menu, MENU_VIEW, hasInReplyTo); + MenuUtils.setMenuItemAvailability(menu, R.id.add_image, !hasMedia && !hasInReplyTo); + MenuUtils.setMenuItemAvailability(menu, R.id.view, hasInReplyTo); MenuUtils.setMenuItemAvailability(menu, R.id.media_menu, hasMedia || hasInReplyTo); - MenuUtils.setMenuItemAvailability(menu, MENU_TOGGLE_SENSITIVE, hasMedia); - MenuUtils.setMenuItemAvailability(menu, MENU_EDIT_MEDIA, hasMedia); + MenuUtils.setMenuItemAvailability(menu, R.id.toggle_sensitive, hasMedia); + MenuUtils.setMenuItemAvailability(menu, R.id.edit_media, hasMedia); MenuUtils.setMenuItemAvailability(menu, R.id.link_to_quoted_status, isQuote()); + MenuUtils.setMenuItemAvailability(menu, R.id.schedule, isScheduleSupported()); menu.setGroupEnabled(MENU_GROUP_IMAGE_EXTENSION, hasMedia); menu.setGroupVisible(MENU_GROUP_IMAGE_EXTENSION, hasMedia); - MenuUtils.setMenuItemChecked(menu, MENU_TOGGLE_SENSITIVE, hasMedia && mIsPossiblySensitive); + MenuUtils.setMenuItemChecked(menu, R.id.toggle_sensitive, hasMedia && mIsPossiblySensitive); MenuUtils.setMenuItemChecked(menu, R.id.link_to_quoted_status, mPreferences.getBoolean(KEY_LINK_TO_QUOTED_TWEET)); ThemeUtils.resetCheatSheet(mMenuBar); // mMenuBar.show(); } + private boolean isScheduleSupported() { + for (ParcelableCredentials account : mAccountsAdapter.getSelectedAccounts()) { + if (TwitterContentUtils.getOfficialKeyType(this, account.consumer_key, account.consumer_secret) + != ConsumerKeyType.TWEETDECK) { + return false; + } + } + return true; + } + private void setProgressVisible(final boolean visible) { mSetProgressVisibleRunnable = new SetProgressVisibleRunnable(this, visible); if (mFragmentResumed) { @@ -1233,18 +1248,6 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL return; } final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false); -// if (mRecentLocation == null && attachLocation) { -// final Location location; -// if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { -// location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); -// } else { -// location = null; -// } -// if (location != null) { -// mRecentLocation = new ParcelableLocation(location); -// } -// setRecentLocation(); -// } final long[] accountIds = mAccountsAdapter.getSelectedAccountIds(); final boolean isQuote = isQuote(); final ParcelableLocation statusLocation = attachLocation ? mRecentLocation : null; @@ -1323,7 +1326,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL private final LongSparseArray mSelection; private final boolean mNameFirst; - private ParcelableAccount[] mAccounts; + private ParcelableCredentials[] mAccounts; public AccountIconsAdapter(ComposeActivity activity) { setHasStableIds(true); @@ -1367,16 +1370,16 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL } @NonNull - public ParcelableAccount[] getSelectedAccounts() { - if (mAccounts == null) return new ParcelableAccount[0]; - final ParcelableAccount[] temp = new ParcelableAccount[mAccounts.length]; + public ParcelableCredentials[] getSelectedAccounts() { + if (mAccounts == null) return new ParcelableCredentials[0]; + final ParcelableCredentials[] temp = new ParcelableCredentials[mAccounts.length]; int selectedCount = 0; - for (ParcelableAccount account : mAccounts) { + for (ParcelableCredentials account : mAccounts) { if (mSelection.get(account.account_id, false)) { temp[selectedCount++] = account; } } - final ParcelableAccount[] result = new ParcelableAccount[selectedCount]; + final ParcelableCredentials[] result = new ParcelableCredentials[selectedCount]; System.arraycopy(temp, 0, result, 0, result.length); return result; } @@ -1403,7 +1406,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL return mAccounts != null ? mAccounts.length : 0; } - public void setAccounts(ParcelableAccount[] accounts) { + public void setAccounts(ParcelableCredentials[] accounts) { mAccounts = accounts; notifyDataSetChanged(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java index 014b95fd6..10709cda6 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java @@ -27,9 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; import android.database.ContentObserver; -import android.graphics.Canvas; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.net.Uri; @@ -41,9 +39,11 @@ import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.NotificationCompat; +import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; +import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ThemedAppCompatDelegateFactory; import android.support.v7.widget.Toolbar; import android.view.Gravity; @@ -60,10 +60,6 @@ import android.widget.FrameLayout; import android.widget.FrameLayout.LayoutParams; import android.widget.Toast; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnClosedListener; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenedListener; import com.meizu.flyme.reflect.StatusBarProxy; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; @@ -107,8 +103,6 @@ import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat; import org.mariotaku.twidere.util.support.ViewSupport; import org.mariotaku.twidere.util.support.view.ViewOutlineProviderCompat; import org.mariotaku.twidere.view.ExtendedViewPager; -import org.mariotaku.twidere.view.HomeSlidingMenu; -import org.mariotaku.twidere.view.LeftDrawerFrameLayout; import org.mariotaku.twidere.view.TabPagerIndicator; import org.mariotaku.twidere.view.TintedStatusFrameLayout; import org.mariotaku.twidere.view.iface.IHomeActionButton; @@ -132,7 +126,7 @@ import static org.mariotaku.twidere.util.Utils.openSearch; import static org.mariotaku.twidere.util.Utils.showMenuItemToast; public class HomeActivity extends BaseAppCompatActivity implements OnClickListener, OnPageChangeListener, - SupportFragmentCallback, OnOpenedListener, OnClosedListener, OnLongClickListener { + SupportFragmentCallback, OnLongClickListener { private final Handler mHandler = new Handler(); @@ -153,11 +147,11 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen private ExtendedViewPager mViewPager; private TabPagerIndicator mTabIndicator; - private HomeSlidingMenu mSlidingMenu; + private DrawerLayout mDrawerLayout; private View mEmptyTabHint; private View mActionsButton; private View mActionBarWithOverlay; - private LeftDrawerFrameLayout mLeftDrawerContainer; + private FrameLayout mLeftDrawerContainer; private TintedStatusFrameLayout mColorStatusFrameLayout; private UpdateUnreadCountTask mUpdateUnreadCountTask; @@ -175,8 +169,8 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen private View mActionBarContainer; public void closeAccountsDrawer() { - if (mSlidingMenu == null) return; - mSlidingMenu.showContent(); +// if (mSlidingMenu == null) return; +// mSlidingMenu.showContent(); } public long[] getActivatedAccountIds() { @@ -206,10 +200,14 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen return getSupportFragmentManager().findFragmentById(R.id.left_drawer); } + public boolean getDefaultSystemWindowsInsets(Rect insets) { + return super.getSystemWindowsInsets(insets); + } + @Override public boolean getSystemWindowsInsets(Rect insets) { final int height = mTabIndicator != null ? mTabIndicator.getHeight() : 0; - insets.top = height != 0 ? height : ThemeUtils.getActionBarHeight(this); + insets.top = (height != 0 ? height : ThemeUtils.getActionBarHeight(this)); return true; } @@ -221,24 +219,24 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_HOME: { + case android.R.id.home: { final FragmentManager fm = getSupportFragmentManager(); final int count = fm.getBackStackEntryCount(); - if (mSlidingMenu.isMenuShowing()) { - mSlidingMenu.showContent(); - return true; - } else if (count == 0) { - mSlidingMenu.showMenu(); - return true; - } +// if (mSlidingMenu.isMenuShowing()) { +// mSlidingMenu.showContent(); +// return true; +// } else if (count == 0) { +// mSlidingMenu.showMenu(); +// return true; +// } return true; } - case MENU_SEARCH: { + case R.id.search: { openSearchView(mSelectedAccountToSearch); return true; } - case MENU_ACTIONS: { + case R.id.actions: { triggerActionsClick(); return true; } @@ -253,12 +251,12 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen if (action != null) { switch (action) { case ACTION_HOME_ACCOUNTS_DASHBOARD: { - if (mSlidingMenu.isMenuShowing()) { - mSlidingMenu.showContent(true); - } else { - mSlidingMenu.showMenu(true); - setControlBarVisibleAnimate(true); - } +// if (mSlidingMenu.isMenuShowing()) { +// mSlidingMenu.showContent(true); +// } else { +// mSlidingMenu.showMenu(true); +// setControlBarVisibleAnimate(true); +// } return true; } } @@ -267,33 +265,33 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen if (action != null) { switch (action) { case ACTION_NAVIGATION_PREVIOUS_TAB: { - final int previous = mViewPager.getCurrentItem() - 1; - final int mode = mSlidingMenu.getMode(); - if (previous < 0 && (mode == SlidingMenu.LEFT || mode == SlidingMenu.LEFT_RIGHT)) { - mSlidingMenu.showMenu(true); - setControlBarVisibleAnimate(true); - } else if (previous < mPagerAdapter.getCount()) { - if (mSlidingMenu.isSecondaryMenuShowing()) { - mSlidingMenu.showContent(true); - } else { - mViewPager.setCurrentItem(previous, true); - } - } +// final int previous = mViewPager.getCurrentItem() - 1; +// final int mode = mSlidingMenu.getMode(); +// if (previous < 0 && (mode == SlidingMenu.LEFT || mode == SlidingMenu.LEFT_RIGHT)) { +// mSlidingMenu.showMenu(true); +// setControlBarVisibleAnimate(true); +// } else if (previous < mPagerAdapter.getCount()) { +// if (mSlidingMenu.isSecondaryMenuShowing()) { +// mSlidingMenu.showContent(true); +// } else { +// mViewPager.setCurrentItem(previous, true); +// } +// } return true; } case ACTION_NAVIGATION_NEXT_TAB: { - final int next = mViewPager.getCurrentItem() + 1; - final int mode = mSlidingMenu.getMode(); - if (next >= mPagerAdapter.getCount() && (mode == SlidingMenu.RIGHT || mode == SlidingMenu.LEFT_RIGHT)) { - mSlidingMenu.showSecondaryMenu(true); - setControlBarVisibleAnimate(true); - } else if (next >= 0) { - if (mSlidingMenu.isMenuShowing()) { - mSlidingMenu.showContent(true); - } else { - mViewPager.setCurrentItem(next, true); - } - } +// final int next = mViewPager.getCurrentItem() + 1; +// final int mode = mSlidingMenu.getMode(); +// if (next >= mPagerAdapter.getCount() && (mode == SlidingMenu.RIGHT || mode == SlidingMenu.LEFT_RIGHT)) { +// mSlidingMenu.showSecondaryMenu(true); +// setControlBarVisibleAnimate(true); +// } else if (next >= 0) { +// if (mSlidingMenu.isMenuShowing()) { +// mSlidingMenu.showContent(true); +// } else { +// mViewPager.setCurrentItem(next, true); +// } +// } return true; } } @@ -405,10 +403,10 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen // Steal MENU key event switch (keyCode) { case KeyEvent.KEYCODE_MENU: { - if (mSlidingMenu != null) { - mSlidingMenu.toggle(true); - return true; - } +// if (mSlidingMenu != null) { +// mSlidingMenu.toggle(true); +// return true; +// } break; } } @@ -524,11 +522,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen } } - @Override - public void onClosed() { - updateDrawerPercentOpen(0, true); - } - @Override public boolean onLongClick(final View v) { switch (v.getId()) { @@ -540,19 +533,15 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen return false; } - @Override - public void onOpened() { - updateDrawerPercentOpen(1, true); - } - @Override public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { } @Override public void onPageSelected(final int position) { - if (mSlidingMenu.isMenuShowing()) { - mSlidingMenu.showContent(); + //TODO handle secondary drawer + if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { + mDrawerLayout.closeDrawers(); } updateSlidingMenuTouchMode(); updateActionsButton(); @@ -566,11 +555,11 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen @Override public void onWindowFocusChanged(final boolean hasFocus) { super.onWindowFocusChanged(hasFocus); - if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) { - updateDrawerPercentOpen(1, false); - } else { - updateDrawerPercentOpen(0, false); - } +// if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) { +// updateDrawerPercentOpen(1, false); +// } else { +// updateDrawerPercentOpen(0, false); +// } } @Override @@ -584,10 +573,12 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen onSearchRequested(); } - public void setSystemWindowInsets(Rect insets) { + @Override + public void onFitSystemWindows(Rect insets) { + super.onFitSystemWindows(insets); final Fragment fragment = getLeftDrawerFragment(); if (fragment instanceof AccountsDashboardFragment) { - ((AccountsDashboardFragment) fragment).setStatusBarHeight(insets.top); + ((AccountsDashboardFragment) fragment).requestFitSystemWindows(); } mColorStatusFrameLayout.setStatusBarHeight(insets.top); } @@ -633,8 +624,9 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen @Override public void onBackPressed() { - if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) { - mSlidingMenu.showContent(); + //TODO handle secondary drawer + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) { + mDrawerLayout.closeDrawers(); return; } super.onBackPressed(); @@ -662,7 +654,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen mActionBar = (Toolbar) findViewById(R.id.action_bar); mActionBarContainer = findViewById(R.id.twidere_action_bar_container); mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs); - mSlidingMenu = (HomeSlidingMenu) findViewById(R.id.home_menu); + mDrawerLayout = (DrawerLayout) findViewById(R.id.home_menu); mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager); mEmptyTabHint = findViewById(R.id.empty_tab_hint); mActionsButton = findViewById(R.id.actions_button); @@ -672,9 +664,9 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen } private Fragment getKeyboardShortcutRecipient() { - if (mSlidingMenu.isMenuShowing()) { + if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { return getLeftDrawerFragment(); - } else if (mSlidingMenu.isSecondaryMenuShowing()) { + } else if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) { return null; } else { return getCurrentVisibleFragment(); @@ -774,8 +766,8 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen } private void openAccountsDrawer() { - if (mSlidingMenu == null) return; - mSlidingMenu.showMenu(); + if (mDrawerLayout == null) return; + mDrawerLayout.openDrawer(GravityCompat.START); } private boolean openSettingsWizard() { @@ -844,35 +836,35 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen } private void setupSlidingMenu() { - if (mSlidingMenu == null) return; - final Resources res = getResources(); - final int marginThreshold = res.getDimensionPixelSize(R.dimen.default_sliding_menu_margin_threshold); - final boolean relativeBehindWidth = res.getBoolean(R.bool.relative_behind_width); - mSlidingMenu.setMode(SlidingMenu.LEFT); - mSlidingMenu.setShadowWidthRes(R.dimen.default_sliding_menu_shadow_width); - mSlidingMenu.setShadowDrawable(R.drawable.shadow_left); - mSlidingMenu.setSecondaryShadowDrawable(R.drawable.shadow_right); - if (relativeBehindWidth) { - mSlidingMenu.setBehindOffsetRes(R.dimen.drawer_offset_home); - } else { - mSlidingMenu.setBehindWidthRes(R.dimen.drawer_width_home); - } - mSlidingMenu.setTouchmodeMarginThreshold(marginThreshold); - mSlidingMenu.setFadeDegree(0.5f); - mSlidingMenu.setMenu(R.layout.drawer_home_accounts); - mSlidingMenu.setOnOpenedListener(this); - mSlidingMenu.setOnClosedListener(this); - mLeftDrawerContainer = (LeftDrawerFrameLayout) mSlidingMenu.getMenu().findViewById(R.id.left_drawer_container); - final boolean isTransparentBackground = ThemeUtils.isTransparentBackground(getCurrentThemeBackgroundOption()); - mLeftDrawerContainer.setClipEnabled(isTransparentBackground); - mLeftDrawerContainer.setScrollScale(mSlidingMenu.getBehindScrollScale()); - mSlidingMenu.setBehindCanvasTransformer(new ListenerCanvasTransformer(this)); - final Window window = getWindow(); - ThemeUtils.applyWindowBackground(this, mSlidingMenu.getContent(), getCurrentThemeResourceId(), - getThemeBackgroundOption(), getCurrentThemeBackgroundAlpha()); - window.setBackgroundDrawable(new EmptyDrawable()); - - mSlidingMenu.addIgnoredView(mActionBarContainer); +// if (mSlidingMenu == null) return; +// final Resources res = getResources(); +// final int marginThreshold = res.getDimensionPixelSize(R.dimen.default_sliding_menu_margin_threshold); +// final boolean relativeBehindWidth = res.getBoolean(R.bool.relative_behind_width); +// mSlidingMenu.setMode(SlidingMenu.LEFT); +// mSlidingMenu.setShadowWidthRes(R.dimen.default_sliding_menu_shadow_width); + mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow_left, GravityCompat.START); +// mSlidingMenu.setSecondaryShadowDrawable(R.drawable.shadow_right); +// if (relativeBehindWidth) { +// mSlidingMenu.setBehindOffsetRes(R.dimen.drawer_offset_home); +// } else { +// mSlidingMenu.setBehindWidthRes(R.dimen.drawer_width_home); +// } +// mSlidingMenu.setTouchmodeMarginThreshold(marginThreshold); +// mSlidingMenu.setFadeDegree(0.5f); +// mSlidingMenu.setMenu(R.layout.drawer_home_accounts); +// mSlidingMenu.setOnOpenedListener(this); +// mSlidingMenu.setOnClosedListener(this); +// mLeftDrawerContainer = (LeftDrawerFrameLayout) mSlidingMenu.getMenu().findViewById(R.id.left_drawer_container); +// final boolean isTransparentBackground = ThemeUtils.isTransparentBackground(getCurrentThemeBackgroundOption()); +// mLeftDrawerContainer.setClipEnabled(isTransparentBackground); +// mLeftDrawerContainer.setScrollScale(mSlidingMenu.getBehindScrollScale()); +// mSlidingMenu.setBehindCanvasTransformer(new ListenerCanvasTransformer(this)); +// final Window window = getWindow(); +// ThemeUtils.applyWindowBackground(this, mSlidingMenu.getContent(), getCurrentThemeResourceId(), +// getThemeBackgroundOption(), getCurrentThemeBackgroundAlpha()); +// window.setBackgroundDrawable(new EmptyDrawable()); +// +// mSlidingMenu.addIgnoredView(mActionBarContainer); } private void showDataProfilingRequest() { @@ -943,19 +935,14 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen mActionsButton.setLayoutParams(lp); } - private void updateDrawerPercentOpen(final float percentOpen, final boolean horizontalScroll) { - if (mLeftDrawerContainer == null) return; - mLeftDrawerContainer.setPercentOpen(percentOpen); - } - private void updateSlidingMenuTouchMode() { - if (mViewPager == null || mSlidingMenu == null) return; - final int position = mViewPager.getCurrentItem(); - final boolean pagingEnabled = mViewPager.isEnabled(); - final boolean atFirstOrLast = position == 0 || position == mPagerAdapter.getCount() - 1; - final int mode = !pagingEnabled || atFirstOrLast ? SlidingMenu.TOUCHMODE_FULLSCREEN - : SlidingMenu.TOUCHMODE_MARGIN; - mSlidingMenu.setTouchModeAbove(mode); +// if (mViewPager == null || mSlidingMenu == null) return; +// final int position = mViewPager.getCurrentItem(); +// final boolean pagingEnabled = mViewPager.isEnabled(); +// final boolean atFirstOrLast = position == 0 || position == mPagerAdapter.getCount() - 1; +// final int mode = !pagingEnabled || atFirstOrLast ? SlidingMenu.TOUCHMODE_FULLSCREEN +// : SlidingMenu.TOUCHMODE_MARGIN; +// mSlidingMenu.setTouchModeAbove(mode); } private static final class AccountChangeObserver extends ContentObserver { @@ -978,20 +965,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen } } - private static class ListenerCanvasTransformer implements CanvasTransformer { - private final HomeActivity mHomeActivity; - - public ListenerCanvasTransformer(final HomeActivity homeActivity) { - mHomeActivity = homeActivity; - } - - @Override - public void transformCanvas(final Canvas canvas, final float percentOpen) { - mHomeActivity.updateDrawerPercentOpen(percentOpen, true); - } - - } - private static class UpdateUnreadCountTask extends AsyncTask> { private final Context mContext; private final ReadStateManager mReadStateManager; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java index a301d7590..810760214 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java @@ -153,7 +153,7 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_HOME: { + case android.R.id.home: { if (mFinishOnly) { finish(); } else { @@ -521,6 +521,10 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System setTitle(R.string.edit_profile); break; } + case LINK_ID_SCHEDULED_STATUSES: { + setTitle(getString(R.string.scheduled_statuses)); + break; + } default: { setTitle(getString(R.string.app_name)); break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java index 53951de97..526cd0741 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/MediaViewerActivity.java @@ -426,11 +426,11 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements if (callback.first.isDetached() || callback.first.getActivity() == null) return; final Menu menu = callback.second; final boolean hasImage = result.first; - MenuUtils.setMenuItemAvailability(menu, MENU_REFRESH, !hasImage && !isLoading); - MenuUtils.setMenuItemAvailability(menu, MENU_SHARE, hasImage && !isLoading); - MenuUtils.setMenuItemAvailability(menu, MENU_SAVE, hasImage && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !hasImage && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.share, hasImage && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.save, hasImage && !isLoading); if (!hasImage) return; - final MenuItem shareItem = menu.findItem(MENU_SHARE); + final MenuItem shareItem = menu.findItem(R.id.share); shareItem.setIntent(Intent.createChooser(result.second, callback.first.getString(R.string.share))); } }; @@ -449,15 +449,15 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case MENU_OPEN_IN_BROWSER: { + case R.id.open_in_browser: { openInBrowser(); return true; } - case MENU_SAVE: { + case R.id.save: { saveToGallery(); return true; } - case MENU_REFRESH: { + case R.id.refresh: { loadImage(); return true; } @@ -885,11 +885,11 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements final Pair linkAndType = mVideoUrlAndType; final boolean isLoading = linkAndType != null && mVideoLoader.isLoading(linkAndType.first); final boolean hasVideo = file != null && file.exists() && linkAndType != null; - MenuUtils.setMenuItemAvailability(menu, MENU_REFRESH, !hasVideo && !isLoading); - MenuUtils.setMenuItemAvailability(menu, MENU_SHARE, hasVideo && !isLoading); - MenuUtils.setMenuItemAvailability(menu, MENU_SAVE, hasVideo && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !hasVideo && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.share, hasVideo && !isLoading); + MenuUtils.setMenuItemAvailability(menu, R.id.save, hasVideo && !isLoading); if (!hasVideo) return; - final MenuItem shareItem = menu.findItem(MENU_SHARE); + final MenuItem shareItem = menu.findItem(R.id.share); final Intent intent = new Intent(Intent.ACTION_SEND); final Uri fileUri = Uri.fromFile(file); intent.setDataAndType(fileUri, linkAndType.second); @@ -913,11 +913,11 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case MENU_SAVE: { + case R.id.save: { saveToGallery(); return true; } - case MENU_REFRESH: { + case R.id.refresh: { loadVideo(); return true; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/SignInActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/SignInActivity.java index fe797758a..324bfd26c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/SignInActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/SignInActivity.java @@ -62,6 +62,7 @@ import com.meizu.flyme.reflect.StatusBarProxy; import org.mariotaku.restfu.http.Authorization; import org.mariotaku.restfu.http.Endpoint; +import org.mariotaku.sqliteqb.library.Expression; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.SettingsActivity; import org.mariotaku.twidere.api.twitter.Twitter; @@ -78,9 +79,9 @@ import org.mariotaku.twidere.fragment.support.SupportProgressDialogFragment; import org.mariotaku.twidere.graphic.EmptyDrawable; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; +import org.mariotaku.twidere.util.AbsLogger; import org.mariotaku.twidere.util.AsyncTaskUtils; import org.mariotaku.twidere.util.ContentValuesCreator; -import org.mariotaku.twidere.util.ErrorLogger; import org.mariotaku.twidere.util.OAuthPasswordAuthenticator; import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticationException; import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticityTokenException; @@ -219,21 +220,21 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_HOME: { + case android.R.id.home: { final long[] account_ids = getActivatedAccountIds(this); if (account_ids.length > 0) { onBackPressed(); } break; } - case MENU_SETTINGS: { + case R.id.settings: { if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return false; final Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); break; } - case MENU_EDIT_API: { + case R.id.edit_api: { if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return false; setDefaultAPI(); @@ -247,7 +248,7 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList startActivityForResult(intent, REQUEST_EDIT_API); break; } - case MENU_OPEN_IN_BROWSER: { + case R.id.open_in_browser: { if (mAuthType != ParcelableCredentials.AUTH_TYPE_OAUTH || mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return false; saveEditedText(); @@ -263,7 +264,7 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList @Override public boolean onPrepareOptionsMenu(final Menu menu) { - final MenuItem itemBrowser = menu.findItem(MENU_OPEN_IN_BROWSER); + final MenuItem itemBrowser = menu.findItem(R.id.open_in_browser); if (itemBrowser != null) { final boolean is_oauth = mAuthType == ParcelableCredentials.AUTH_TYPE_OAUTH; itemBrowser.setVisible(is_oauth); @@ -440,18 +441,26 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList ((DialogFragment) f).dismiss(); } if (result != null) { - if (result.succeed) { - insertAccount(result); + if (result.alreadyLoggedIn) { + final ContentValues values = result.toContentValues(); + if (values != null) { + mResolver.update(Accounts.CONTENT_URI, values, Expression.equals(Accounts.ACCOUNT_ID, + result.user.getId()).getSQL(), null); + } + Toast.makeText(this, R.string.error_already_logged_in, Toast.LENGTH_SHORT).show(); + } else if (result.succeed) { + final ContentValues values = result.toContentValues(); + if (values != null) { + mResolver.insert(Accounts.CONTENT_URI, values); + } final long loggedId = result.user.getId(); final Intent intent = new Intent(this, HomeActivity.class); intent.putExtra(EXTRA_REFRESH_IDS, new long[]{loggedId}); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent); finish(); - } else if (result.alreadyLoggedIn) { - Toast.makeText(this, R.string.error_already_logged_in, Toast.LENGTH_SHORT).show(); } else { - ErrorLogger.exception(result.exception); + AbsLogger.error(result.exception); if (result.exception instanceof AuthenticityTokenException) { Toast.makeText(this, R.string.wrong_api_key, Toast.LENGTH_SHORT).show(); } else if (result.exception instanceof WrongUserPassException) { @@ -466,35 +475,6 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList setSignInButton(); } - private void insertAccount(final SignInResponse result) { - final ContentValues values; - switch (result.authType) { - case ParcelableCredentials.AUTH_TYPE_BASIC: { - values = createAccount(result.basicUsername, result.basicPassword, - result.user, result.color, result.apiUrlFormat, result.noVersionSuffix); - break; - } - case ParcelableCredentials.AUTH_TYPE_TWIP_O_MODE: { - values = ContentValuesCreator.createAccount(result.user, result.color, - result.apiUrlFormat, result.noVersionSuffix); - break; - } - case ParcelableCredentials.AUTH_TYPE_OAUTH: - case ParcelableCredentials.AUTH_TYPE_XAUTH: { - values = ContentValuesCreator.createAccount(result.oauth, - result.user, result.authType, result.color, result.apiUrlFormat, - result.sameOauthSigningUrl, result.noVersionSuffix); - break; - } - default: { - values = null; - } - } - if (values != null) { - mResolver.insert(Accounts.CONTENT_URI, values); - } - } - void onSignInStart() { mHandler.post(new Runnable() { @Override @@ -609,13 +589,14 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList protected SignInResponse doInBackground(final Object... params) { try { final String versionSuffix = noVersionSuffix ? null : "1.1"; - final Endpoint endpoint = new Endpoint(TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", versionSuffix)); + Endpoint endpoint = new OAuthEndpoint(TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", null)); final TwitterOAuth oauth = TwitterAPIFactory.getInstance(context, endpoint, new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret()), TwitterOAuth.class); final OAuthToken accessToken = oauth.getAccessToken(requestToken, oauthVerifier); final long userId = accessToken.getUserId(); if (userId <= 0) return new SignInResponse(false, false, null); final OAuthAuthorization auth = new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret(), accessToken); + endpoint = new OAuthEndpoint(TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", versionSuffix)); final Twitter twitter = TwitterAPIFactory.getInstance(context, endpoint, auth, Twitter.class); final User user = twitter.verifyCredentials(); @@ -707,28 +688,14 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList } private SignInResponse authOAuth() throws AuthenticationException, TwitterException { - String endpointUrl, signEndpointUrl; - endpointUrl = TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", null); - if (!sameOAuthSigningUrl) { - signEndpointUrl = TwitterAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, "api", null); - } else { - signEndpointUrl = endpointUrl; - } - Endpoint endpoint = new OAuthEndpoint(endpointUrl, signEndpointUrl); + Endpoint endpoint = TwitterAPIFactory.getOAuthEndpoint(apiUrlFormat, sameOAuthSigningUrl); OAuthAuthorization auth = new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret()); final TwitterOAuth oauth = TwitterAPIFactory.getInstance(context, endpoint, auth, TwitterOAuth.class); final OAuthPasswordAuthenticator authenticator = new OAuthPasswordAuthenticator(oauth); final OAuthToken accessToken = authenticator.getOAuthAccessToken(username, password); final long userId = accessToken.getUserId(); if (userId <= 0) return new SignInResponse(false, false, null); - final String versionSuffix = noVersionSuffix ? null : "1.1"; - endpointUrl = TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", versionSuffix); - if (!sameOAuthSigningUrl) { - signEndpointUrl = TwitterAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, "api", versionSuffix); - } else { - signEndpointUrl = endpointUrl; - } - endpoint = new OAuthEndpoint(endpointUrl, signEndpointUrl); + endpoint = TwitterAPIFactory.getRestEndpoint(apiUrlFormat, sameOAuthSigningUrl, noVersionSuffix); auth = new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret(), accessToken); final Twitter twitter = TwitterAPIFactory.getInstance(context, endpoint, auth, Twitter.class); @@ -751,20 +718,14 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList } private SignInResponse authxAuth() throws TwitterException { - String endpointUrl, signEndpointUrl; - endpointUrl = TwitterAPIFactory.getApiUrl(apiUrlFormat, "api", null); - if (!sameOAuthSigningUrl) { - signEndpointUrl = TwitterAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, "api", null); - } else { - signEndpointUrl = endpointUrl; - } - Endpoint endpoint = new OAuthEndpoint(endpointUrl, signEndpointUrl); + Endpoint endpoint = TwitterAPIFactory.getOAuthEndpoint(apiUrlFormat, sameOAuthSigningUrl); OAuthAuthorization auth = new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret()); final TwitterOAuth oauth = TwitterAPIFactory.getInstance(context, endpoint, auth, TwitterOAuth.class); final OAuthToken accessToken = oauth.getAccessToken(username, password, TwitterOAuth.XAuthMode.CLIENT); final long userId = accessToken.getUserId(); if (userId <= 0) return new SignInResponse(false, false, null); auth = new OAuthAuthorization(consumerKey.getOauthToken(), consumerKey.getOauthTokenSecret(), accessToken); + endpoint = TwitterAPIFactory.getRestEndpoint(apiUrlFormat, sameOAuthSigningUrl, noVersionSuffix); final Twitter twitter = TwitterAPIFactory.getInstance(context, endpoint, auth, Twitter.class); final User user = twitter.verifyCredentials(); final int color = analyseUserProfileColor(user); @@ -827,6 +788,31 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList this(alreadyLoggedIn, true, null, null, null, null, user, ParcelableCredentials.AUTH_TYPE_TWIP_O_MODE, color, apiUrlFormat, false, noVersionSuffix); } + + private ContentValues toContentValues() { + final ContentValues values; + switch (authType) { + case ParcelableCredentials.AUTH_TYPE_BASIC: { + values = createAccount(basicUsername, basicPassword, user, color, apiUrlFormat, + noVersionSuffix); + break; + } + case ParcelableCredentials.AUTH_TYPE_TWIP_O_MODE: { + values = ContentValuesCreator.createAccount(user, color, apiUrlFormat, noVersionSuffix); + break; + } + case ParcelableCredentials.AUTH_TYPE_OAUTH: + case ParcelableCredentials.AUTH_TYPE_XAUTH: { + values = ContentValuesCreator.createAccount(oauth, user, authType, color, apiUrlFormat, + sameOauthSigningUrl, noVersionSuffix); + break; + } + default: { + values = null; + } + } + return values; + } } public static class SetConsumerKeySecretDialogFragment extends BaseSupportDialogFragment { 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 8ef24468c..d78a6cd54 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java @@ -25,7 +25,6 @@ import android.support.annotation.NonNull; import android.support.v4.app.FragmentActivity; import android.support.v4.util.Pair; import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.View; @@ -59,7 +58,7 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener; /** * Created by mariotaku on 15/1/3. */ -public abstract class AbsActivitiesAdapter extends Adapter implements Constants, +public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter implements Constants, IActivitiesAdapter, StatusClickListener, OnLinkClickListener { private static final int ITEM_VIEW_TYPE_STUB = 0; @@ -83,8 +82,6 @@ public abstract class AbsActivitiesAdapter extends Adapter imp private final TwidereLinkify mLinkify; private final DummyStatusHolderAdapter mStatusAdapterDelegate; private final UserColorNameManager mUserColorNameManager; - private boolean mLoadMoreSupported; - private boolean mLoadMoreIndicatorVisible; private ActivityAdapterListener mActivityAdapterListener; protected AbsActivitiesAdapter(final Context context, boolean compact) { @@ -121,11 +118,13 @@ public abstract class AbsActivitiesAdapter extends Adapter imp @Override public abstract void setData(Data data); + @NonNull @Override public MediaLoaderWrapper getMediaLoader() { return mImageLoader; } + @NonNull @Override public Context getContext() { return mContext; @@ -157,32 +156,6 @@ public abstract class AbsActivitiesAdapter extends Adapter imp return mTextSize; } - @Override - public boolean isLoadMoreIndicatorVisible() { - return mLoadMoreIndicatorVisible; - } - - @Override - public boolean isLoadMoreSupported() { - return mLoadMoreSupported; - } - - @Override - public void setLoadMoreSupported(boolean supported) { - mLoadMoreSupported = supported; - if (!supported) { - mLoadMoreIndicatorVisible = false; - } - notifyDataSetChanged(); - } - - @Override - public void setLoadMoreIndicatorVisible(boolean enabled) { - if (mLoadMoreIndicatorVisible == enabled) return; - mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported; - notifyDataSetChanged(); - } - public int getLinkHighlightingStyle() { return mLinkHighlightingStyle; } @@ -343,7 +316,7 @@ public abstract class AbsActivitiesAdapter extends Adapter imp @Override public final int getItemCount() { - return getActivityCount() + (mLoadMoreIndicatorVisible ? 1 : 0); + return getActivityCount() + (isLoadMoreIndicatorVisible() ? 1 : 0); } @Override @@ -368,6 +341,7 @@ public abstract class AbsActivitiesAdapter extends Adapter imp } + @NonNull @Override public UserColorNameManager getUserColorNameManager() { return mUserColorNameManager; diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java index c353e172d..fc1caccfb 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java @@ -102,11 +102,13 @@ public abstract class AbsStatusesAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter extends LoadMoreSupportAdapter implements Constants, +public class MessageEntriesAdapter extends LoadMoreSupportAdapter implements Constants, IContentCardAdapter, OnClickListener, OnReadStateChangeListener { public static final int ITEM_VIEW_TYPE_MESSAGE = 0; @@ -67,8 +67,6 @@ public class MessageEntriesAdapter extends Adapter implements Consta private final AsyncTwitterWrapper mTwitterWrapper; private final boolean mDisplayProfileImage; - private boolean mLoadMoreSupported; - private boolean mLoadMoreIndicatorVisible; private boolean mShowAccountsColor; private Cursor mCursor; private MessageEntriesAdapterListener mListener; @@ -98,6 +96,7 @@ public class MessageEntriesAdapter extends Adapter implements Consta }; } + @NonNull @Override public Context getContext() { return mContext; @@ -130,42 +129,18 @@ public class MessageEntriesAdapter extends Adapter implements Consta return new DirectMessageEntry(c); } + @NonNull @Override public MediaLoaderWrapper getMediaLoader() { return mImageLoader; } + @NonNull @Override public UserColorNameManager getUserColorNameManager() { return mUserColorNameManager; } - @Override - public boolean isLoadMoreIndicatorVisible() { - return mLoadMoreIndicatorVisible; - } - - @Override - public void setLoadMoreIndicatorVisible(boolean enabled) { - if (mLoadMoreIndicatorVisible == enabled) return; - mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported; - notifyDataSetChanged(); - } - - @Override - public boolean isLoadMoreSupported() { - return mLoadMoreSupported; - } - - @Override - public void setLoadMoreSupported(boolean supported) { - mLoadMoreSupported = supported; - if (!supported) { - mLoadMoreIndicatorVisible = false; - } - notifyDataSetChanged(); - } - @Override public void onClick(final View view) { // if (mMultiSelectManager.isActive()) return; @@ -222,7 +197,7 @@ public class MessageEntriesAdapter extends Adapter implements Consta @Override public final int getItemCount() { - return getMessagesCount() + (mLoadMoreIndicatorVisible ? 1 : 0); + return getMessagesCount() + (isLoadMoreIndicatorVisible() ? 1 : 0); } public void onMessageClick(int position) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java index 3c1e25bab..690785bfc 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java @@ -19,6 +19,8 @@ package org.mariotaku.twidere.adapter.iface; +import android.support.annotation.NonNull; + import org.mariotaku.twidere.model.ParcelableActivity; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoadingHandler; @@ -38,6 +40,7 @@ public interface IActivitiesAdapter extends IContentCardAdapter, IGapSuppo @PreviewStyle int getMediaPreviewStyle(); + @NonNull @Override MediaLoaderWrapper getMediaLoader(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IContentCardAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IContentCardAdapter.java index b76498e27..dd0807825 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IContentCardAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IContentCardAdapter.java @@ -31,8 +31,11 @@ import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle; * Created by mariotaku on 15/1/3. */ public interface IContentCardAdapter extends ILoadMoreSupportAdapter { + + @NonNull Context getContext(); + @NonNull UserColorNameManager getUserColorNameManager(); int getItemCount(); @@ -47,5 +50,6 @@ public interface IContentCardAdapter extends ILoadMoreSupportAdapter { @NonNull AsyncTwitterWrapper getTwitterWrapper(); + @NonNull MediaLoaderWrapper getMediaLoader(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUserListsAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUserListsAdapter.java index 4683e3a95..ae78b43bf 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUserListsAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUserListsAdapter.java @@ -19,6 +19,8 @@ package org.mariotaku.twidere.adapter.iface; +import android.support.annotation.NonNull; + import org.mariotaku.twidere.model.ParcelableUserList; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.view.holder.UserListViewHolder.UserListClickListener; @@ -40,6 +42,7 @@ public interface IUserListsAdapter extends IContentCardAdapter, UserListCl boolean isNameFirst(); + @NonNull @Override MediaLoaderWrapper getMediaLoader(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUsersAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUsersAdapter.java index d9ca6cce7..a1c762b22 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUsersAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IUsersAdapter.java @@ -19,6 +19,8 @@ package org.mariotaku.twidere.adapter.iface; +import android.support.annotation.NonNull; + import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.view.holder.UserViewHolder.UserClickListener; @@ -38,6 +40,7 @@ public interface IUsersAdapter extends IContentCardAdapter, UserClickListe boolean shouldShowAccountsColor(); + @NonNull @Override MediaLoaderWrapper getMediaLoader(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java index 09c369235..efb499425 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java +++ b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java @@ -44,7 +44,6 @@ import com.nostra13.universalimageloader.utils.L; import com.squareup.okhttp.internal.Network; import com.squareup.otto.Bus; -import org.acra.ACRA; import org.acra.annotation.ReportsCrashes; import org.acra.sender.HttpSender; import org.mariotaku.twidere.BuildConfig; @@ -53,15 +52,16 @@ import org.mariotaku.twidere.activity.AssistLauncherActivity; import org.mariotaku.twidere.activity.MainActivity; import org.mariotaku.twidere.activity.MainHondaJOJOActivity; import org.mariotaku.twidere.service.RefreshService; +import org.mariotaku.twidere.util.AbsLogger; import org.mariotaku.twidere.util.AsyncTaskManager; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.DebugModeUtils; -import org.mariotaku.twidere.util.ErrorLogger; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MultiSelectManager; import org.mariotaku.twidere.util.ReadStateManager; import org.mariotaku.twidere.util.StrictModeUtils; +import org.mariotaku.twidere.util.TwidereLogger; import org.mariotaku.twidere.util.UserAgentUtils; import org.mariotaku.twidere.util.UserColorNameManager; import org.mariotaku.twidere.util.Utils; @@ -271,8 +271,8 @@ public class TwidereApplication extends MultiDexApplication implements Constants } private void initBugReport() { - ACRA.init(this); - ErrorLogger.setEnabled(BuildConfig.DEBUG); + AbsLogger.setImplementation(new TwidereLogger()); + AbsLogger.init(this); } private void migrateUsageStatisticsPreferences() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java index 43856c4bd..3ca10fdaf 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java @@ -83,7 +83,7 @@ public abstract class BaseAccountPreferenceFragment extends PreferenceFragment i final String switchKey = getSwitchPreferenceKey(); if (!TextUtils.isEmpty(switchKey)) { inflater.inflate(R.menu.menu_switch_preference, menu); - final View actionView = menu.findItem(MENU_TOGGLE).getActionView(); + final View actionView = menu.findItem(R.id.toggle).getActionView(); final CompoundButton toggle = (CompoundButton) actionView.findViewById(android.R.id.toggle); final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); toggle.setOnCheckedChangeListener(this); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java index 8d72fb042..c08de5549 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java @@ -159,12 +159,12 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment extends BaseSupportFragment +public abstract class AbsContentRecyclerViewFragment extends BaseSupportFragment implements OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, ControlBarOffsetListener, ContentListSupport { @@ -222,7 +223,7 @@ public abstract class AbsContentRecyclerViewFragment extends AbsContentRecyclerViewFr public boolean onMenuItemClick(MenuItem item) { final ParcelableStatus status = mSelectedStatus; if (status == null) return false; - if (item.getItemId() == MENU_SHARE) { + if (item.getItemId() == R.id.share) { final Intent shareIntent = Utils.createStatusShareIntent(getActivity(), status); startActivity(Intent.createChooser(shareIntent, getString(R.string.share_status))); return true; 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 82f1861e4..45aedcc8f 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 @@ -141,6 +141,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo private AccountToggleProvider mAccountActionProvider; private boolean mSwitchAccountAnimationPlaying; + private final Rect mSystemWindowsInsets = new Rect(); public long[] getActivatedAccountIds() { if (mAccountActionProvider != null) { @@ -242,7 +243,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo @Override public void onLoadFinished(final Loader loader, final Cursor data) { final Menu menu = mAccountsToggleMenu.getMenu(); - mAccountActionProvider = (AccountToggleProvider) MenuItemCompat.getActionProvider(menu.findItem(MENU_SELECT_ACCOUNT)); + mAccountActionProvider = (AccountToggleProvider) MenuItemCompat.getActionProvider(menu.findItem(R.id.select_account)); final ParcelableAccount[] accounts = ParcelableAccount.getAccounts(data); if (accounts.length > 0) { mNoAccountContainer.setVisibility(View.GONE); @@ -285,29 +286,29 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo if (account == null || !(item instanceof OptionItem)) return; final OptionItem option = (OptionItem) item; switch (option.id) { - case MENU_SEARCH: { + case R.id.search: { final Intent intent = new Intent(getActivity(), QuickSearchBarActivity.class); intent.putExtra(EXTRA_ACCOUNT_ID, account.account_id); startActivity(intent); closeAccountsDrawer(); break; } - case MENU_COMPOSE: { + case R.id.compose: { final Intent composeIntent = new Intent(INTENT_ACTION_COMPOSE); composeIntent.setClass(getActivity(), ComposeActivity.class); composeIntent.putExtra(EXTRA_ACCOUNT_IDS, new long[]{account.account_id}); startActivity(composeIntent); break; } - case MENU_FAVORITES: { + case R.id.favorites: { openUserFavorites(getActivity(), account.account_id, account.account_id, account.screen_name); break; } - case MENU_LISTS: { + case R.id.lists: { openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name); break; } - case MENU_EDIT: { + case R.id.edit: { Utils.openProfileEditor(getActivity(), account.account_id); break; } @@ -316,19 +317,19 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo if (!(item instanceof OptionItem)) return; final OptionItem option = (OptionItem) item; switch (option.id) { - case MENU_ACCOUNTS: { + case R.id.accounts: { Utils.openAccountsManager(getActivity()); break; } - case MENU_DRAFTS: { + case R.id.drafts: { Utils.openDrafts(getActivity()); break; } - case MENU_FILTERS: { + case R.id.filters: { Utils.openFilters(getActivity()); break; } - case MENU_SETTINGS: { + case R.id.settings: { final Intent intent = new Intent(getActivity(), SettingsActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivityForResult(intent, REQUEST_SETTINGS); @@ -372,7 +373,17 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo @Override protected void fitSystemWindows(Rect insets) { - // No-op + mSystemWindowsInsets.set(insets); + updateSystemWindowsInsets(); + } + + private void updateSystemWindowsInsets() { + if (mAccountProfileContainer == null) return; + final HomeActivity activity = (HomeActivity) getActivity(); + final Rect insets = mSystemWindowsInsets; + if (!activity.getDefaultSystemWindowsInsets(insets)) return; + final int top = Utils.getInsetsTopWithoutActionBarHeight(getActivity(), insets.top); + mAccountProfileContainer.setPadding(0, top, 0, 0); } @Override @@ -436,6 +447,8 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo mPreferences.registerOnSharedPreferenceChangeListener(this); getLoaderManager().initLoader(0, null, this); + + updateSystemWindowsInsets(); } @Override @@ -466,12 +479,12 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo void initAccountActionsAdapter(ParcelableAccount[] accounts) { mAccountOptionsAdapter.clear(); - mAccountOptionsAdapter.add(new OptionItem(android.R.string.search_go, R.drawable.ic_action_search, MENU_SEARCH)); + mAccountOptionsAdapter.add(new OptionItem(android.R.string.search_go, R.drawable.ic_action_search, R.id.search)); if (accounts.length > 1) { - mAccountOptionsAdapter.add(new OptionItem(R.string.compose, R.drawable.ic_action_status_compose, MENU_COMPOSE)); + mAccountOptionsAdapter.add(new OptionItem(R.string.compose, R.drawable.ic_action_status_compose, R.id.compose)); } - mAccountOptionsAdapter.add(new OptionItem(R.string.favorites, R.drawable.ic_action_star, MENU_FAVORITES)); - mAccountOptionsAdapter.add(new OptionItem(R.string.lists, R.drawable.ic_action_list, MENU_LISTS)); + mAccountOptionsAdapter.add(new OptionItem(R.string.favorites, R.drawable.ic_action_star, R.id.favorites)); + mAccountOptionsAdapter.add(new OptionItem(R.string.lists, R.drawable.ic_action_list, R.id.lists)); } private void closeAccountsDrawer() { @@ -644,7 +657,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo @Override protected String getTitle(int position, OptionItem option) { final ParcelableAccount account = mSelectedAccount; - if (account != null && option.id == MENU_COMPOSE) { + if (account != null && option.id == R.id.compose) { final Context context = getContext(); final String displayName = mUserColorNameManager.getDisplayName(-1, account.name, account.screen_name, mNameFirst, false); @@ -802,10 +815,10 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo public AppMenuAdapter(final Context context) { super(context); - add(new OptionItem(R.string.accounts, R.drawable.ic_action_accounts, MENU_ACCOUNTS)); - add(new OptionItem(R.string.drafts, R.drawable.ic_action_draft, MENU_DRAFTS)); - add(new OptionItem(R.string.filters, R.drawable.ic_action_speaker_muted, MENU_FILTERS)); - add(new OptionItem(R.string.settings, R.drawable.ic_action_settings, MENU_SETTINGS)); + add(new OptionItem(R.string.accounts, R.drawable.ic_action_accounts, R.id.accounts)); + add(new OptionItem(R.string.drafts, R.drawable.ic_action_draft, R.id.drafts)); + add(new OptionItem(R.string.filters, R.drawable.ic_action_speaker_muted, R.id.filters)); + add(new OptionItem(R.string.settings, R.drawable.ic_action_settings, R.id.settings)); } } 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 12271e4a3..c61de87ce 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 @@ -78,7 +78,7 @@ public class AccountsManagerFragment extends BaseSupportFragment implements Load @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case MENU_ADD_ACCOUNT: { + case R.id.add_account: { final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN); intent.setClass(getActivity(), SignInActivity.class); startActivity(intent); @@ -118,14 +118,14 @@ public class AccountsManagerFragment extends BaseSupportFragment implements Load mSelectedAccount = mAdapter.getAccount(info.position); if (mSelectedAccount == null) return false; switch (item.getItemId()) { - case MENU_SET_COLOR: { + case R.id.set_color: { final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); intent.putExtra(EXTRA_COLOR, mSelectedAccount.color); intent.putExtra(EXTRA_ALPHA_SLIDER, false); startActivityForResult(intent, REQUEST_SET_COLOR); break; } - case MENU_DELETE: { + case R.id.delete: { final AccountDeletionDialogFragment f = new AccountDeletionDialogFragment(); final Bundle args = new Bundle(); args.putLong(EXTRA_ACCOUNT_ID, mSelectedAccount.account_id); 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 50767438b..330482bf8 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 @@ -288,7 +288,7 @@ public class DirectMessagesFragment extends AbsContentRecyclerViewFragment mTrendsCallback = new LoaderCallbacks() { - - @Override - public Loader onCreateLoader(final int id, final Bundle args) { - final Uri uri = CachedTrends.Local.CONTENT_URI; - final String table = getTableNameByUri(uri); - final SQLSelectQuery selectQuery = SQLQueryBuilder.select(new Columns(CachedTrends.TIMESTAMP)) - .from(new Table(table)) - .orderBy(new OrderBy(CachedTrends.TIMESTAMP, false)) - .limit(1) - .build(); - final Expression where = Expression.equals(CachedTrends.TIMESTAMP, selectQuery); - return new CursorLoader(getActivity(), uri, CachedTrends.COLUMNS, where.getSQL(), null, null); - } - - @Override - public void onLoaderReset(final Loader loader) { - mTrendsAdapter.swapCursor(null); - } - - @Override - public void onLoadFinished(final Loader loader, final Cursor data) { - mTrendsAdapter.swapCursor(data); - } - - }; - - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mQuickMenuContainer.setOnFitSystemWindowsListener(this); - mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - if (mPreferences.getBoolean(KEY_QUICK_MENU_EXPANDED, false)) { - } else { - } - final Context context = getThemedContext(); - mAdapter = new MergeAdapter(); - mTrendsAdapter = new TrendsAdapter(context); - - mAdapter.addView(Utils.newSectionView(context, R.string.trends), false); - mAdapter.addAdapter(mTrendsAdapter); - mListView.setAdapter(mAdapter); - mListView.setOnItemClickListener(this); - getLoaderManager().initLoader(LOADER_ID_TRENDS, null, mTrendsCallback); - } - - @Override - public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { - return LayoutInflater.from(getThemedContext()); - } - - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_quick_menu, container, false); - } - - @Override - public void onDestroy() { - super.onDestroy(); - final SharedPreferences.Editor editor = mPreferences.edit(); - editor.putBoolean(KEY_QUICK_MENU_EXPANDED, mSlidingUpPanel.getPanelState() == PanelState.EXPANDED); - editor.apply(); - } - - @Override - public void onBaseViewCreated(final View view, final Bundle savedInstanceState) { - super.onBaseViewCreated(view, savedInstanceState); - mQuickMenuContainer = (ExtendedFrameLayout) view.findViewById(R.id.quick_menu_fragment); - mListView = (ListView) view.findViewById(android.R.id.list); - mSlidingUpPanel = (SlidingUpPanelLayout) view.findViewById(R.id.activities_drawer); - mActivitiesConfigButton = (ImageButton) view.findViewById(R.id.activities_config_button); - final View activitiesContainer = view.findViewById(R.id.activities_container); - } - - @Override - public void onFitSystemWindows(Rect insets) { - mQuickMenuContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom); - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - final ListAdapter adapter = mAdapter.getAdapter(position); - if (adapter instanceof TrendsAdapter) { - openTweetSearch(getActivity(), getAccountId(), (String) mAdapter.getItem(position)); - } - } - - private long getAccountId() { - return -1; - } - - @Override - public Context getThemedContext() { - if (mThemedContext != null) return mThemedContext; - final Context context = getActivity(); - final int currentThemeResource = ThemeUtils.getNoActionBarThemeResource(context); - final int themeResource = ThemeUtils.getDrawerThemeResource(currentThemeResource); - return mThemedContext = new ContextThemeWrapper(context, themeResource); - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ScheduledStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ScheduledStatusesFragment.java new file mode 100644 index 000000000..d0cdfaf55 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ScheduledStatusesFragment.java @@ -0,0 +1,156 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.fragment.support; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.Loader; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.adapter.LoadMoreSupportAdapter; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatus; +import org.mariotaku.twidere.loader.support.ScheduledStatusesLoader; +import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; + +import java.util.List; + +/** + * Created by mariotaku on 15/7/10. + */ +public class ScheduledStatusesFragment extends AbsContentRecyclerViewFragment + implements LoaderManager.LoaderCallbacks> { + + @Override + public boolean isRefreshing() { + return getLoaderManager().hasRunningLoaders(); + } + + @NonNull + @Override + protected ScheduledStatusesAdapter onCreateAdapter(Context context, boolean compact) { + return new ScheduledStatusesAdapter(getActivity()); + } + + @Override + public Loader> onCreateLoader(int id, Bundle args) { + final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1); + final long sinceId = args.getLong(EXTRA_SINCE_ID, -1); + final long maxId = args.getLong(EXTRA_MAX_ID, -1); + final ScheduledStatus.State[] states = {ScheduledStatus.State.SCHEDULED, ScheduledStatus.State.FAILED}; + return new ScheduledStatusesLoader(getActivity(), accountId, sinceId, maxId, states, null); + } + + @Override + public void onLoadFinished(Loader> loader, List data) { + getAdapter().setData(data); + showContent(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + final Bundle args = getArguments(); + final Bundle loaderArgs = new Bundle(); + loaderArgs.putLong(EXTRA_ACCOUNT_ID, args.getLong(EXTRA_ACCOUNT_ID)); + getLoaderManager().initLoader(0, loaderArgs, this); + showProgress(); + } + + @Override + public void onLoaderReset(Loader> loader) { + getAdapter().setData(null); + } + + public static class ScheduledStatusesAdapter extends LoadMoreSupportAdapter { + public static final int ITEM_VIEW_TYPE_SCHEDULED_STATUS = 2; + + private final Context mContext; + private final LayoutInflater mInflater; + private List mData; + + public ScheduledStatusesAdapter(Context context) { + mContext = context; + mInflater = LayoutInflater.from(context); + setLoadMoreSupported(false); + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case ITEM_VIEW_TYPE_SCHEDULED_STATUS: { + return new ScheduledStatusViewHolder(mInflater.inflate(R.layout.list_item_scheduled_status, parent, false)); + } + case ITEM_VIEW_TYPE_LOAD_INDICATOR: { + return new LoadIndicatorViewHolder(mInflater.inflate(R.layout.card_item_load_indicator, parent, false)); + } + } + throw new UnsupportedOperationException(); + } + + @Override + public int getItemViewType(int position) { + return ITEM_VIEW_TYPE_SCHEDULED_STATUS; + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + switch (holder.getItemViewType()) { + case ITEM_VIEW_TYPE_SCHEDULED_STATUS: { + ((ScheduledStatusViewHolder) holder).displayScheduledStatus(mData.get(position)); + break; + } + } + } + + @Override + public int getItemCount() { + if (mData == null) return 0; + return mData.size(); + } + + public void setData(List data) { + mData = data; + notifyDataSetChanged(); + } + } + + private static final class ScheduledStatusViewHolder extends RecyclerView.ViewHolder { + + private final TextView textView; + + public ScheduledStatusViewHolder(View itemView) { + super(itemView); + textView = (TextView) itemView.findViewById(R.id.text); + } + + public void displayScheduledStatus(ScheduledStatus status) { + textView.setText(status.getText()); + } + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java index 8efcdb0a3..f874f9e48 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java @@ -211,14 +211,14 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll @Override public void onPrepareOptionsMenu(Menu menu) { - final MenuItem item = menu.findItem(MENU_COMPOSE); + final MenuItem item = menu.findItem(R.id.compose); item.setTitle(getString(R.string.tweet_hashtag, getQuery())); } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case MENU_SAVE: { + case R.id.save: { final AsyncTwitterWrapper twitter = getTwitterWrapper(); final Bundle args = getArguments(); if (twitter != null && args != null) { @@ -226,7 +226,7 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll } return true; } - case MENU_COMPOSE: { + case R.id.compose: { final Intent intent = new Intent(getActivity(), ComposeActivity.class); intent.setAction(INTENT_ACTION_COMPOSE); intent.putExtra(Intent.EXTRA_TEXT, String.format("#%s ", getQuery())); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java index 331c9bd85..722b3d9c0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java @@ -905,7 +905,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper(); final FragmentActivity activity = fragment.getActivity(); final FragmentManager fm = fragment.getFragmentManager(); - if (item.getItemId() == MENU_RETWEET) { + if (item.getItemId() == R.id.retweet) { RetweetQuoteDialogFragment.show(fm, status); return true; } @@ -1146,6 +1146,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac return RecyclerView.NO_POSITION; } + @NonNull @Override public Context getContext() { return mContext; @@ -1172,6 +1173,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac return mDisplayProfileImage; } + @NonNull @Override public MediaLoaderWrapper getMediaLoader() { return mImageLoader; @@ -1256,6 +1258,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac return mMediaLoadingHandler; } + @NonNull @Override public UserColorNameManager getUserColorNameManager() { return mUserColorNameManager; 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 179f6ecaa..c4d8a03c1 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 @@ -106,6 +106,7 @@ import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; import org.mariotaku.twidere.graphic.ActionBarColorDrawable; import org.mariotaku.twidere.graphic.ActionIconDrawable; import org.mariotaku.twidere.loader.support.ParcelableUserLoader; +import org.mariotaku.twidere.model.ConsumerKeyType; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableUser; @@ -840,15 +841,18 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final ParcelableUser user = getUser(); final Relationship relationship = mRelationship; if (twitter == null || user == null) return; + final boolean isMyself = user.account_id == user.id; - final MenuItem mentionItem = menu.findItem(MENU_MENTION); + final MenuItem mentionItem = menu.findItem(R.id.mention); if (mentionItem != null) { final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true); mentionItem.setTitle(getString(R.string.mention_user_name, displayName)); } - MenuUtils.setMenuItemAvailability(menu, MENU_MENTION, !isMyself); + MenuUtils.setMenuItemAvailability(menu, R.id.mention, !isMyself); MenuUtils.setMenuItemAvailability(menu, R.id.incoming_friendships, isMyself); MenuUtils.setMenuItemAvailability(menu, R.id.saved_searches, isMyself); + MenuUtils.setMenuItemAvailability(menu, R.id.scheduled_statuses, isMyself + && Utils.getOfficialKeyType(getActivity(), user.account_id) == ConsumerKeyType.TWEETDECK); // final MenuItem followItem = menu.findItem(MENU_FOLLOW); // followItem.setVisible(!isMyself); // final boolean shouldShowFollowItem = !creatingFriendship && !destroyingFriendship && !isMyself @@ -863,38 +867,38 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener // followItem.setIcon(null); // } if (!isMyself && relationship != null) { - MenuUtils.setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, relationship.canSourceDMTarget()); - MenuUtils.setMenuItemAvailability(menu, MENU_BLOCK, true); - MenuUtils.setMenuItemAvailability(menu, MENU_MUTE_USER, true); - final MenuItem blockItem = menu.findItem(MENU_BLOCK); + MenuUtils.setMenuItemAvailability(menu, R.id.send_direct_message, relationship.canSourceDMTarget()); + MenuUtils.setMenuItemAvailability(menu, R.id.block, true); + MenuUtils.setMenuItemAvailability(menu, R.id.mute_user, true); + final MenuItem blockItem = menu.findItem(R.id.block); if (blockItem != null) { final boolean blocking = relationship.isSourceBlockingTarget(); ActionIconDrawable.setMenuHighlight(blockItem, new TwidereMenuInfo(blocking)); blockItem.setTitle(blocking ? R.string.unblock : R.string.block); } - final MenuItem muteItem = menu.findItem(MENU_MUTE_USER); + final MenuItem muteItem = menu.findItem(R.id.mute_user); if (muteItem != null) { final boolean muting = relationship.isSourceMutingTarget(); ActionIconDrawable.setMenuHighlight(muteItem, new TwidereMenuInfo(muting)); muteItem.setTitle(muting ? R.string.unmute : R.string.mute); } - final MenuItem filterItem = menu.findItem(MENU_ADD_TO_FILTER); + final MenuItem filterItem = menu.findItem(R.id.add_to_filter); if (filterItem != null) { final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); ActionIconDrawable.setMenuHighlight(filterItem, new TwidereMenuInfo(filtering)); filterItem.setTitle(filtering ? R.string.remove_from_filter : R.string.add_to_filter); } - final MenuItem wantRetweetsItem = menu.findItem(MENU_ENABLE_RETWEETS); + final MenuItem wantRetweetsItem = menu.findItem(R.id.enable_retweets); if (wantRetweetsItem != null) { wantRetweetsItem.setChecked(relationship.isSourceWantRetweetsFromTarget()); } } else { - MenuUtils.setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, false); - MenuUtils.setMenuItemAvailability(menu, MENU_ENABLE_RETWEETS, false); - MenuUtils.setMenuItemAvailability(menu, MENU_BLOCK, false); - MenuUtils.setMenuItemAvailability(menu, MENU_MUTE_USER, false); - MenuUtils.setMenuItemAvailability(menu, MENU_REPORT_SPAM, false); + MenuUtils.setMenuItemAvailability(menu, R.id.send_direct_message, false); + MenuUtils.setMenuItemAvailability(menu, R.id.enable_retweets, false); + MenuUtils.setMenuItemAvailability(menu, R.id.block, false); + MenuUtils.setMenuItemAvailability(menu, R.id.mute_user, false); + MenuUtils.setMenuItemAvailability(menu, R.id.report_spam, false); } MenuUtils.setMenuItemAvailability(menu, R.id.muted_users, isMyself); MenuUtils.setMenuItemAvailability(menu, R.id.blocked_users, isMyself); @@ -920,7 +924,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final Relationship relationship = mRelationship; if (user == null || twitter == null) return false; switch (item.getItemId()) { - case MENU_BLOCK: { + case R.id.block: { if (mRelationship != null) { if (mRelationship.isSourceBlockingTarget()) { twitter.destroyBlockAsync(user.account_id, user.id); @@ -930,11 +934,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } break; } - case MENU_REPORT_SPAM: { + case R.id.report_spam: { ReportSpamDialogFragment.show(getFragmentManager(), user); break; } - case MENU_ADD_TO_FILTER: { + case R.id.add_to_filter: { final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); final ContentResolver cr = getContentResolver(); if (filtering) { @@ -947,7 +951,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } break; } - case MENU_MUTE_USER: { + case R.id.mute_user: { if (mRelationship != null) { if (mRelationship.isSourceMutingTarget()) { twitter.destroyMuteAsync(user.account_id, user.id); @@ -957,7 +961,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } break; } - case MENU_MENTION: { + case R.id.mention: { final Intent intent = new Intent(INTENT_ACTION_MENTION); final Bundle bundle = new Bundle(); bundle.putParcelable(EXTRA_USER, user); @@ -965,7 +969,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener startActivity(intent); break; } - case MENU_SEND_DIRECT_MESSAGE: { + case R.id.send_direct_message: { final Uri.Builder builder = new Uri.Builder(); builder.scheme(SCHEME_TWIDERE); builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION); @@ -977,7 +981,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener startActivity(intent); break; } - case MENU_SET_COLOR: { + case R.id.set_color: { final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); intent.putExtra(EXTRA_COLOR, mUserColorNameManager.getUserColor(user.id, true)); intent.putExtra(EXTRA_ALPHA_SLIDER, false); @@ -985,17 +989,17 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener startActivityForResult(intent, REQUEST_SET_COLOR); break; } - case MENU_CLEAR_NICKNAME: { + case R.id.clear_nickname: { final UserColorNameManager manager = UserColorNameManager.getInstance(getActivity()); manager.clearUserNickname(user.id); break; } - case MENU_SET_NICKNAME: { + case R.id.set_nickname: { final String nick = mUserColorNameManager.getUserNickname(user.id, true); SetUserNicknameDialogFragment.show(getFragmentManager(), user.id, nick); break; } - case MENU_ADD_TO_LIST: { + case R.id.add_to_list: { final Intent intent = new Intent(INTENT_ACTION_SELECT_USER_LIST); intent.setClass(getActivity(), UserListSelectorActivity.class); intent.putExtra(EXTRA_ACCOUNT_ID, user.account_id); @@ -1003,14 +1007,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener startActivityForResult(intent, REQUEST_ADD_TO_LIST); break; } - case MENU_OPEN_WITH_ACCOUNT: { + case R.id.open_with_account: { final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT); intent.setClass(getActivity(), AccountSelectorActivity.class); intent.putExtra(EXTRA_SINGLE_SELECTION, true); startActivityForResult(intent, REQUEST_SELECT_ACCOUNT); break; } - case MENU_FOLLOW: { + case R.id.follow: { if (relationship == null) return false; final boolean isFollowing = relationship.isSourceFollowingTarget(); final boolean isCreatingFriendship = twitter.isCreatingFriendship(user.account_id, user.id); @@ -1024,7 +1028,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } return true; } - case MENU_ENABLE_RETWEETS: { + case R.id.enable_retweets: { final boolean newState = !item.isChecked(); final FriendshipUpdate update = new FriendshipUpdate(); update.retweets(newState); @@ -1052,6 +1056,10 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener Utils.openSavedSearches(getActivity(), user.account_id); return true; } + case R.id.scheduled_statuses: { + Utils.openScheduledStatuses(getActivity(), user.account_id); + return true; + } default: { if (item.getIntent() != null) { try { 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 ef1c27b60..1c92a0d45 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 @@ -277,16 +277,16 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList @Override public void onPrepareOptionsMenu(Menu menu) { final ParcelableUserList userList = mUserList; - setMenuItemAvailability(menu, MENU_INFO, userList != null); + setMenuItemAvailability(menu, R.id.info, userList != null); menu.removeGroup(MENU_GROUP_USER_LIST_EXTENSION); if (userList != null) { final boolean isMyList = userList.user_id == userList.account_id; final boolean isFollowing = userList.is_following; - setMenuItemAvailability(menu, MENU_EDIT, isMyList); - setMenuItemAvailability(menu, MENU_FOLLOW, !isMyList); - setMenuItemAvailability(menu, MENU_ADD, isMyList); - setMenuItemAvailability(menu, MENU_DELETE, isMyList); - final MenuItem followItem = menu.findItem(MENU_FOLLOW); + setMenuItemAvailability(menu, R.id.edit, isMyList); + setMenuItemAvailability(menu, R.id.follow, !isMyList); + setMenuItemAvailability(menu, R.id.add, isMyList); + setMenuItemAvailability(menu, R.id.delete, isMyList); + final MenuItem followItem = menu.findItem(R.id.follow); if (isFollowing) { followItem.setIcon(R.drawable.ic_action_cancel); followItem.setTitle(R.string.unsubscribe); @@ -299,10 +299,10 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList extensionsIntent.putExtra(EXTRA_USER_LIST, userList); addIntentToMenu(getActivity(), menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION); } else { - setMenuItemAvailability(menu, MENU_EDIT, false); - setMenuItemAvailability(menu, MENU_FOLLOW, false); - setMenuItemAvailability(menu, MENU_ADD, false); - setMenuItemAvailability(menu, MENU_DELETE, false); + setMenuItemAvailability(menu, R.id.edit, false); + setMenuItemAvailability(menu, R.id.follow, false); + setMenuItemAvailability(menu, R.id.add, false); + setMenuItemAvailability(menu, R.id.delete, false); } } @@ -312,7 +312,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList final ParcelableUserList userList = mUserList; if (twitter == null || userList == null) return false; switch (item.getItemId()) { - case MENU_ADD: { + case R.id.add: { if (userList.user_id != userList.account_id) return false; final Intent intent = new Intent(INTENT_ACTION_SELECT_USER); intent.setClass(getActivity(), UserListSelectorActivity.class); @@ -320,12 +320,12 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList startActivityForResult(intent, REQUEST_SELECT_USER); break; } - case MENU_DELETE: { + case R.id.delete: { if (userList.user_id != userList.account_id) return false; DestroyUserListDialogFragment.show(getFragmentManager(), userList); break; } - case MENU_EDIT: { + case R.id.edit: { final Bundle args = new Bundle(); args.putLong(EXTRA_ACCOUNT_ID, userList.account_id); args.putString(EXTRA_LIST_NAME, userList.name); @@ -337,7 +337,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList f.show(getFragmentManager(), "edit_user_list_details"); return true; } - case MENU_FOLLOW: { + case R.id.follow: { if (userList.is_following) { DestroyUserListSubscriptionDialogFragment.show(getFragmentManager(), userList); } else { @@ -345,7 +345,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList } return true; } - case MENU_OPEN_WITH_ACCOUNT: { + case R.id.open_with_account: { final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT); intent.setClass(getActivity(), AccountSelectorActivity.class); intent.putExtra(EXTRA_SINGLE_SELECTION, true); 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 bab45485c..48d536007 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 @@ -193,7 +193,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case MENU_SAVE: { + case R.id.save: { final String name = ParseUtils.parseString(mEditName.getText()); final String url = ParseUtils.parseString(mEditUrl.getText()); final String location = ParseUtils.parseString(mEditLocation.getText()); 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 new file mode 100644 index 000000000..7c87558bd --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ScheduledStatusesLoader.java @@ -0,0 +1,73 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.loader.support; + +import android.content.Context; +import android.support.v4.content.AsyncTaskLoader; + +import org.mariotaku.twidere.api.twitter.Twitter; +import org.mariotaku.twidere.api.twitter.TwitterException; +import org.mariotaku.twidere.api.twitter.model.Paging; +import org.mariotaku.twidere.api.twitter.model.ScheduledStatus; +import org.mariotaku.twidere.util.TwitterAPIFactory; + +import java.util.List; + +/** + * Created by mariotaku on 15/7/10. + */ +public class ScheduledStatusesLoader extends AsyncTaskLoader> { + + private final long mAccountId; + private final long mSinceId; + private final long mMaxId; + private final ScheduledStatus.State[] mStates; + + public ScheduledStatusesLoader(Context context, long accountId, long sinceId, long maxId, ScheduledStatus.State[] states, List data) { + super(context); + mAccountId = accountId; + mSinceId = sinceId; + mMaxId = maxId; + mStates = states; + } + + + @Override + public List loadInBackground() { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true); + final Paging paging = new Paging(); + if (mSinceId > 0) { + paging.setSinceId(mSinceId); + } + if (mMaxId > 0) { + paging.setMaxId(mMaxId); + } + try { + return twitter.getScheduledStatusesList(paging, mStates); + } catch (TwitterException e) { + return null; + } + } + + @Override + protected void onStartLoading() { + forceLoad(); + } +} 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 3da812351..f69c0b0b2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java @@ -44,9 +44,9 @@ import android.widget.Toast; import com.nostra13.universalimageloader.utils.IoUtils; import com.twitter.Extractor; -import org.mariotaku.sqliteqb.library.Expression; import org.mariotaku.restfu.http.ContentType; import org.mariotaku.restfu.http.mime.FileTypedData; +import org.mariotaku.sqliteqb.library.Expression; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.MainActivity; @@ -216,6 +216,7 @@ public class BackgroundOperationService extends IntentService implements Constan private void handleSendDraftIntent(Intent intent) { final Uri uri = intent.getData(); if (uri == null) return; + mNotificationManager.cancel(uri.toString(), NOTIFICATION_ID_DRAFTS); final long draftId = ParseUtils.parseLong(uri.getLastPathSegment(), -1); if (draftId == -1) return; final Expression where = Expression.equals(Drafts._ID, draftId); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java b/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java index 4ede76e9f..64dca9106 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java @@ -103,7 +103,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, final List selectedItems = mMultiSelectManager.getSelectedItems(); if (selectedItems.isEmpty()) return false; switch (item.getItemId()) { - case MENU_REPLY: { + case R.id.reply: { final Extractor extractor = new Extractor(); final Intent intent = new Intent(INTENT_ACTION_REPLY_MULTIPLE); final Bundle bundle = new Bundle(); @@ -133,7 +133,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, mode.finish(); break; } - case MENU_MUTE_USER: { + case R.id.mute_user: { final ContentResolver resolver = mActivity.getContentResolver(); final ArrayList valuesList = new ArrayList<>(); final Set userIds = new HashSet<>(); @@ -155,7 +155,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, mActivity.sendBroadcast(new Intent(BROADCAST_MULTI_MUTESTATE_CHANGED)); break; } - case MENU_BLOCK: { + case R.id.block: { final long accountId = mMultiSelectManager.getAccountId(); final long[] userIds = MultiSelectManager.getSelectedUserIds(selectedItems); if (accountId > 0 && userIds != null) { @@ -164,7 +164,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, mode.finish(); break; } - case MENU_REPORT_SPAM: { + case R.id.report_spam: { final long accountId = mMultiSelectManager.getAccountId(); final long[] userIds = MultiSelectManager.getSelectedUserIds(selectedItems); if (accountId > 0 && userIds != null) { @@ -190,7 +190,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, @Override public boolean onCreateActionMode(final ActionMode mode, final Menu menu) { mode.getMenuInflater().inflate(R.menu.action_multi_select_contents, menu); - mAccountActionProvider = (AccountActionProvider) menu.findItem(MENU_SELECT_ACCOUNT).getActionProvider(); + mAccountActionProvider = (AccountActionProvider) menu.findItem(R.id.select_account).getActionProvider(); mAccountActionProvider.setSelectedAccountIds(mMultiSelectManager.getFirstSelectAccountId()); return true; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLogger.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLogger.java new file mode 100644 index 000000000..adf3d60c1 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLogger.java @@ -0,0 +1,76 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.util; + +import android.app.Application; +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import android.util.Log; + +import org.acra.ACRA; +import org.acra.ErrorReporter; +import org.mariotaku.twidere.BuildConfig; +import org.mariotaku.twidere.Constants; + +/** + * Created by mariotaku on 15/7/8. + */ +public class TwidereLogger extends AbsLogger implements Constants { + + @Override + protected void logImpl(@Nullable String message, @Nullable Throwable throwable) { + Log.d(LOGTAG, message, throwable); + } + + @Override + protected void errorImpl(@Nullable String message, @Nullable Throwable throwable) { + final ErrorReporter errorReporter = ACRA.getErrorReporter(); + if (throwable == null && message == null) { + throw new NullPointerException("Message and Throwable can't be both null"); + } + if (message != null) { + if (BuildConfig.DEBUG) { + Log.w(LOGTAG, message, throwable); + } + + handleSilentException(new Exception(message, throwable)); + return; + } + if (BuildConfig.DEBUG) { + Log.w(LOGTAG, throwable); + } + handleSilentException(throwable); + } + + private void handleSilentException(final Throwable throwable) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + ACRA.getErrorReporter().handleSilentException(throwable); + } + }); + } + + @Override + protected void initImpl(Application application) { + ACRA.init(application); + } + +} 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 e5e50ffe6..b0494fd2a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java @@ -307,6 +307,9 @@ public class TwitterAPIFactory implements TwidereConstants { case TWITTER_FOR_MAC: { return "Twitter-Mac"; } + case TWEETDECK: { + return "TweetDeck"; + } } return "Twitter"; } @@ -321,6 +324,29 @@ public class TwitterAPIFactory implements TwidereConstants { } } + public static Endpoint getOAuthEndpoint(String apiUrlFormat, boolean sameOAuthSigningUrl) { + String endpointUrl, signEndpointUrl; + endpointUrl = getApiUrl(apiUrlFormat, "api", null); + if (!sameOAuthSigningUrl) { + signEndpointUrl = getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, "api", null); + } else { + signEndpointUrl = endpointUrl; + } + return new OAuthEndpoint(endpointUrl, signEndpointUrl); + } + + public static Endpoint getRestEndpoint(String apiUrlFormat, boolean sameOAuthSigningUrl, boolean noVersionSuffix) { + final String versionSuffix = noVersionSuffix ? null : "1.1"; + String endpointUrl, signEndpointUrl; + endpointUrl = getApiUrl(apiUrlFormat, "api", versionSuffix); + if (!sameOAuthSigningUrl) { + signEndpointUrl = getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, "api", versionSuffix); + } else { + signEndpointUrl = endpointUrl; + } + return new OAuthEndpoint(endpointUrl, signEndpointUrl); + } + public static class TwidereRequestInfoFactory implements RequestInfoFactory { private static HashMap sExtraParams = new HashMap<>(); 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 2359f31b0..c53380329 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -120,6 +120,9 @@ import org.apache.http.protocol.HTTP; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.mariotaku.restfu.RestAPIFactory; +import org.mariotaku.restfu.RestClient; +import org.mariotaku.restfu.http.Authorization; import org.mariotaku.sqliteqb.library.AllColumns; import org.mariotaku.sqliteqb.library.Columns; import org.mariotaku.sqliteqb.library.Columns.Column; @@ -132,9 +135,6 @@ import org.mariotaku.sqliteqb.library.Selectable; import org.mariotaku.sqliteqb.library.Table; import org.mariotaku.sqliteqb.library.Tables; import org.mariotaku.sqliteqb.library.query.SQLSelectQuery; -import org.mariotaku.restfu.RestAPIFactory; -import org.mariotaku.restfu.RestClient; -import org.mariotaku.restfu.http.Authorization; import org.mariotaku.twidere.BuildConfig; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; @@ -162,6 +162,7 @@ import org.mariotaku.twidere.fragment.support.ListsFragment; import org.mariotaku.twidere.fragment.support.MessagesConversationFragment; import org.mariotaku.twidere.fragment.support.MutesUsersListFragment; import org.mariotaku.twidere.fragment.support.SavedSearchesListFragment; +import org.mariotaku.twidere.fragment.support.ScheduledStatusesFragment; import org.mariotaku.twidere.fragment.support.SearchFragment; import org.mariotaku.twidere.fragment.support.SensitiveContentWarningDialogFragment; import org.mariotaku.twidere.fragment.support.SetUserNicknameDialogFragment; @@ -190,6 +191,7 @@ import org.mariotaku.twidere.graphic.ActionIconDrawable; import org.mariotaku.twidere.graphic.PaddingDrawable; import org.mariotaku.twidere.menu.SupportStatusShareProvider; import org.mariotaku.twidere.model.AccountPreferences; +import org.mariotaku.twidere.model.ConsumerKeyType; import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableDirectMessage; @@ -388,6 +390,7 @@ public final class Utils implements Constants { LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_SEARCH, null, LINK_ID_SEARCH); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_MUTES_USERS, null, LINK_ID_MUTES_USERS); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_MAP, null, LINK_ID_MAP); + LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_SCHEDULED_STATUSES, null, LINK_ID_SCHEDULED_STATUSES); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_ACCOUNTS, null, LINK_ID_ACCOUNTS); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_DRAFTS, null, LINK_ID_DRAFTS); @@ -941,6 +944,10 @@ public final class Utils implements Constants { fragment = new MutesUsersListFragment(); break; } + case LINK_ID_SCHEDULED_STATUSES: { + fragment = new ScheduledStatusesFragment(); + break; + } case LINK_ID_DIRECT_MESSAGES_CONVERSATION: { fragment = new MessagesConversationFragment(); final String paramRecipientId = uri.getQueryParameter(QUERY_PARAM_RECIPIENT_ID); @@ -2546,18 +2553,23 @@ public final class Utils implements Constants { } public static boolean isOfficialKeyAccount(final Context context, final long accountId) { - if (context == null) return false; + return getOfficialKeyType(context, accountId) != ConsumerKeyType.UNKNOWN; + } + + @NonNull + public static ConsumerKeyType getOfficialKeyType(final Context context, final long accountId) { + if (context == null) return ConsumerKeyType.UNKNOWN; final String[] projection = {Accounts.CONSUMER_KEY, Accounts.CONSUMER_SECRET}; final String selection = Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(); final Cursor c = context.getContentResolver().query(Accounts.CONTENT_URI, projection, selection, null, null); //noinspection TryFinallyCanBeTryWithResources try { if (c.moveToPosition(0)) - return TwitterContentUtils.isOfficialKey(context, c.getString(0), c.getString(1)); + return TwitterContentUtils.getOfficialKeyType(context, c.getString(0), c.getString(1)); } finally { c.close(); } - return false; + return ConsumerKeyType.UNKNOWN; } public static boolean isOfficialTwitterInstance(final Context context, final Twitter twitter) { @@ -2761,12 +2773,22 @@ public final class Utils implements Constants { context.startActivity(Intent.createChooser(intent, null)); } - public static void openMutesUsers(final Activity activity, final long account_id) { + public static void openMutesUsers(final Activity activity, final long accountId) { if (activity == null) return; final Uri.Builder builder = new Uri.Builder(); builder.scheme(SCHEME_TWIDERE); builder.authority(AUTHORITY_MUTES_USERS); - builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(account_id)); + builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId)); + final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); + activity.startActivity(intent); + } + + public static void openScheduledStatuses(final Activity activity, final long accountId) { + if (activity == null) return; + final Uri.Builder builder = new Uri.Builder(); + builder.scheme(SCHEME_TWIDERE); + builder.authority(AUTHORITY_SCHEDULED_STATUSES); + builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId)); final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); activity.startActivity(intent); } @@ -3294,26 +3316,26 @@ public final class Utils implements Constants { final int retweetHighlight = resources.getColor(R.color.highlight_retweet); final int favoriteHighlight = resources.getColor(R.color.highlight_favorite); final boolean isMyRetweet = isMyRetweet(status); - final MenuItem delete = menu.findItem(MENU_DELETE); + final MenuItem delete = menu.findItem(R.id.delete); if (delete != null) { delete.setVisible(isMyStatus(status)); } - final MenuItem retweet = menu.findItem(MENU_RETWEET); + final MenuItem retweet = menu.findItem(R.id.retweet); if (retweet != null) { ActionIconDrawable.setMenuHighlight(retweet, new TwidereMenuInfo(isMyRetweet, retweetHighlight)); retweet.setTitle(isMyRetweet ? R.string.cancel_retweet : R.string.retweet); } - final MenuItem favorite = menu.findItem(MENU_FAVORITE); + final MenuItem favorite = menu.findItem(R.id.favorite); if (favorite != null) { ActionIconDrawable.setMenuHighlight(favorite, new TwidereMenuInfo(status.is_favorite, favoriteHighlight)); favorite.setTitle(status.is_favorite ? R.string.unfavorite : R.string.favorite); } - final MenuItem translate = menu.findItem(MENU_TRANSLATE); + final MenuItem translate = menu.findItem(R.id.translate); if (translate != null) { final boolean isOfficialKey = isOfficialCredentials(context, account); final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); final boolean forcePrivateApis = prefs.getBoolean(KEY_FORCE_USING_PRIVATE_APIS, false); - MenuUtils.setMenuItemAvailability(menu, MENU_TRANSLATE, forcePrivateApis || isOfficialKey); + MenuUtils.setMenuItemAvailability(menu, R.id.translate, forcePrivateApis || isOfficialKey); } menu.removeGroup(MENU_GROUP_STATUS_EXTENSION); addIntentToMenuForExtension(context, menu, MENU_GROUP_STATUS_EXTENSION, INTENT_ACTION_EXTENSION_OPEN_STATUS, @@ -3599,13 +3621,13 @@ public final class Utils implements Constants { public static boolean handleMenuItemClick(Context context, Fragment fragment, FragmentManager fm, AsyncTwitterWrapper twitter, ParcelableStatus status, MenuItem item) { final UserColorNameManager colorNameManager = UserColorNameManager.getInstance(context); switch (item.getItemId()) { - case MENU_COPY: { + case R.id.copy: { if (ClipboardUtils.setText(context, status.text_plain)) { showOkMessage(context, R.string.text_copied, false); } break; } - case MENU_RETWEET: { + case R.id.retweet: { if (isMyRetweet(status)) { twitter.cancelRetweetAsync(status.account_id, status.id, status.my_retweet_id); } else { @@ -3613,19 +3635,19 @@ public final class Utils implements Constants { } break; } - case MENU_QUOTE: { + case R.id.quote: { final Intent intent = new Intent(INTENT_ACTION_QUOTE); intent.putExtra(EXTRA_STATUS, status); context.startActivity(intent); break; } - case MENU_REPLY: { + case R.id.reply: { final Intent intent = new Intent(INTENT_ACTION_REPLY); intent.putExtra(EXTRA_STATUS, status); context.startActivity(intent); break; } - case MENU_FAVORITE: { + case R.id.favorite: { if (status.is_favorite) { twitter.destroyFavoriteAsync(status.account_id, status.id); } else { @@ -3633,15 +3655,15 @@ public final class Utils implements Constants { } break; } - case MENU_DELETE: { + case R.id.delete: { DestroyStatusDialogFragment.show(fm, status); break; } - case MENU_ADD_TO_FILTER: { + case R.id.add_to_filter: { AddStatusFilterDialogFragment.show(fm, status); break; } - case MENU_SET_COLOR: { + case R.id.set_color: { final Intent intent = new Intent(context, ColorPickerDialogActivity.class); final int color = colorNameManager.getUserColor(status.user_id, true); if (color != 0) { @@ -3656,16 +3678,16 @@ public final class Utils implements Constants { } break; } - case MENU_CLEAR_NICKNAME: { + case R.id.clear_nickname: { colorNameManager.clearUserNickname(status.user_id); break; } - case MENU_SET_NICKNAME: { + case R.id.set_nickname: { final String nick = colorNameManager.getUserNickname(status.user_id, true); SetUserNicknameDialogFragment.show(fm, status.user_id, nick); break; } - case MENU_TRANSLATE: { + case R.id.translate: { final ParcelableCredentials account = ParcelableAccount.getCredentials(context, status.account_id); if (isOfficialCredentials(context, account)) { @@ -3688,7 +3710,7 @@ public final class Utils implements Constants { } break; } - case MENU_OPEN_WITH_ACCOUNT: { + case R.id.open_with_account: { final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT); intent.setClass(context, AccountSelectorActivity.class); intent.putExtra(EXTRA_SINGLE_SELECTION, true); diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/AssetFontTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/AssetFontTextView.java deleted file mode 100644 index f98328760..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/AssetFontTextView.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.mariotaku.twidere.view; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Typeface; -import android.util.AttributeSet; -import android.widget.TextView; - -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.view.iface.ICustomTypefaceTextView; - -/** - * Created by mariotaku on 14/11/14. - */ -public class AssetFontTextView extends TextView implements ICustomTypefaceTextView { - public AssetFontTextView(Context context) { - this(context, null); - } - - public AssetFontTextView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public AssetFontTextView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AssetFontTextView, defStyleAttr, 0); - final String path = a.getString(R.styleable.AssetFontTextView_fontPath); - if (path != null && !isInEditMode()) { - setTypeface(Typeface.createFromAsset(context.getAssets(), path)); - } - a.recycle(); - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java index 6548c72e8..6839ac991 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java @@ -21,7 +21,6 @@ package org.mariotaku.twidere.view; import android.content.Context; import android.support.annotation.NonNull; -import android.support.v7.widget.AppCompatTextView; import android.text.Layout; import android.text.Spannable; import android.text.SpannableString; @@ -29,7 +28,9 @@ import android.text.style.ClickableSpan; import android.util.AttributeSet; import android.view.MotionEvent; -public class HandleSpanClickTextView extends AppCompatTextView { +import org.mariotaku.twidere.view.themed.ThemedTextView; + +public class HandleSpanClickTextView extends ThemedTextView { private boolean mLongClickPerformed; diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HomeSlidingMenu.java b/twidere/src/main/java/org/mariotaku/twidere/view/HomeSlidingMenu.java deleted file mode 100644 index 19e0894b2..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/HomeSlidingMenu.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.mariotaku.twidere.view; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Rect; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -import com.jeremyfeinstein.slidingmenu.lib.CustomViewBehind; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; - -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.activity.support.HomeActivity; - -/** - * Created by mariotaku on 14/10/21. - */ -public class HomeSlidingMenu extends SlidingMenu implements Constants { - - public HomeSlidingMenu(final Context context) { - this(context, null); - } - - public HomeSlidingMenu(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public HomeSlidingMenu(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public boolean dispatchTouchEvent(@NonNull final MotionEvent ev) { - switch (ev.getActionMasked()) { - case MotionEvent.ACTION_DOWN: { - final boolean isTouchingMargin = isTouchingMargin(ev); - setTouchModeAbove(isTouchingMargin ? TOUCHMODE_MARGIN : TOUCHMODE_FULLSCREEN); - break; - } - } - return super.dispatchTouchEvent(ev); - } - - @Override - protected boolean fitSystemWindows(Rect insets) { - if (isInEditMode()) return false; - final HomeActivity activity = (HomeActivity) getContext(); - activity.setSystemWindowInsets(insets); - return false; - } - - @Override - protected CustomViewBehind newCustomViewBehind(final Context context) { - if (isInEditMode()) return super.newCustomViewBehind(context); - return new MyCustomViewBehind(context, this); - } - - @Nullable - private ViewPager getViewPager() { - if (isInEditMode()) return null; - final HomeActivity activity = (HomeActivity) getContext(); - if (activity == null) return null; - return activity.getViewPager(); - } - - private boolean isTouchingMargin(final MotionEvent e) { - final float x = e.getX(), marginThreshold = getTouchmodeMarginThreshold(); - final View content = getContent(); - final int mode = getMode(), left = content.getLeft(), right = content.getRight(); - if (mode == SlidingMenu.LEFT) - return x >= left && x <= marginThreshold + left; - else if (mode == SlidingMenu.RIGHT) - return x <= right && x >= right - marginThreshold; - else if (mode == SlidingMenu.LEFT_RIGHT) - return x >= left && x <= marginThreshold + left || x <= right && x >= right - marginThreshold; - return false; - } - - @SuppressLint("ViewConstructor") - private static class MyCustomViewBehind extends CustomViewBehind { - - private final HomeSlidingMenu mSlidingMenu; - - public MyCustomViewBehind(final Context context, final HomeSlidingMenu slidingMenu) { - super(context); - mSlidingMenu = slidingMenu; - } - - @Override - public boolean menuClosedSlideAllowed(final float dx) { - if (mSlidingMenu.getTouchModeAbove() != SlidingMenu.TOUCHMODE_FULLSCREEN) - return super.menuClosedSlideAllowed(dx); - final ViewPager viewPager = mSlidingMenu.getViewPager(); - if (viewPager == null) return false; - final boolean canScrollHorizontally = viewPager.canScrollHorizontally(Math.round(-dx)); - final int mode = getMode(); - if (mode == SlidingMenu.LEFT) - return dx > 0 && !canScrollHorizontally; - else if (mode == SlidingMenu.RIGHT) - return dx < 0 && !canScrollHorizontally; - else if (mode == SlidingMenu.LEFT_RIGHT) return !canScrollHorizontally; - return false; - } - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/LeftDrawerFrameLayout.java b/twidere/src/main/java/org/mariotaku/twidere/view/LeftDrawerFrameLayout.java index 6dd2c8e7b..f0981b0a9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/LeftDrawerFrameLayout.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/LeftDrawerFrameLayout.java @@ -1,18 +1,18 @@ /* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * * 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 . */ @@ -20,11 +20,6 @@ package org.mariotaku.twidere.view; import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.support.annotation.NonNull; import android.util.AttributeSet; import android.widget.FrameLayout; @@ -32,10 +27,6 @@ import org.mariotaku.twidere.util.ThemeUtils; public class LeftDrawerFrameLayout extends FrameLayout { - private final Paint mClipPaint = new Paint(); - private float mScrollScale, mPercentOpen; - private boolean mClipEnabled; - public LeftDrawerFrameLayout(final Context context) { this(context, null); } @@ -47,41 +38,5 @@ public class LeftDrawerFrameLayout extends FrameLayout { public LeftDrawerFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); ThemeUtils.setupDrawerBackground(context, this); - setWillNotDraw(false); - mClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - } - - @Override - public boolean hasOverlappingRendering() { - return mClipEnabled; - } - - public void setClipEnabled(final boolean clipEnabled) { - mClipEnabled = clipEnabled; - if (!clipEnabled) { - setAlpha(1); - } - } - - public void setPercentOpen(final float percentOpen) { - if (mPercentOpen == percentOpen) return; - mPercentOpen = percentOpen; - if (mClipEnabled) { - setAlpha(1 - (1 - mPercentOpen) * (1.0f / 0xff)); - invalidate(); - } - } - - public void setScrollScale(final float scrollScale) { - mScrollScale = scrollScale; - } - - @Override - protected void dispatchDraw(@NonNull final Canvas canvas) { - super.dispatchDraw(canvas); - if (mClipEnabled && mPercentOpen > 0 && mPercentOpen < 1) { - final int left = Math.round(getWidth() * (1 - (1 - mPercentOpen) * (1 - mScrollScale))); - canvas.drawRect(left, getTop(), getRight(), getBottom(), mClipPaint); - } } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java b/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java index 23e31f6a4..ea2acf2b7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java @@ -30,14 +30,14 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.util.AttributeSet; import android.util.TypedValue; -import android.widget.TextView; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.view.themed.ThemedTextView; /** * Created by mariotaku on 15/5/28. */ -public class NameView extends TextView { +public class NameView extends ThemedTextView { private boolean mNameFirst; diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java b/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java index 3c8f2a08c..4a9415719 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java @@ -24,17 +24,17 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Handler; import android.os.SystemClock; -import android.support.v7.widget.AppCompatTextView; import android.text.format.DateUtils; import android.util.AttributeSet; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.view.themed.ThemedTextView; import static android.text.format.DateUtils.getRelativeTimeSpanString; import static org.mariotaku.twidere.util.Utils.formatSameDayTime; -public class ShortTimeView extends AppCompatTextView implements Constants, OnSharedPreferenceChangeListener { +public class ShortTimeView extends ThemedTextView implements Constants, OnSharedPreferenceChangeListener { private static final long TICKER_DURATION = 5000L; diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java index 06bf93d73..b1678921e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java @@ -3,7 +3,6 @@ package org.mariotaku.twidere.view.holder; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.Html; import android.text.Spanned; @@ -170,15 +169,14 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi nameView.setName(manager.getUserNickname(status.quoted_by_user_id, status.quoted_by_user_name, false)); nameView.setScreenName("@" + status.quoted_by_user_screen_name); - final int idx = status.quote_text_unescaped.lastIndexOf(" twitter.com"); if (translation != null) { quoteTextView.setText(translation.getText()); } else if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) { final String text = status.quote_text_unescaped; - quoteTextView.setText(idx > 0 ? text.substring(0, idx) : text); + quoteTextView.setText(text); } else { final Spanned text = Html.fromHtml(status.quote_text_html); - quoteTextView.setText(idx > 0 ? text.subSequence(0, idx) : text); + quoteTextView.setText(text); linkify.applyAllLinks(quoteTextView, status.account_id, getLayoutPosition(), status.is_possibly_sensitive, adapter.getLinkHighlightingStyle()); quoteTextView.setMovementMethod(null); @@ -326,10 +324,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi nameView.updateText(); quotedNameView.updateText(); - } - public CardView getCardView() { - return (CardView) itemView.findViewById(R.id.card); } public ImageView getProfileImageView() { @@ -504,11 +499,13 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi updateOptions(); } + @NonNull @Override public MediaLoaderWrapper getMediaLoader() { return loader; } + @NonNull @Override public Context getContext() { return context; @@ -519,6 +516,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi return handler; } + @NonNull @Override public UserColorNameManager getUserColorNameManager() { return manager; diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_cake.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_cake.png new file mode 100644 index 000000000..de39a3d1f Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_cake.png differ diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_link.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_link.png new file mode 100644 index 000000000..3de877f73 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_link.png differ diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_location.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_location.png new file mode 100644 index 000000000..c532119dd Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_location.png differ diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_settings.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_settings.png new file mode 100644 index 000000000..526110bc1 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_settings.png differ diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_time.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_time.png new file mode 100644 index 000000000..e021d8127 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_action_time.png differ diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_cake.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_cake.png new file mode 100644 index 000000000..369743350 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_cake.png differ diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_link.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_link.png new file mode 100644 index 000000000..3f4b6251a Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_link.png differ diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_location.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_location.png new file mode 100644 index 000000000..318e2cbdc Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_location.png differ diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_settings.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_settings.png new file mode 100644 index 000000000..e058f0d3b Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_settings.png differ diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_time.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_time.png new file mode 100644 index 000000000..054e55a76 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_action_time.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_cake.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_cake.png new file mode 100644 index 000000000..b131b3a35 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_cake.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_link.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_link.png new file mode 100644 index 000000000..8c9bab514 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_link.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_location.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_location.png new file mode 100644 index 000000000..f83aa0fa7 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_location.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_settings.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_settings.png new file mode 100644 index 000000000..71862a26d Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_settings.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_time.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_time.png new file mode 100644 index 000000000..b18c53c95 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_action_time.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_cake.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_cake.png new file mode 100644 index 000000000..9ccf82370 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_cake.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_link.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_link.png new file mode 100644 index 000000000..422ae5509 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_link.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_location.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_location.png new file mode 100644 index 000000000..0179a1b9c Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_location.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_settings.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_settings.png new file mode 100644 index 000000000..4f400e646 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_settings.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_time.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_time.png new file mode 100644 index 000000000..611e2f008 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_action_time.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_cake.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_cake.png new file mode 100644 index 000000000..c4f1646d6 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_cake.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_link.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_link.png new file mode 100644 index 000000000..3365c4ba8 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_link.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_location.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_location.png new file mode 100644 index 000000000..3c59cdd2d Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_location.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_settings.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_settings.png new file mode 100644 index 000000000..39cadf5f7 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_settings.png differ diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_time.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_time.png new file mode 100644 index 000000000..5b99c1dc2 Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_action_time.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_link.png b/twidere/src/main/res/drawable-hdpi/ic_action_link.png deleted file mode 100755 index 3eaacfe6f..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_link.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_location.png b/twidere/src/main/res/drawable-hdpi/ic_action_location.png deleted file mode 100755 index e7ce17d1d..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_location.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_portal_cake.png b/twidere/src/main/res/drawable-hdpi/ic_action_portal_cake.png deleted file mode 100755 index 03fc5570b..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_portal_cake.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_settings.png b/twidere/src/main/res/drawable-hdpi/ic_action_settings.png deleted file mode 100644 index 1a65e4de0..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_settings.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_time.png b/twidere/src/main/res/drawable-hdpi/ic_action_time.png deleted file mode 100755 index a5bcaad5d..000000000 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_time.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_link.png b/twidere/src/main/res/drawable-mdpi/ic_action_link.png deleted file mode 100755 index 48ea6462d..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_link.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_location.png b/twidere/src/main/res/drawable-mdpi/ic_action_location.png deleted file mode 100755 index 0547b3c26..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_location.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_portal_cake.png b/twidere/src/main/res/drawable-mdpi/ic_action_portal_cake.png deleted file mode 100755 index 804f114ad..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_portal_cake.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_settings.png b/twidere/src/main/res/drawable-mdpi/ic_action_settings.png deleted file mode 100644 index 7cfdb48ff..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_settings.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_time.png b/twidere/src/main/res/drawable-mdpi/ic_action_time.png deleted file mode 100755 index 9fca2514c..000000000 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_time.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_link.png b/twidere/src/main/res/drawable-xhdpi/ic_action_link.png deleted file mode 100755 index e5bf2cb72..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_link.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_location.png b/twidere/src/main/res/drawable-xhdpi/ic_action_location.png deleted file mode 100755 index b17d5a545..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_location.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_portal_cake.png b/twidere/src/main/res/drawable-xhdpi/ic_action_portal_cake.png deleted file mode 100755 index 015352410..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_portal_cake.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_settings.png b/twidere/src/main/res/drawable-xhdpi/ic_action_settings.png deleted file mode 100644 index a29fe5dc3..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_settings.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_time.png b/twidere/src/main/res/drawable-xhdpi/ic_action_time.png deleted file mode 100755 index 910362140..000000000 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_time.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_link.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_link.png deleted file mode 100755 index 1220e13ad..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_link.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_location.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_location.png deleted file mode 100755 index 4248fde8c..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_location.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_portal_cake.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_portal_cake.png deleted file mode 100755 index 0183b0820..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_portal_cake.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_settings.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_settings.png deleted file mode 100644 index 874ab7f8a..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_settings.png and /dev/null differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_time.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_time.png deleted file mode 100755 index 77969c71d..000000000 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_time.png and /dev/null differ diff --git a/twidere/src/main/res/drawable/drawer_shadow_left.xml b/twidere/src/main/res/drawable/drawer_shadow_left.xml new file mode 100644 index 000000000..aaadd3ed2 --- /dev/null +++ b/twidere/src/main/res/drawable/drawer_shadow_left.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/activity_compose_bottombar.xml b/twidere/src/main/res/layout/activity_compose_bottombar.xml index 8e4cf7b74..584949f00 100644 --- a/twidere/src/main/res/layout/activity_compose_bottombar.xml +++ b/twidere/src/main/res/layout/activity_compose_bottombar.xml @@ -66,7 +66,7 @@ - - + - - + - + + - \ No newline at end of file + android:layout_gravity="start" /> + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/card_item_activity_summary.xml b/twidere/src/main/res/layout/card_item_activity_summary.xml index ce6726e07..a376a777a 100644 --- a/twidere/src/main/res/layout/card_item_activity_summary.xml +++ b/twidere/src/main/res/layout/card_item_activity_summary.xml @@ -99,7 +99,7 @@ android:layout_margin="2dp" android:contentDescription="@string/profile_image" /> - - - - - - . --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/layout/fragment_quick_menu.xml b/twidere/src/main/res/layout/fragment_quick_menu.xml deleted file mode 100644 index 97a1bc29e..000000000 --- a/twidere/src/main/res/layout/fragment_quick_menu.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/layout/header_status_common.xml b/twidere/src/main/res/layout/header_status_common.xml index 7b307ed28..2858fde7c 100644 --- a/twidere/src/main/res/layout/header_status_common.xml +++ b/twidere/src/main/res/layout/header_status_common.xml @@ -44,7 +44,7 @@ android:layout_height="wrap_content" android:layout_margin="@dimen/padding_profile_image_detail_page" /> - - - - - - - - - - - - - - - - - + android:src="@drawable/ic_action_web" /> + android:src="@drawable/ic_action_time" /> - - - - - - - - + + + + \ No newline at end of file diff --git a/twidere/src/main/res/menu/menu_compose.xml b/twidere/src/main/res/menu/menu_compose.xml index 9d73e1b2c..f199591c7 100644 --- a/twidere/src/main/res/menu/menu_compose.xml +++ b/twidere/src/main/res/menu/menu_compose.xml @@ -1,20 +1,20 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> + tools:ignore="AlwaysShowAction" /> + tools:ignore="AlwaysShowAction" /> + android:title="@string/take_photo" /> + android:title="@string/add_image" /> + android:title="@string/edit_media" /> + android:title="@string/mark_as_sensitive" /> + tools:ignore="AlwaysShowAction" /> + tools:ignore="AlwaysShowAction" /> + tools:ignore="AlwaysShowAction" /> + app:showAsAction="never" /> + \ No newline at end of file diff --git a/twidere/src/main/res/menu/menu_user_profile.xml b/twidere/src/main/res/menu/menu_user_profile.xml index b6235c334..fb80c3467 100644 --- a/twidere/src/main/res/menu/menu_user_profile.xml +++ b/twidere/src/main/res/menu/menu_user_profile.xml @@ -40,6 +40,10 @@ android:id="@+id/saved_searches" android:icon="@drawable/ic_action_search" android:title="@string/saved_searches" /> + - - - diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index f41f92dbb..77ca0d866 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -770,4 +770,6 @@ Media preload On mobile network Twidere is reaching token limit, you will have to create an app at https://apps.twitter.com/ and paste consumer key and secret below.\nIf you continue using default key, you may not be able to sign in. + Send at + Scheduled tweets \ No newline at end of file diff --git a/twidere/src/main/svg/drawable/ic_action_cake-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_cake-mdpi.svg new file mode 100644 index 000000000..8a1414bf1 --- /dev/null +++ b/twidere/src/main/svg/drawable/ic_action_cake-mdpi.svg @@ -0,0 +1,12 @@ + + + + Artboard + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/svg/drawable/ic_action_link-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_link-mdpi.svg new file mode 100644 index 000000000..4d819e3d0 --- /dev/null +++ b/twidere/src/main/svg/drawable/ic_action_link-mdpi.svg @@ -0,0 +1,12 @@ + + + + Artboard + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/svg/drawable/ic_action_location-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_location-mdpi.svg new file mode 100644 index 000000000..9df9d1251 --- /dev/null +++ b/twidere/src/main/svg/drawable/ic_action_location-mdpi.svg @@ -0,0 +1,12 @@ + + + + Artboard + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/svg/ic_action_settings-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_settings-mdpi.svg similarity index 100% rename from twidere/src/main/svg/ic_action_settings-mdpi.svg rename to twidere/src/main/svg/drawable/ic_action_settings-mdpi.svg diff --git a/twidere/src/main/svg/drawable/ic_action_time-mdpi.svg b/twidere/src/main/svg/drawable/ic_action_time-mdpi.svg new file mode 100644 index 000000000..26434242f --- /dev/null +++ b/twidere/src/main/svg/drawable/ic_action_time-mdpi.svg @@ -0,0 +1,13 @@ + + + + Artboard + Created with Sketch. + + + + + + + + \ No newline at end of file