migrating SlidingMenu to DrawerLayout

This commit is contained in:
Mariotaku Lee 2015-07-17 22:30:41 +08:00
parent 29a5de17e5
commit 0bf7f466a5
148 changed files with 1398 additions and 1154 deletions

View File

@ -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'

View File

@ -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

View File

@ -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";

View File

@ -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;
}

View File

@ -0,0 +1,53 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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;
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -17,25 +17,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<ScheduledStatus> {
}

View File

@ -0,0 +1,87 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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;
}
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,73 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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<ScheduledStatusesList> {
@JsonField(name = "results")
ArrayList<ScheduledStatus> 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<ScheduledStatus> implements ScheduledStatusesList {
}
}

View File

@ -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

View File

@ -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<Date> {
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);
}
}

View File

@ -50,7 +50,7 @@ public class ObjectCursor<E> extends AbstractList<E> {
mCache.put(location, object);
return object;
}
throw new ArrayIndexOutOfBoundsException(location);
throw new ArrayIndexOutOfBoundsException("length=" + mCursor.getCount() + "; index=" + location);
}
private void ensureCursor() {

View File

@ -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<ParcelableCredentials> credentialsList = getCredentialsList(context, activatedOnly, officialKeyOnly);
return credentialsList.toArray(new ParcelableCredentials[credentialsList.size()]);
}
public static List<ParcelableCredentials> getCredentialsList(final Context context, final boolean activatedOnly,
final boolean officialKeyOnly) {
if (context == null) return Collections.emptyList();

View File

@ -648,7 +648,12 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@Override
ParcelableStatus newObject(Cursor cursor) {
return new ParcelableStatus(cursor, this);
final long time = System.currentTimeMillis();
final ParcelableStatus status = new ParcelableStatus(cursor, this);
TwitterContentUtils.checkTime(status.timestamp, time);
TwitterContentUtils.checkTime(status.quote_timestamp, time);
TwitterContentUtils.checkTime(status.retweet_timestamp, time);
return status;
}
@Override

View File

@ -0,0 +1,65 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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);
}

View File

@ -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));
}
}
}

View File

@ -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'])
}

View File

@ -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'
}

View File

@ -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'

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Boolean> 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();
}

View File

@ -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<Object, Object, Map<SupportTabSpec, Integer>> {
private final Context mContext;
private final ReadStateManager mReadStateManager;

View File

@ -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;

View File

@ -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<String, String> 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;
}

View File

