added enable/disable retweet feature

This commit is contained in:
Mariotaku Lee 2015-05-13 18:54:13 +08:00
parent d529226329
commit 0a47a6bb92
31 changed files with 342 additions and 157 deletions

View File

@ -27,6 +27,7 @@ import org.mariotaku.simplerestapi.param.Form;
import org.mariotaku.simplerestapi.param.Query;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Friendship;
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
import org.mariotaku.twidere.api.twitter.model.IDs;
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
import org.mariotaku.twidere.api.twitter.model.Paging;
@ -111,9 +112,11 @@ public interface FriendsFollowersResources {
Relationship showFriendship(@Query("source_screen_name") String sourceScreenName,
@Query("target_screen_name") String targetScreenName) throws TwitterException;
Relationship updateFriendship(long userId, boolean enableDeviceNotification, boolean retweets)
throws TwitterException;
@POST("/friendships/update.json")
@Body(BodyType.FORM)
Relationship updateFriendship(@Form("user_id") long userId, @Form FriendshipUpdate update) throws TwitterException;
Relationship updateFriendship(String screenName, boolean enableDeviceNotification, boolean retweets)
throws TwitterException;
@POST("/friendships/update.json")
@Body(BodyType.FORM)
Relationship updateFriendship(@Form("screen_name") String screenName, @Form FriendshipUpdate update) throws TwitterException;
}

View File

@ -0,0 +1,46 @@
/*
* 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;
import org.mariotaku.simplerestapi.http.SimpleValueMap;
/**
* Created by mariotaku on 15/5/13.
*/
public class FriendshipUpdate extends SimpleValueMap {
public void setDeviceNotificationsEnabled(boolean enabled) {
put("device", enabled);
}
public void setRetweetsEnabled(boolean enabled) {
put("retweets", enabled);
}
public FriendshipUpdate retweets(boolean enabled) {
setRetweetsEnabled(enabled);
return this;
}
public FriendshipUpdate deviceNotifications(boolean enabled) {
setDeviceNotificationsEnabled(enabled);
return this;
}
}

View File

@ -106,4 +106,8 @@ public interface Relationship extends TwitterResponse {
boolean isSourceRequestedFollowingTarget();
boolean isTargetRequestedFollowingSource();
boolean isSourceWantRetweetsFromTarget();
boolean isSourceNotificationsEnabledForTarget();
}

View File

@ -120,6 +120,16 @@ public class RelationshipImpl extends TwitterResponseImpl implements Relationshi
return target.followingRequested;
}
@Override
public boolean isSourceWantRetweetsFromTarget() {
return source.wantRetweets;
}
@Override
public boolean isSourceNotificationsEnabledForTarget() {
return source.notificationsEnabled;
}
@JsonObject
static class Target {
@JsonField(name = "id")
@ -152,5 +162,9 @@ public class RelationshipImpl extends TwitterResponseImpl implements Relationshi
boolean followedBy;
@JsonField(name = "following_requested")
boolean followingRequested;
@JsonField(name = "want_retweets")
boolean wantRetweets;
@JsonField(name = "notifications_enabled")
boolean notificationsEnabled;
}
}

View File

@ -95,6 +95,7 @@ dependencies {
compile 'org.apache.commons:commons-lang3:3.4'
compile 'com.bluelinelabs:logansquare:1.0.6'
compile 'ch.acra:acra:4.6.2'
compile 'com.github.boxme:AsyncManager:9391ed71d7@aar'
googleCompile 'com.google.android.gms:play-services-maps:7.0.0'
googleCompile 'com.google.maps.android:android-maps-utils:0.3.4'
fdroidCompile 'org.osmdroid:osmdroid-android:4.3'

View File

@ -10,8 +10,8 @@ import org.mariotaku.simplerestapi.http.RestHttpRequest;
import org.mariotaku.simplerestapi.http.mime.FileTypedData;
import org.mariotaku.simplerestapi.http.mime.MultipartTypedBody;
import org.mariotaku.simplerestapi.method.POST;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.util.TwitterAPIUtils;
import org.mariotaku.twidere.util.Utils;
import java.io.File;
import java.io.FileInputStream;
@ -69,7 +69,7 @@ public class SpiceAsyUploadTask extends AsyncTask<Object, Object, Object> {
SpiceProfilingUtil.log("server has already received file " + tmp.getName());
tmp.delete();
} catch (Exception e) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, e);
SpiceProfilingUtil.log("server does not receive file " + tmp.getName());
}

View File

@ -10,8 +10,8 @@ import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.Utils;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
@ -44,7 +44,7 @@ public class SpiceProfilingUtil {
}
public static boolean log(final String msg) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
final StackTraceElement ste = new Throwable().fillInStackTrace().getStackTrace()[1];
final String fullName = ste.getClassName();
final String name = fullName.substring(fullName.lastIndexOf('.'));

View File

@ -7,8 +7,8 @@ import android.content.SharedPreferences;
import android.os.BatteryManager;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.Utils;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
@ -30,7 +30,7 @@ public class ProfilingUtil {
}
public static boolean log(final Context context, final String msg) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
final StackTraceElement ste = new Throwable().fillInStackTrace().getStackTrace()[1];
final String fullname = ste.getClassName();
final String name = fullname.substring(fullname.lastIndexOf('.'));

View File

@ -116,6 +116,7 @@ public interface Constants extends TwidereConstants {
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;

View File

@ -37,6 +37,7 @@ import android.widget.FrameLayout;
import com.meizu.flyme.reflect.StatusBarProxy;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
@ -139,7 +140,7 @@ public abstract class BasePreferenceActivity extends AppCompatPreferenceActivity
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}

View File

@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
@ -94,7 +95,7 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}

View File

@ -23,11 +23,11 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
public class MainActivity extends Activity implements Constants {
@ -39,7 +39,7 @@ public class MainActivity extends Activity implements Constants {
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}

View File

@ -28,6 +28,7 @@ import android.support.v7.app.ThemedAppCompatDelegateFactory;
import android.support.v7.widget.Toolbar;
import android.view.View;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.StrictModeUtils;
@ -99,7 +100,7 @@ public abstract class ThemedAppCompatActivity extends AppCompatActivity implemen
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}

View File

@ -31,6 +31,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
@ -123,7 +124,7 @@ public abstract class ThemedFragmentActivity extends FragmentActivity implements
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}

View File

@ -36,6 +36,7 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.Expression;
import org.mariotaku.querybuilder.OrderBy;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
@ -180,7 +181,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
CachedUsers.NAME}, new boolean[]{false, false, true, true});
final Cursor cursor = mResolver.query(Uri.withAppendedPath(CachedUsers.CONTENT_URI_WITH_SCORE, String.valueOf(mAccountId)),
CachedUsers.BASIC_COLUMNS, selection != null ? selection.getSQL() : null, selectionArgs, orderBy.getSQL());
if (Utils.isDebugBuild() && cursor == null) throw new NullPointerException();
if (BuildConfig.DEBUG && cursor == null) throw new NullPointerException();
return cursor;
} else {
final String selection = constraintEscaped != null ? CachedHashtags.NAME + " LIKE ?||'%' ESCAPE '^'"
@ -188,7 +189,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
final String[] selectionArgs = constraintEscaped != null ? new String[]{constraintEscaped} : null;
final Cursor cursor = mDatabase.query(true, CachedHashtags.TABLE_NAME, CachedHashtags.COLUMNS, selection, selectionArgs,
null, null, CachedHashtags.NAME, null);
if (Utils.isDebugBuild() && cursor == null) throw new NullPointerException();
if (BuildConfig.DEBUG && cursor == null) throw new NullPointerException();
return cursor;
}
}

View File

@ -187,7 +187,7 @@ public class TwidereApplication extends MultiDexApplication implements Constants
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(getDiskCache());
cb.imageDownloader(getImageDownloader());
L.writeDebugLogs(Utils.isDebugBuild());
L.writeDebugLogs(BuildConfig.DEBUG);
loader.init(cb.build());
return mImageLoader = loader;
}
@ -231,7 +231,7 @@ public class TwidereApplication extends MultiDexApplication implements Constants
@Override
public void onCreate() {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
StrictModeUtils.detectAllVmPolicy();
}
super.onCreate();

View File