@ -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 {

View File

@ -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<Data> extends Adapter<ViewHolder> implements Constants,
public abstract class AbsActivitiesAdapter<Data> extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
IActivitiesAdapter<Data>, StatusClickListener, OnLinkClickListener {
private static final int ITEM_VIEW_TYPE_STUB = 0;
@ -83,8 +82,6 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> 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<Data> extends Adapter<ViewHolder> 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<Data> extends Adapter<ViewHolder> 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<Data> extends Adapter<ViewHolder> 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<Data> extends Adapter<ViewHolder> imp
}
@NonNull
@Override
public UserColorNameManager getUserColorNameManager() {
return mUserColorNameManager;

View File

@ -102,11 +102,13 @@ public abstract class AbsStatusesAdapter<D> extends LoadMoreSupportAdapter<ViewH
return mShowAccountsColor;
}
@NonNull
@Override
public final MediaLoaderWrapper getMediaLoader() {
return mMediaLoader;
}
@NonNull
@Override
public final Context getContext() {
return mContext;
@ -133,6 +135,7 @@ public abstract class AbsStatusesAdapter<D> extends LoadMoreSupportAdapter<ViewH
return mTwitterWrapper;
}
@NonNull
@Override
public UserColorNameManager getUserColorNameManager() {
return mUserColorNameManager;

View File

@ -76,6 +76,7 @@ public abstract class AbsUserListsAdapter<D> extends LoadMoreSupportAdapter<View
mCompactCards = compact;
}
@NonNull
@Override
public Context getContext() {
return mContext;
@ -97,6 +98,7 @@ public abstract class AbsUserListsAdapter<D> extends LoadMoreSupportAdapter<View
return mTwitterWrapper;
}
@NonNull
@Override
public UserColorNameManager getUserColorNameManager() {
return mUserColorNameManager;
@ -193,6 +195,7 @@ public abstract class AbsUserListsAdapter<D> extends LoadMoreSupportAdapter<View
return false;
}
@NonNull
@Override
public MediaLoaderWrapper getMediaLoader() {
return mMediaLoader;

View File

@ -74,6 +74,7 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
mCompactCards = compact;
}
@NonNull
@Override
public Context getContext() {
return mContext;
@ -95,6 +96,7 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
return mTwitterWrapper;
}
@NonNull
@Override
public UserColorNameManager getUserColorNameManager() {
return mUserColorNameManager;
@ -186,6 +188,7 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
return false;
}
@NonNull
@Override
public MediaLoaderWrapper getMediaLoader() {
return mMediaLoader;

View File

@ -48,7 +48,7 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.MessageEntryViewHolder;
public class MessageEntriesAdapter extends Adapter<ViewHolder> implements Constants,
public class MessageEntriesAdapter extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
IContentCardAdapter, OnClickListener, OnReadStateChangeListener {
public static final int ITEM_VIEW_TYPE_MESSAGE = 0;
@ -67,8 +67,6 @@ public class MessageEntriesAdapter extends Adapter<ViewHolder> 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<ViewHolder> implements Consta
};
}
@NonNull
@Override
public Context getContext() {
return mContext;
@ -130,42 +129,18 @@ public class MessageEntriesAdapter extends Adapter<ViewHolder> 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<ViewHolder> implements Consta
@Override
public final int getItemCount() {
return getMessagesCount() + (mLoadMoreIndicatorVisible ? 1 : 0);
return getMessagesCount() + (isLoadMoreIndicatorVisible() ? 1 : 0);
}
public void onMessageClick(int position) {

View File

@ -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<Data> extends IContentCardAdapter, IGapSuppo
@PreviewStyle
int getMediaPreviewStyle();
@NonNull
@Override
MediaLoaderWrapper getMediaLoader();

View File

@ -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();
}

View File

@ -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<Data> extends IContentCardAdapter, UserListCl
boolean isNameFirst();
@NonNull
@Override
MediaLoaderWrapper getMediaLoader();

View File

@ -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<Data> extends IContentCardAdapter, UserClickListe
boolean shouldShowAccountsColor();
@NonNull
@Override
MediaLoaderWrapper getMediaLoader();

View File

@ -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() {

View File

@ -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);

View File

@ -159,12 +159,12 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment<Sim
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
final ListView listView = getListView();
switch (item.getItemId()) {
case MENU_DELETE: {
case R.id.delete: {
final Expression where = Expression.in(new Column(Filters._ID), new RawItemArray(listView.getCheckedItemIds()));
mResolver.delete(getContentUri(), where.getSQL(), null);
break;
}
case MENU_INVERSE_SELECTION: {
case R.id.inverse_selection: {
final SparseBooleanArray positions = listView.getCheckedItemPositions();
for (int i = 0, j = listView.getCount(); i < j; i++) {
listView.setItemChecked(i, !positions.get(i));
@ -214,7 +214,7 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment<Sim
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD: {
case R.id.add: {
final Bundle args = new Bundle();
args.putParcelable(EXTRA_URI, getContentUri());
final AddItemFragment dialog = new AddItemFragment();
@ -367,7 +367,7 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment<Sim
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD: {
case R.id.add: {
final Bundle args = new Bundle();
args.putInt(EXTRA_AUTO_COMPLETE_TYPE, AUTO_COMPLETE_TYPE_SOURCES);
args.putParcelable(EXTRA_URI, getContentUri());
@ -454,7 +454,7 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment<Sim
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD: {
case R.id.add: {
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(getActivity(), UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, getDefaultAccountId(getActivity()));

View File

@ -101,7 +101,7 @@ public class CustomTabsFragment extends BaseFragment implements LoaderCallbacks<
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE: {
case R.id.delete: {
final long[] itemIds = mListView.getCheckedItemIds();
final Expression where = Expression.in(new Column(Tabs._ID), new RawItemArray(itemIds));
mResolver.delete(Tabs.CONTENT_URI, where.getSQL(), null);

View File

@ -104,9 +104,9 @@ public class ExtensionsListFragment extends BaseListFragment implements Constant
if (extensionInfo.pname != null && extensionInfo.settings != null) {
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_SETTINGS);
intent.setClassName(extensionInfo.pname, extensionInfo.settings);
MenuUtils.setMenuItemAvailability(menu, MENU_SETTINGS, mPackageManager.queryIntentActivities(intent, 0).size() == 1);
MenuUtils.setMenuItemAvailability(menu, R.id.settings, mPackageManager.queryIntentActivities(intent, 0).size() == 1);
} else {
MenuUtils.setMenuItemAvailability(menu, MENU_SETTINGS, false);
MenuUtils.setMenuItemAvailability(menu, R.id.settings, false);
}
}
@ -116,15 +116,15 @@ public class ExtensionsListFragment extends BaseListFragment implements Constant
final AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
final ExtensionInfo extensionInfo = mAdapter.getItem(adapterMenuInfo.position);
switch (item.getItemId()) {
case MENU_SETTINGS: {
case R.id.settings: {
openSettings(extensionInfo);
break;
}
case MENU_DELETE: {
case R.id.delete: {
uninstallExtension(extensionInfo);
break;
}
case MENU_REVOKE: {
case R.id.revoke: {
mPermissionsManager.revoke(extensionInfo.pname);
mAdapter.notifyDataSetChanged();
break;

View File

@ -95,7 +95,7 @@ public class HostMappingsListFragment extends BaseListFragment implements MultiC
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE: {
case R.id.delete: {
final SharedPreferences.Editor editor = mPreferences.edit();
final SparseBooleanArray array = mListView.getCheckedItemPositions();
if (array == null) return false;
@ -129,7 +129,7 @@ public class HostMappingsListFragment extends BaseListFragment implements MultiC
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD:
case R.id.add:
final DialogFragment df = new AddMappingDialogFragment();
df.show(getFragmentManager(), "add_mapping");
break;

View File

@ -88,7 +88,7 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_RESET: {
case R.id.reset: {
final DialogFragment f = new ResetKeyboardShortcutConfirmDialogFragment();
f.show(getFragmentManager().beginTransaction(), "reset_keyboard_shortcut_confirm");
return true;

View File

@ -42,8 +42,8 @@ import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener;
import org.mariotaku.twidere.adapter.LoadMoreSupportAdapter;
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
import org.mariotaku.twidere.adapter.iface.IContentCardAdapter;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.util.ContentListScrollListener;
import org.mariotaku.twidere.util.ContentListScrollListener.ContentListSupport;
@ -54,9 +54,10 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
/**
* Comment, blah, blah, blah.
* Created by mariotaku on 15/4/16.
*/
public abstract class AbsContentRecyclerViewFragment<A extends IContentCardAdapter> extends BaseSupportFragment
public abstract class AbsContentRecyclerViewFragment<A extends LoadMoreSupportAdapter> extends BaseSupportFragment
implements OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, ControlBarOffsetListener,
ContentListSupport {
@ -222,7 +223,7 @@ public abstract class AbsContentRecyclerViewFragment<A extends IContentCardAdapt
mItemDecoration = new DividerItemDecoration(context, mLayoutManager.getOrientation());
mRecyclerView.addItemDecoration(mItemDecoration);
}
mRecyclerView.setAdapter((RecyclerView.Adapter) mAdapter);
mRecyclerView.setAdapter(mAdapter);
mScrollListener = new ContentListScrollListener(this);
mScrollListener.setTouchSlop(ViewConfiguration.get(context).getScaledTouchSlop());

View File

@ -66,7 +66,7 @@ public abstract class AbsStatusesFragment<Data> 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;

View File

@ -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<Cursor> 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));
}
}

View File

@ -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);

View File

@ -288,7 +288,7 @@ public class DirectMessagesFragment extends AbsContentRecyclerViewFragment<Messa
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_COMPOSE: {
case R.id.compose: {
openMessageConversation(getActivity(), -1, -1);
break;
}

View File

@ -107,7 +107,7 @@ public class DraftsFragment extends BaseSupportFragment implements Constants, Lo
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE: {
case R.id.delete: {
final DeleteDraftsConfirmDialogFragment f = new DeleteDraftsConfirmDialogFragment();
final Bundle args = new Bundle();
args.putLongArray(EXTRA_IDS, mListView.getCheckedItemIds());
@ -115,7 +115,7 @@ public class DraftsFragment extends BaseSupportFragment implements Constants, Lo
f.show(getChildFragmentManager(), "delete_drafts_confirm");
break;
}
case MENU_SEND: {
case R.id.send: {
final Cursor c = mAdapter.getCursor();
if (c == null || c.isClosed()) return false;
final SparseBooleanArray checked = mListView.getCheckedItemPositions();

View File

@ -412,14 +412,14 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuUtils.setMenuItemAvailability(menu, MENU_DELETE_ALL, mRecipient != null && Utils.isOfficialCredentials(getActivity(), mAccount));
MenuUtils.setMenuItemAvailability(menu, R.id.delete_all, mRecipient != null && Utils.isOfficialCredentials(getActivity(), mAccount));
updateRecipientInfo();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE_ALL: {
case R.id.delete_all: {
return true;
}
@ -511,11 +511,11 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
final long message_id = mSelectedDirectMessage.id;
final long account_id = mSelectedDirectMessage.account_id;
switch (item.getItemId()) {
case MENU_DELETE: {
case R.id.delete: {
mTwitterWrapper.destroyDirectMessageAsync(account_id, message_id);
break;
}
case MENU_COPY: {
case R.id.copy: {
if (ClipboardUtils.setText(getActivity(), mSelectedDirectMessage.text_plain)) {
showOkMessage(getActivity(), R.string.text_copied, false);
}
@ -740,7 +740,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
mPopupMenu = new PopupMenu(context, view);
mPopupMenu.inflate(R.menu.action_direct_message);
final Menu menu = mPopupMenu.getMenu();
final MenuItem view_profile_item = menu.findItem(MENU_VIEW_PROFILE);
final MenuItem view_profile_item = menu.findItem(R.id.view_profile);
if (view_profile_item != null && dm != null) {
view_profile_item.setVisible(dm.account_id != dm.sender_id);
}

View File

@ -90,6 +90,7 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
@Override
public void onStop() {
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
assert bus != null;
bus.unregister(this);
super.onStop();
}

View File

@ -1,157 +0,0 @@
package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.commonsware.cwac.merge.MergeAdapter;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState;
import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.sqliteqb.library.OrderBy;
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
import org.mariotaku.sqliteqb.library.Table;
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.TrendsAdapter;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ExtendedFrameLayout;
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener;
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
import static org.mariotaku.twidere.util.Utils.openTweetSearch;
public class QuickMenuFragment extends BaseSupportFragment implements OnFitSystemWindowsListener, OnItemClickListener {
private ExtendedFrameLayout mQuickMenuContainer;
private SharedPreferences mPreferences;
private Context mThemedContext;
private ListView mListView;
private SlidingUpPanelLayout mSlidingUpPanel;
private ImageButton mActivitiesConfigButton;
private MergeAdapter mAdapter;
private TrendsAdapter mTrendsAdapter;
private static final int LOADER_ID_TRENDS = 1;
private final LoaderCallbacks<Cursor> mTrendsCallback = new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> 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<Cursor> loader) {
mTrendsAdapter.swapCursor(null);
}
@Override
public void onLoadFinished(final Loader<Cursor> 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);
}
}

View File

@ -0,0 +1,156 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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<ScheduledStatusesFragment.ScheduledStatusesAdapter>
implements LoaderManager.LoaderCallbacks<List<ScheduledStatus>> {
@Override
public boolean isRefreshing() {
return getLoaderManager().hasRunningLoaders();
}
@NonNull
@Override
protected ScheduledStatusesAdapter onCreateAdapter(Context context, boolean compact) {
return new ScheduledStatusesAdapter(getActivity());
}
@Override
public Loader<List<ScheduledStatus>> 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<List<ScheduledStatus>> loader, List<ScheduledStatus> 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<List<ScheduledStatus>> loader) {
getAdapter().setData(null);
}
public static class ScheduledStatusesAdapter extends LoadMoreSupportAdapter<RecyclerView.ViewHolder> {
public static final int ITEM_VIEW_TYPE_SCHEDULED_STATUS = 2;
private final Context mContext;
private final LayoutInflater mInflater;
private List<ScheduledStatus> 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<ScheduledStatus> 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());
}
}
}

View File

@ -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()));

View File

@ -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;

View File

@ -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 {

View File

@ -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);

View File

@ -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());

View File

@ -0,0 +1,73 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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<List<ScheduledStatus>> {
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<ScheduledStatus> data) {
super(context);
mAccountId = accountId;
mSinceId = sinceId;
mMaxId = maxId;
mStates = states;
}
@Override
public List<ScheduledStatus> 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();
}
}

View File

@ -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);

View File

@ -103,7 +103,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
final List<Object> 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<ContentValues> valuesList = new ArrayList<>();
final Set<Long> 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;
}

View File

@ -0,0 +1,76 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.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);
}
}

View File

@ -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<String, String> sExtraParams = new HashMap<>();

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -1,18 +1,18 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@ -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);
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Some files were not shown because too many files have changed in this diff Show More