@ -97,6 +97,7 @@ import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
import org.mariotaku.twidere.api.twitter.model.Relationship;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
@ -133,6 +134,7 @@ import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
import org.mariotaku.twidere.util.message.FriendshipUserUpdatedEvent;
import org.mariotaku.twidere.util.message.ProfileUpdatedEvent;
import org.mariotaku.twidere.util.message.TaskStateChangedEvent;
import org.mariotaku.twidere.util.support.ActivitySupport;
@ -242,80 +244,83 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mFollowProgress.setVisibility(View.GONE);
final ParcelableUser user = getUser();
final Relationship relationship = data.getData();
mRelationship = relationship;
if (user == null) return;
invalidateOptionsMenu();
final boolean isMyself = user.account_id == user.id;
if (isMyself) {
mFollowButton.setText(R.string.edit);
mFollowButton.setVisibility(View.VISIBLE);
} else if (relationship != null) {
final int drawableRes;
mFollowButton.setEnabled(!relationship.isSourceBlockedByTarget());
if (relationship.isSourceBlockedByTarget()) {
mPagesErrorContainer.setVisibility(View.VISIBLE);
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
mPagesErrorText.setText(getString(R.string.blocked_by_user_summary, displayName));
mPagesErrorIcon.setImageResource(R.drawable.ic_info_error_generic);
mPagesContent.setVisibility(View.GONE);
} else if (!relationship.isSourceFollowingTarget() && user.is_protected) {
mPagesErrorContainer.setVisibility(View.VISIBLE);
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
mPagesErrorText.setText(getString(R.string.user_protected_summary, displayName));
mPagesErrorIcon.setImageResource(R.drawable.ic_info_locked);
mPagesContent.setVisibility(View.GONE);
} else {
mPagesErrorContainer.setVisibility(View.GONE);
mPagesErrorText.setText(null);
mPagesContent.setVisibility(View.VISIBLE);
}
if (relationship.isSourceBlockingTarget()) {
mFollowButton.setText(R.string.unblock);
drawableRes = R.drawable.ic_follow_blocked;
} else if (relationship.isSourceFollowingTarget()) {
mFollowButton.setText(R.string.unfollow);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_bidirectional;
} else {
drawableRes = R.drawable.ic_follow_outgoing;
}
} else if (user.is_follow_request_sent) {
mFollowButton.setText(R.string.requested);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_incoming;
} else {
drawableRes = R.drawable.ic_follow_pending;
}
} else {
mFollowButton.setText(R.string.follow);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_incoming;
} else {
drawableRes = R.drawable.ic_follow_none;
}
}
final Drawable icon = ResourcesCompat.getDrawable(getResources(), drawableRes, null);
final int iconSize = Math.round(mFollowButton.getTextSize() * 1.4f);
icon.setBounds(0, 0, iconSize, iconSize);
icon.setColorFilter(mFollowButton.getCurrentTextColor(), Mode.SRC_ATOP);
mFollowButton.setCompoundDrawables(icon, null, null, null);
mFollowButton.setCompoundDrawablePadding(Math.round(mFollowButton.getTextSize() * 0.25f));
final ContentResolver resolver = getContentResolver();
final ContentValues cachedValues = ParcelableUser.makeCachedUserContentValues(user);
resolver.insert(CachedUsers.CONTENT_URI, cachedValues);
mFollowButton.setVisibility(View.VISIBLE);
} else {
mFollowButton.setText(null);
mFollowButton.setVisibility(View.GONE);
mPagesErrorContainer.setVisibility(View.GONE);
mPagesContent.setVisibility(View.VISIBLE);
// mFollowingYouIndicator.setVisibility(View.GONE);
}
showRelationship(user, relationship);
}
};
private void showRelationship(ParcelableUser user, Relationship relationship) {
mRelationship = relationship;
if (user == null) return;
invalidateOptionsMenu();
final boolean isMyself = user.account_id == user.id;
if (isMyself) {
mFollowButton.setText(R.string.edit);
mFollowButton.setVisibility(View.VISIBLE);
} else if (relationship != null) {
final int drawableRes;
mFollowButton.setEnabled(!relationship.isSourceBlockedByTarget());
if (relationship.isSourceBlockedByTarget()) {
mPagesErrorContainer.setVisibility(View.VISIBLE);
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
mPagesErrorText.setText(getString(R.string.blocked_by_user_summary, displayName));
mPagesErrorIcon.setImageResource(R.drawable.ic_info_error_generic);
mPagesContent.setVisibility(View.GONE);
} else if (!relationship.isSourceFollowingTarget() && user.is_protected) {
mPagesErrorContainer.setVisibility(View.VISIBLE);
final String displayName = mUserColorNameManager.getDisplayName(user, mNameFirst, true);
mPagesErrorText.setText(getString(R.string.user_protected_summary, displayName));
mPagesErrorIcon.setImageResource(R.drawable.ic_info_locked);
mPagesContent.setVisibility(View.GONE);
} else {
mPagesErrorContainer.setVisibility(View.GONE);
mPagesErrorText.setText(null);
mPagesContent.setVisibility(View.VISIBLE);
}
if (relationship.isSourceBlockingTarget()) {
mFollowButton.setText(R.string.unblock);
drawableRes = R.drawable.ic_follow_blocked;
} else if (relationship.isSourceFollowingTarget()) {
mFollowButton.setText(R.string.unfollow);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_bidirectional;
} else {
drawableRes = R.drawable.ic_follow_outgoing;
}
} else if (user.is_follow_request_sent) {
mFollowButton.setText(R.string.requested);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_incoming;
} else {
drawableRes = R.drawable.ic_follow_pending;
}
} else {
mFollowButton.setText(R.string.follow);
if (relationship.isTargetFollowingSource()) {
drawableRes = R.drawable.ic_follow_incoming;
} else {
drawableRes = R.drawable.ic_follow_none;
}
}
final Drawable icon = ResourcesCompat.getDrawable(getResources(), drawableRes, null);
final int iconSize = Math.round(mFollowButton.getTextSize() * 1.4f);
icon.setBounds(0, 0, iconSize, iconSize);
icon.setColorFilter(mFollowButton.getCurrentTextColor(), Mode.SRC_ATOP);
mFollowButton.setCompoundDrawables(icon, null, null, null);
mFollowButton.setCompoundDrawablePadding(Math.round(mFollowButton.getTextSize() * 0.25f));
final ContentResolver resolver = getContentResolver();
final ContentValues cachedValues = ParcelableUser.makeCachedUserContentValues(user);
resolver.insert(CachedUsers.CONTENT_URI, cachedValues);
mFollowButton.setVisibility(View.VISIBLE);
} else {
mFollowButton.setText(null);
mFollowButton.setVisibility(View.GONE);
mPagesErrorContainer.setVisibility(View.GONE);
mPagesContent.setVisibility(View.VISIBLE);
}
}
private final LoaderCallbacks<SingleResponse<ParcelableUser>> mUserInfoLoaderCallbacks = new LoaderCallbacks<SingleResponse<ParcelableUser>>() {
@Override
@ -605,7 +610,15 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Subscribe
public void notifyFriendshipUpdated(FriendshipUpdatedEvent event) {
if (!event.user.equals(mUser)) return;
final ParcelableUser user = getUser();
if (user == null || event.accountId != user.account_id || event.userId != user.id) return;
getFriendship();
}
@Subscribe
public void notifyFriendshipUserUpdated(FriendshipUserUpdatedEvent event) {
final ParcelableUser user = getUser();
if (user == null || !event.user.equals(user)) return;
getFriendship();
}
@ -796,6 +809,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
public void onStart() {
super.onStart();
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
assert bus != null;
bus.register(this);
}
@ -808,6 +822,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Override
public void onStop() {
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
assert bus != null;
bus.unregister(this);
super.onStop();
}
@ -877,8 +892,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
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);
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);
@ -1011,6 +1032,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
return true;
}
case MENU_ENABLE_RETWEETS: {
final boolean newState = !item.isChecked();
final FriendshipUpdate update = new FriendshipUpdate();
update.retweets(newState);
twitter.updateFriendship(user.account_id, user.id, update);
item.setChecked(newState);
return true;
}
case R.id.muted_users: {
Utils.openMutesUsers(getActivity(), user.account_id);
return true;

View File

@ -27,6 +27,7 @@ import android.util.Pair;
import com.bluelinelabs.logansquare.LoganSquare;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Activity;
@ -34,7 +35,6 @@ import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.util.LoganSquareWrapper;
import org.mariotaku.twidere.util.TwitterAPIUtils;
import org.mariotaku.twidere.util.Utils;
import java.io.File;
import java.io.FileOutputStream;
@ -153,11 +153,11 @@ public abstract class TwitterAPIActivitiesLoader extends ParcelableActivitiesLoa
try {
return LoganSquareWrapper.parseList(file, ParcelableActivity.class);
} catch (final IOException e) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, e);
}
} catch (RuntimeException e) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
throw e;
}
Log.e(LOGTAG, "Error unserializing data", e);

View File

@ -63,6 +63,7 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.Expression;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.query.SQLSelectQuery;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.HomeActivity;
@ -629,7 +630,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
private Cursor getCachedImageCursor(final String url) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("getCachedImageCursor(%s)", url));
}
final MatrixCursor c = new MatrixCursor(TwidereDataStore.CachedImages.MATRIX_COLUMNS);
@ -641,7 +642,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
private ParcelFileDescriptor getCachedImageFd(final String url) throws FileNotFoundException {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("getCachedImageFd(%s)", url));
}
final File file = mImagePreloader.getCachedImageFile(url);
@ -672,7 +673,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
c.addRow(new String[]{host, address.getHostAddress()});
}
} catch (final IOException ignore) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, ignore);
}
}

View File

@ -27,8 +27,8 @@ import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.Utils;
import edu.tsinghua.spice.Utilies.NetworkStateUtil;
import edu.tsinghua.spice.Utilies.SpiceProfilingUtil;
@ -43,7 +43,7 @@ public class ConnectivityStateReceiver extends BroadcastReceiver implements Cons
@Override
public void onReceive(final Context context, final Intent intent) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RECEIVER_LOGTAG, String.format("Received Broadcast %s", intent));
}
if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) return;

View File

@ -29,6 +29,7 @@ import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.AccountPreferences;
@ -47,7 +48,6 @@ import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.hasAutoRefreshAccounts;
import static org.mariotaku.twidere.util.Utils.isBatteryOkay;
import static org.mariotaku.twidere.util.Utils.isDebugBuild;
import static org.mariotaku.twidere.util.Utils.isNetworkAvailable;
import static org.mariotaku.twidere.util.Utils.shouldStopAutoRefreshOnBatteryLow;
@ -65,7 +65,7 @@ public class RefreshService extends Service implements Constants {
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Refresh service received action %s", action));
}
if (BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING.equals(action)) {
@ -82,7 +82,7 @@ public class RefreshService extends Service implements Constants {
if (BROADCAST_REFRESH_HOME_TIMELINE.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new HomeRefreshableFilter());
final long[] sinceIds = getNewestStatusIdsFromDatabase(context, Statuses.CONTENT_URI, refreshIds);
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing home for %s", Arrays.toString(refreshIds)));
}
if (!isHomeTimelineRefreshing()) {
@ -91,7 +91,7 @@ public class RefreshService extends Service implements Constants {
} else if (BROADCAST_REFRESH_MENTIONS.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MentionsRefreshableFilter());
final long[] sinceIds = getNewestStatusIdsFromDatabase(context, Mentions.CONTENT_URI, refreshIds);
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing mentions for %s", Arrays.toString(refreshIds)));
}
if (!isMentionsRefreshing()) {
@ -101,7 +101,7 @@ public class RefreshService extends Service implements Constants {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MessagesRefreshableFilter());
final long[] sinceIds = getNewestMessageIdsFromDatabase(context, DirectMessages.Inbox.CONTENT_URI,
refreshIds);
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing messages for %s", Arrays.toString(refreshIds)));
}
if (!isReceivedDirectMessagesRefreshing()) {
@ -109,7 +109,7 @@ public class RefreshService extends Service implements Constants {
}
} else if (BROADCAST_REFRESH_TRENDS.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new TrendsRefreshableFilter());
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing trends for %s", Arrays.toString(refreshIds)));
}
if (!isLocalTrendsRefreshing()) {

View File

@ -32,6 +32,9 @@ import android.support.annotation.NonNull;
import android.support.v4.util.LongSparseArray;
import android.util.Log;
import com.desmond.asyncmanager.AsyncManager;
import com.desmond.asyncmanager.BackgroundTask;
import com.desmond.asyncmanager.TaskRunnable;
import com.squareup.otto.Bus;
import org.apache.commons.lang3.ArrayUtils;
@ -39,12 +42,15 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.Expression;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.SQLFunctions;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.Relationship;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.SavedSearch;
import org.mariotaku.twidere.api.twitter.model.Status;
@ -82,6 +88,7 @@ import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
import org.mariotaku.twidere.util.message.FriendshipUserUpdatedEvent;
import org.mariotaku.twidere.util.message.GetMessagesTaskEvent;
import org.mariotaku.twidere.util.message.GetStatusesTaskEvent;
import org.mariotaku.twidere.util.message.ProfileUpdatedEvent;
@ -518,6 +525,33 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return null;
}
public BackgroundTask updateFriendship(final long accountId, final long userId, final FriendshipUpdate update) {
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
if (bus == null) return null;
return AsyncManager.runBackgroundTask(new TaskRunnable<Object, SingleResponse<Relationship>, Bus>() {
@Override
public SingleResponse<Relationship> doLongOperation(Object param) throws InterruptedException {
final Twitter twitter = TwitterAPIUtils.getTwitterInstance(mContext, accountId, true);
try {
return SingleResponse.getInstance(twitter.updateFriendship(userId, update));
} catch (TwitterException e) {
return SingleResponse.getInstance(e);
}
}
@Override
public void callback(Bus handler, SingleResponse<Relationship> result) {
if (result.hasData()) {
handler.post(new FriendshipUpdatedEvent(accountId, userId, result.getData()));
} else if (result.hasException()) {
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, "Unable to update friendship", result.getException());
}
}
}
}.setResultHandler(bus));
}
static class GetSavedSearchesTask extends ManagedAsyncTask<Long, Object, SingleResponse<Object>> {
private final Context mContext;
@ -569,6 +603,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
if (result.hasData()) {
showOkMessage(mContext, R.string.profile_banner_image_updated, false);
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
assert bus != null;
bus.post(new ProfileUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(),
@ -834,7 +869,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
manager.getDisplayName(result.getData(), nameFirst, true));
showInfoMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_blocking, result.getException(), true);
}
@ -968,7 +1003,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
showOkMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_following, result.getException(), false);
}
@ -1072,7 +1107,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
manager.getDisplayName(result.getData(), nameFirst, true));
showInfoMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_muting, result.getException(), true);
}
@ -1354,7 +1389,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
manager.getDisplayName(result.getData(), nameFirst, true));
showInfoMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_unblocking, result.getException(), true);
}
@ -1604,7 +1639,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
manager.getDisplayName(result.getData(), nameFirst, true));
showInfoMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_unfollowing, result.getException(), true);
}
@ -1648,7 +1683,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
manager.getDisplayName(result.getData(), nameFirst, true));
showInfoMessage(mContext, message, false);
final Bus bus = application.getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_unmuting, result.getException(), true);
}
@ -1902,7 +1937,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
truncated));
storeMessages(accountId, messages, isOutgoing(), true);
} catch (final TwitterException e) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, e);
}
result.add(new MessageListResponse(accountId, e));
@ -2388,7 +2423,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
showInfoMessage(mContext, R.string.reported_user_for_spam, false);
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
bus.post(new FriendshipUpdatedEvent(result.getData()));
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
} else {
showErrorMessage(mContext, R.string.action_reporting_for_spam, result.getException(), true);
}
@ -2587,5 +2622,4 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
}
}

View File

@ -26,6 +26,7 @@ import android.os.Binder;
import android.os.Process;
import android.text.TextUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import java.util.HashMap;
@ -81,7 +82,7 @@ public class PermissionsManager implements Constants {
public boolean checkSignature(final String pname) {
if (mContext.getPackageName().equals(pname)) return true;
if (Utils.isDebugBuild()) return false;
if (BuildConfig.DEBUG) return false;
return mPackageManager.checkSignatures(pname, mContext.getPackageName()) == PackageManager.SIGNATURE_MATCH;
}

View File

@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.annotation.Preference;
@ -49,7 +50,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getBoolean(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}
@ -65,7 +66,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getFloat(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}
@ -75,7 +76,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getInt(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}
@ -85,7 +86,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getLong(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}
@ -99,7 +100,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getString(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}
@ -109,7 +110,7 @@ public class SharedPreferencesWrapper implements Constants {
try {
return mPreferences.getStringSet(key, defValue);
} catch (final ClassCastException e) {
if (Utils.isDebugBuild()) Log.w(LOGTAG, e);
if (BuildConfig.DEBUG) Log.w(LOGTAG, e);
mPreferences.edit().remove(key).apply();
return defValue;
}

View File

@ -2405,10 +2405,6 @@ public final class Utils implements Constants, TwitterConstants {
}
}
public static boolean isDebugBuild() {
return BuildConfig.DEBUG;
}
public static boolean isFiltered(final SQLiteDatabase database, final long user_id, final String text_plain,
final String text_html, final String source, final long retweeted_by_id) {
return isFiltered(database, user_id, text_plain, text_html, source, retweeted_by_id, true);
@ -3507,7 +3503,7 @@ public final class Utils implements Constants, TwitterConstants {
@Override
public void run() {
if (isNetworkAvailable(context) && hasAutoRefreshAccounts(context)) {
if (isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, "Start background refresh service");
}
context.startService(refreshServiceIntent);

View File

@ -1,7 +1,7 @@
/*
* Twidere - Twitter client for Android
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
* 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
@ -21,17 +21,21 @@ package org.mariotaku.twidere.util.message;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.api.twitter.model.Relationship;
/**
* Created by mariotaku on 14/12/7.
*/
public class FriendshipUpdatedEvent {
public final long accountId;
public final long userId;
@NonNull
public final ParcelableUser user;
public final Relationship relationship;
public FriendshipUpdatedEvent(@NonNull ParcelableUser user) {
this.user = user;
public FriendshipUpdatedEvent(long accountId, long userId,@NonNull Relationship relationship) {
this.accountId = accountId;
this.userId = userId;
this.relationship = relationship;
}
}

View File

@ -0,0 +1,37 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 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.message;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.model.ParcelableUser;
/**
* Created by mariotaku on 14/12/7.
*/
public class FriendshipUserUpdatedEvent {
@NonNull
public final ParcelableUser user;
public FriendshipUserUpdatedEvent(@NonNull ParcelableUser user) {
this.user = user;
}
}

View File

@ -28,9 +28,9 @@ import android.util.LruCache;
import com.squareup.okhttp.internal.Network;
import org.apache.http.conn.util.InetAddressUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.HostsFileParser;
import org.mariotaku.twidere.util.Utils;
import org.xbill.DNS.AAAARecord;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.CNAMERecord;
@ -84,7 +84,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
// First, I'll try to load address cached.
final InetAddress[] cachedHostAddr = mHostCache.get(host);
if (cachedHostAddr != null) {
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RESOLVER_LOGTAG, "Got cached " + Arrays.toString(cachedHostAddr));
return cachedHostAddr;
}
@ -96,7 +96,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
if (mappedAddr != null) {
final InetAddress[] hostAddr = fromAddressString(originalHost, mappedAddr);
mHostCache.put(originalHost, hostAddr);
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RESOLVER_LOGTAG, "Got mapped " + Arrays.toString(hostAddr));
}
return hostAddr;
@ -106,7 +106,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
if (mSystemHosts.contains(host)) {
final InetAddress[] hostAddr = fromAddressString(originalHost, mSystemHosts.getAddress(host));
mHostCache.put(originalHost, hostAddr);
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RESOLVER_LOGTAG, "Got hosts " + Arrays.toString(hostAddr));
}
return hostAddr;
@ -115,7 +115,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
if (customMappedHost != null) {
final InetAddress[] hostAddr = fromAddressString(originalHost, customMappedHost);
mHostCache.put(originalHost, hostAddr);
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RESOLVER_LOGTAG, "Got mapped address " + customMappedHost + " for host " + host);
}
return hostAddr;
@ -146,7 +146,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
if (!resolvedAddresses.isEmpty()) {
final InetAddress[] hostAddr = resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
mHostCache.put(originalHost, hostAddr);
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.d(RESOLVER_LOGTAG, "Resolved " + Arrays.toString(hostAddr));
}
return hostAddr;
@ -158,7 +158,7 @@ public class TwidereHostAddressResolver implements Constants, Network {
return resolveInternal(originalHost, ((CNAMERecord) record).getTarget().toString());
}
}
if (Utils.isDebugBuild()) {
if (BuildConfig.DEBUG) {
Log.w(RESOLVER_LOGTAG, "Resolve address " + host + " failed, using original host");
}
final InetAddress[] defaultAddresses = InetAddress.getAllByName(host);

View File

@ -1,68 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/mention"
android:icon="@drawable/ic_action_at"
app:showAsAction="ifRoom"
android:title="@string/mention_this_user"/>
android:title="@string/mention_this_user"
app:showAsAction="ifRoom" />
<item
android:id="@id/send_direct_message"
android:icon="@drawable/ic_action_new_message"
android:title="@string/send_direct_message"
android:visible="false"/>
android:visible="false" />
<item
android:id="@id/add_to_list"
android:icon="@drawable/ic_action_add_to_list"
android:title="@string/add_to_list"/>
android:title="@string/add_to_list" />
<item
android:id="@id/set_color"
android:icon="@drawable/ic_action_color_palette"
android:title="@string/set_color"/>
android:title="@string/set_color" />
<item
android:id="@id/set_nickname"
android:icon="@drawable/ic_action_edit"
android:title="@string/set_nickname"/>
android:title="@string/set_nickname" />
<item
android:id="@id/add_to_filter"
android:icon="@drawable/ic_action_speaker_muted"
android:title="@string/add_to_filter"/>
android:title="@string/add_to_filter" />
<item
android:id="@id/enable_retweets"
android:checkable="true"
android:icon="@drawable/ic_action_retweet"
android:title="@string/enable_retweets" />
<item
android:id="@id/mute_user"
android:icon="@drawable/ic_action_mic_muted"
android:title="@string/twitter_mute_user"/>
android:title="@string/twitter_mute_user" />
<item
android:id="@id/block"
android:icon="@drawable/ic_action_block"
android:title="@string/block"/>
android:title="@string/block" />
<item
android:id="@id/report_spam"
android:icon="@drawable/ic_action_warning"
android:title="@string/report_for_spam"/>
android:title="@string/report_for_spam" />
<item
android:id="@+id/muted_users"
android:icon="@drawable/ic_action_mic_muted"
android:title="@string/twitter_muted_users"/>
android:title="@string/twitter_muted_users" />
<item
android:id="@+id/blocked_users"
android:icon="@drawable/ic_action_block"
android:title="@string/blocked_users"/>
android:title="@string/blocked_users" />
<item
android:id="@+id/incoming_friendships"
android:icon="@drawable/ic_action_profile"
android:title="@string/incoming_friendships"/>
android:title="@string/incoming_friendships" />
<item
android:id="@+id/user_mentions"
android:icon="@drawable/ic_action_at"
android:title="@string/user_mentions"/>
android:title="@string/user_mentions" />
<item
android:id="@+id/saved_searches"
android:icon="@drawable/ic_action_search"
android:title="@string/saved_searches"/>
android:title="@string/saved_searches" />
<item
android:id="@id/open_with_account"
android:icon="@drawable/ic_action_accounts"
android:title="@string/open_with_account"/>
android:title="@string/open_with_account" />
</menu>

View File

@ -40,6 +40,7 @@
<item name="report_spam" type="id"/>
<item name="mute_source" type="id"/>
<item name="mute_user" type="id"/>
<item name="enable_retweets" type="id"/>
<item name="view_profile" type="id"/>
<item name="mention" type="id"/>
<item name="send_direct_message" type="id"/>

View File

@ -747,5 +747,7 @@
<string name="delete_conversation_confirm_message">Delete all messages of this conversation?</string>
<string name="name_first_summary_on">Display name first</string>
<string name="name_first_summary_off">Display @screenname first</string>
<string name="comment_hint">Comment...</string>
<string name="comment_hint">Comment…</string>
<string name="enable_retweets">Enable retweets</string>
<string name="disable_retweets">Disable retweets</string>
</resources>