1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-02 09:46:51 +01:00

improved compose account selection button appearance

implemented retweet in tweet list
This commit is contained in:
Mariotaku Lee 2014-12-10 20:15:09 +08:00
parent 10ac7ccf52
commit 30c302fa52
49 changed files with 1110 additions and 961 deletions

View File

@ -5,7 +5,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.0.0-rc4' classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

@ -1 +1 @@
Subproject commit 19b5078fc96f7a9d54b51d95648bbee545d650d5 Subproject commit bed0ede61d99c45746f84a87930d271f195e35a0

@ -1 +1 @@
Subproject commit 3835fb07d65585a09a6895747e313eed13304bce Subproject commit f988e0bdf132fdd4f6430d9de9acde64c6770730

@ -1 +1 @@
Subproject commit befa4a83f6fb54ac210668815e8d7bb2c930935a Subproject commit c2abc8708204fd2437cd069f173ac8a74f601266

@ -1 +1 @@
Subproject commit 028b9da420d0a3e7368bc1c09ff0400996d386ec Subproject commit d58d3151e8410524d8d223a7b78c62f3a1a5a69d

@ -1 +1 @@
Subproject commit 7e5c5d298168dea83e9b6a45684fa6416712fa2e Subproject commit 45c34152104f49e8cad50ebc86233de131ce3000

@ -1 +1 @@
Subproject commit 397e9d058eeff6e4a040677219815c3c1ede4ddc Subproject commit ef54ac9c260a982279fa963bca948e8b8d0ecf01

View File

@ -216,7 +216,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override @Override
public void onClick(final View v) { public void onClick(final View v) {
switch (v.getId()) { switch (v.getId()) {
case R.id.actions_button: { case R.id.action_buttons: {
triggerActionsClick(); triggerActionsClick();
break; break;
} }
@ -247,7 +247,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mSlidingMenu = (HomeSlidingMenu) findViewById(R.id.home_menu); mSlidingMenu = (HomeSlidingMenu) findViewById(R.id.home_menu);
mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager); mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager);
mEmptyTabHint = findViewById(R.id.empty_tab_hint); mEmptyTabHint = findViewById(R.id.empty_tab_hint);
mActionsButton = findViewById(R.id.actions_button); mActionsButton = findViewById(R.id.action_buttons);
mTabsContainer = findViewById(R.id.tabs_container); mTabsContainer = findViewById(R.id.tabs_container);
mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs); mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
mActionBarOverlay = findViewById(R.id.actionbar_overlay); mActionBarOverlay = findViewById(R.id.actionbar_overlay);
@ -297,7 +297,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override @Override
public boolean onLongClick(final View v) { public boolean onLongClick(final View v) {
switch (v.getId()) { switch (v.getId()) {
case R.id.actions_button: { case R.id.action_buttons: {
showMenuItemToast(v, v.getContentDescription(), true); showMenuItemToast(v, v.getContentDescription(), true);
return true; return true;
} }

View File

@ -59,7 +59,9 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
switch (viewType) { switch (viewType) {
case ITEM_VIEW_TYPE_STATUS: { case ITEM_VIEW_TYPE_STATUS: {
final View view = mInflater.inflate(mCardLayoutResource, parent, false); final View view = mInflater.inflate(mCardLayoutResource, parent, false);
return new StatusViewHolder(this, view); final StatusViewHolder holder = new StatusViewHolder(this, view);
holder.setupViews();
return holder;
} }
case ITEM_VIEW_TYPE_GAP: { case ITEM_VIEW_TYPE_GAP: {
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false); final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);

View File

@ -39,8 +39,11 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<ParcelableAccount> {
private final boolean mDisplayProfileImage; private final boolean mDisplayProfileImage;
public AccountsSpinnerAdapter(final Context context) { public AccountsSpinnerAdapter(final Context context) {
super(context, R.layout.list_item_two_line_small); this(context, R.layout.list_item_user);
setDropDownViewResource(R.layout.list_item_two_line_small); }
public AccountsSpinnerAdapter(final Context context, int itemViewResource) {
super(context, itemViewResource);
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper(); mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
mDisplayProfileImage = context.getSharedPreferences(DirectMessagesConversationFragment.SHARED_PREFERENCES_NAME, mDisplayProfileImage = context.getSharedPreferences(DirectMessagesConversationFragment.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true); Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true);
@ -69,18 +72,28 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<ParcelableAccount> {
final TextView text1 = (TextView) view.findViewById(android.R.id.text1); final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
final TextView text2 = (TextView) view.findViewById(android.R.id.text2); final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon); final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
text2.setVisibility(item.is_dummy ? View.GONE : View.VISIBLE); if (text2 != null) {
icon.setVisibility(item.is_dummy ? View.GONE : View.VISIBLE); text2.setVisibility(item.is_dummy ? View.GONE : View.VISIBLE);
}
if (icon != null) {
icon.setVisibility(item.is_dummy ? View.GONE : View.VISIBLE);
}
if (!item.is_dummy) { if (!item.is_dummy) {
text1.setText(item.name); if (text1 != null) {
text2.setText(String.format("@%s", item.screen_name)); text1.setText(item.name);
if (mDisplayProfileImage) {
mImageLoader.displayProfileImage(icon, item.profile_image_url);
} else {
mImageLoader.cancelDisplayTask(icon);
icon.setImageResource(R.drawable.ic_profile_image_default);
} }
} else { if (text2 != null) {
text2.setText(String.format("@%s", item.screen_name));
}
if (icon != null) {
if (mDisplayProfileImage) {
mImageLoader.displayProfileImage(icon, item.profile_image_url);
} else {
mImageLoader.cancelDisplayTask(icon);
icon.setImageResource(R.drawable.ic_profile_image_default);
}
}
} else if (text1 != null) {
text1.setText(R.string.none); text1.setText(R.string.none);
} }
} }

View File

@ -1,376 +0,0 @@
/*
* 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.adapter;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView.ScaleType;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.provider.TweetStore.Statuses;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
import java.util.Locale;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.findStatusInDatabases;
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
import static org.mariotaku.twidere.util.Utils.isFiltered;
import static org.mariotaku.twidere.util.Utils.openImage;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
public class CursorStatusesListAdapter extends BaseCursorAdapter implements IStatusesListAdapter<Cursor>, OnClickListener,
OnOverflowIconClickListener {
public static final String[] CURSOR_COLS = Statuses.COLUMNS;
private final Context mContext;
private final ImageLoaderWrapper mImageLoader;
private final MultiSelectManager mMultiSelectManager;
private final SQLiteDatabase mDatabase;
private final ImageLoadingHandler mImageLoadingHandler;
private MenuButtonClickListener mListener;
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
mAnimationEnabled;
private boolean mFilterIgnoreUser, mFilterIgnoreSource, mFilterIgnoreTextHtml, mFilterIgnoreTextPlain,
mFilterRetweetedById;
private int mMaxAnimationPosition, mCardHighlightOption;
private ParcelableStatus.CursorIndices mIndices;
private ScaleType mImagePreviewScaleType;
public CursorStatusesListAdapter(final Context context) {
this(context, Utils.isCompactCards(context));
}
public CursorStatusesListAdapter(final Context context, final boolean compactCards) {
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
mContext = context;
final TwidereApplication application = TwidereApplication.getInstance(context);
mMultiSelectManager = application.getMultiSelectManager();
mImageLoader = application.getImageLoaderWrapper();
mDatabase = application.getSQLiteDatabase();
mImageLoadingHandler = new ImageLoadingHandler();
configBaseCardAdapter(context, this);
setMaxAnimationPosition(-1);
}
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
final StatusViewHolder holder = (StatusViewHolder) view.getTag();
holder.displayStatus(cursor, mIndices);
}
@Override
public int findPositionByStatusId(final long status_id) {
final Cursor c = getCursor();
if (c == null || c.isClosed()) return -1;
for (int i = 0, count = c.getCount(); i < count; i++) {
if (c.moveToPosition(i) && c.getLong(mIndices.status_id) == status_id) return i;
}
return -1;
}
@Override
public long getAccountId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(mIndices.account_id);
}
@Override
public int getStatusCount() {
return super.getCount();
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
}
@Override
public void onItemMenuClick(ViewHolder holder, int position) {
}
@Override
public void onStatusClick(StatusViewHolder holder, int position) {
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
}
@Override
public int getCount() {
final int count = super.getCount();
return mFiltersEnabled && mIsLastItemFiltered && count > 0 ? count - 1 : count;
}
@Override
public ParcelableStatus getLastStatus() {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToLast()) return null;
final long account_id = c.getLong(mIndices.account_id);
final long status_id = c.getLong(mIndices.status_id);
return findStatusInDatabases(mContext, account_id, status_id);
}
@Override
public long getLastStatusId() {
final Cursor c = getCursor();
try {
if (c == null || c.isClosed() || !c.moveToLast()) return -1;
return c.getLong(mIndices.status_id);
} catch (final IllegalStateException e) {
return -1;
}
}
@Override
public Context getContext() {
return mContext;
}
@Override
public ImageLoadingHandler getImageLoadingHandler() {
return mImageLoadingHandler;
}
@Override
public ParcelableStatus getStatus(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
return new ParcelableStatus(c, mIndices);
}
@Override
public long getStatusId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(mIndices.status_id);
}
@Override
public boolean isGapItem(int position) {
return false;
}
@Override
public boolean isLastItemFiltered() {
return mFiltersEnabled && mIsLastItemFiltered;
}
@Override
public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
final View view = super.newView(context, cursor, parent);
final Object tag = view.getTag();
if (!(tag instanceof StatusViewHolder)) {
final StatusViewHolder holder = new StatusViewHolder(this, view);
view.setTag(holder);
}
return view;
}
@Override
public void onClick(final View view) {
if (mMultiSelectManager.isActive()) return;
final Object tag = view.getTag();
final int position = tag instanceof Integer ? (Integer) tag : -1;
if (position == -1) return;
switch (view.getId()) {
case R.id.image_preview: {
final ParcelableStatus status = getStatus(position);
if (status == null || status.first_media == null) return;
openImage(mContext, status.account_id, status.first_media, status.is_possibly_sensitive);
break;
}
case R.id.my_profile_image:
case R.id.profile_image: {
final ParcelableStatus status = getStatus(position);
if (status == null) return;
final Activity activity = (Activity) getContext();
final Bundle options = Utils.makeSceneTransitionOption(activity,
new Pair<>(view, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
openUserProfile(mContext, status.account_id, status.user_id,
status.user_screen_name, options);
break;
}
}
}
@Override
public void onOverflowIconClick(final View view) {
if (mMultiSelectManager.isActive()) return;
final Object tag = view.getTag();
if (tag instanceof StatusViewHolder) {
final StatusViewHolder holder = (StatusViewHolder) tag;
final int position = holder.getPosition();
if (position == -1 || mListener == null) return;
mListener.onMenuButtonClick(view, position, getItemId(position));
}
}
@Override
public void setAnimationEnabled(final boolean anim) {
mAnimationEnabled = anim;
}
@Override
public void setCardHighlightOption(final String option) {
mCardHighlightOption = getCardHighlightOptionInt(option);
}
@Override
public void setData(final Cursor data) {
swapCursor(data);
}
@Override
public void setDisplayImagePreview(final boolean display) {
mDisplayImagePreview = display;
}
@Override
public void setDisplaySensitiveContents(final boolean display) {
mDisplaySensitiveContents = display;
}
@Override
public void setFavoritesHightlightDisabled(final boolean disable) {
mFavoritesHighlightDisabled = disable;
}
@Override
public void setFiltersEnabled(final boolean enabled) {
if (mFiltersEnabled == enabled) return;
mFiltersEnabled = enabled;
rebuildFilterInfo(getCursor(), mIndices);
}
@Override
public void setGapDisallowed(final boolean disallowed) {
mGapDisallowed = disallowed;
}
@Override
public void setHighlightKeyword(final String... keywords) {
// TODO Auto-generated method stub
}
@Override
public void setIgnoredFilterFields(final boolean user, final boolean textPlain, final boolean textHtml,
final boolean source, final boolean retweetedById) {
mFilterIgnoreTextPlain = textPlain;
mFilterIgnoreTextHtml = textHtml;
mFilterIgnoreUser = user;
mFilterIgnoreSource = source;
mFilterRetweetedById = retweetedById;
rebuildFilterInfo(getCursor(), mIndices);
}
@Override
public void setImagePreviewScaleType(final String scaleTypeString) {
final ScaleType scaleType = ScaleType.valueOf(scaleTypeString.toUpperCase(Locale.US));
mImagePreviewScaleType = scaleType;
}
@Override
public void setIndicateMyStatusDisabled(final boolean disable) {
mIndicateMyStatusDisabled = disable;
}
@Override
public void setMaxAnimationPosition(final int position) {
mMaxAnimationPosition = position;
}
@Override
public void setMentionsHightlightDisabled(final boolean disable) {
mMentionsHighlightDisabled = disable;
}
@Override
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
mListener = listener;
}
@Override
public Cursor swapCursor(final Cursor cursor) {
mIndices = cursor != null ? new ParcelableStatus.CursorIndices(cursor) : null;
rebuildFilterInfo(cursor, mIndices);
return super.swapCursor(cursor);
}
private void rebuildFilterInfo(final Cursor c, final ParcelableStatus.CursorIndices i) {
if (i != null && c != null && moveCursorToLast(c)) {
final long userId = mFilterIgnoreUser ? -1 : c.getLong(mIndices.user_id);
final String textPlain = mFilterIgnoreTextPlain ? null : c.getString(mIndices.text_plain);
final String textHtml = mFilterIgnoreTextHtml ? null : c.getString(mIndices.text_html);
final String source = mFilterIgnoreSource ? null : c.getString(mIndices.source);
final long retweetedById = mFilterRetweetedById ? -1 : c.getLong(mIndices.retweeted_by_user_id);
mIsLastItemFiltered = isFiltered(mDatabase, userId, textPlain, textHtml, source, retweetedById);
} else {
mIsLastItemFiltered = false;
}
}
private static int getItemResource(final boolean compactCards) {
return compactCards ? R.layout.card_item_status_compat : R.layout.card_item_status;
}
private static boolean moveCursorToLast(final Cursor c) {
if (c == null || c.isClosed()) return false;
try {
return c.moveToNext();
} catch (final Exception e) {
return false;
}
}
@Override
public void onGapClick(ViewHolder holder, int position) {
}
}

View File

@ -43,7 +43,7 @@ public class SimpleParcelableUsersAdapter extends BaseArrayAdapter<ParcelableUse
private final Context mContext; private final Context mContext;
public SimpleParcelableUsersAdapter(final Context context) { public SimpleParcelableUsersAdapter(final Context context) {
super(context, R.layout.list_item_two_line); super(context, R.layout.list_item_user);
mContext = context; mContext = context;
final TwidereApplication app = TwidereApplication.getInstance(context); final TwidereApplication app = TwidereApplication.getInstance(context);
mImageLoader = app.getImageLoaderWrapper(); mImageLoader = app.getImageLoaderWrapper();

View File

@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.State;
import android.view.View; import android.view.View;
public class DividerItemDecoration extends RecyclerView.ItemDecoration { public class DividerItemDecoration extends RecyclerView.ItemDecoration {
@ -55,7 +56,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
} }
@Override @Override
public void onDraw(Canvas c, RecyclerView parent) { public void onDraw(Canvas c, RecyclerView parent, State state) {
if (mOrientation == VERTICAL_LIST) { if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent); drawVertical(c, parent);
} else { } else {
@ -98,7 +99,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
} }
@Override @Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
if (mOrientation == VERTICAL_LIST) { if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else { } else {

View File

@ -188,15 +188,31 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
@Override @Override
public void onStatusActionClick(StatusViewHolder holder, int id, int position) { public void onStatusActionClick(StatusViewHolder holder, int id, int position) {
final ParcelableStatus status = mAdapter.getStatus(position);
if (status == null) return;
switch (id) { switch (id) {
case R.id.reply_count: { case R.id.reply_count: {
final Context context = getActivity(); final Context context = getActivity();
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY); final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY);
intent.setPackage(context.getPackageName()); intent.setPackage(context.getPackageName());
intent.putExtra(IntentConstants.EXTRA_STATUS, mAdapter.getStatus(position)); intent.putExtra(IntentConstants.EXTRA_STATUS, status);
context.startActivity(intent); context.startActivity(intent);
break; break;
} }
case R.id.retweet_count: {
RetweetQuoteDialogFragment.show(getFragmentManager(), status);
break;
}
case R.id.favorite_count: {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return;
if (status.is_favorite) {
twitter.destroyFavoriteAsync(status.account_id, status.id);
} else {
twitter.createFavoriteAsync(status.account_id, status.id);
}
break;
}
} }
} }

View File

@ -305,7 +305,7 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
cancelRetweet(twitter, status); cancelRetweet(twitter, status);
} else { } else {
final long id_to_retweet = status.retweet_id > 0 ? status.retweet_id : status.id; final long id_to_retweet = status.retweet_id > 0 ? status.retweet_id : status.id;
twitter.retweetStatus(status.account_id, id_to_retweet); twitter.retweetStatusAsync(status.account_id, id_to_retweet);
} }
break; break;
} }

View File

@ -24,6 +24,7 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
@ -33,51 +34,52 @@ import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
public class DestroyFriendshipDialogFragment extends BaseSupportDialogFragment implements public class DestroyFriendshipDialogFragment extends BaseSupportDialogFragment implements
DialogInterface.OnClickListener { DialogInterface.OnClickListener {
public static final String FRAGMENT_TAG = "destroy_friendship"; public static final String FRAGMENT_TAG = "destroy_friendship";
@Override @Override
public void onClick(final DialogInterface dialog, final int which) { public void onClick(final DialogInterface dialog, final int which) {
switch (which) { switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
final ParcelableUser user = getUser(); final ParcelableUser user = getUser();
final AsyncTwitterWrapper twitter = getTwitterWrapper(); final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (user == null || twitter == null) return; if (user == null || twitter == null) return;
twitter.destroyFriendshipAsync(user.account_id, user.id); twitter.destroyFriendshipAsync(user.account_id, user.id);
break; break;
default: default:
break; break;
} }
} }
@Override @NonNull
public Dialog onCreateDialog(final Bundle savedInstanceState) { @Override
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity()); public Dialog onCreateDialog(final Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped); final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final ParcelableUser user = getUser(); final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
if (user != null) { final ParcelableUser user = getUser();
final String display_name = Utils.getDisplayName(getActivity(), user.id, user.name, user.screen_name); if (user != null) {
builder.setTitle(getString(R.string.unfollow_user, display_name)); final String display_name = Utils.getDisplayName(getActivity(), user.id, user.name, user.screen_name);
builder.setMessage(getString(R.string.unfollow_user_confirm_message, display_name)); builder.setTitle(getString(R.string.unfollow_user, display_name));
} builder.setMessage(getString(R.string.unfollow_user_confirm_message, display_name));
builder.setPositiveButton(android.R.string.ok, this); }
builder.setNegativeButton(android.R.string.cancel, null); builder.setPositiveButton(android.R.string.ok, this);
return builder.create(); builder.setNegativeButton(android.R.string.cancel, null);
} return builder.create();
}
private ParcelableUser getUser() { private ParcelableUser getUser() {
final Bundle args = getArguments(); final Bundle args = getArguments();
if (!args.containsKey(EXTRA_USER)) return null; if (!args.containsKey(EXTRA_USER)) return null;
return args.getParcelable(EXTRA_USER); return args.getParcelable(EXTRA_USER);
} }
public static DestroyFriendshipDialogFragment show(final FragmentManager fm, final ParcelableUser user) { public static DestroyFriendshipDialogFragment show(final FragmentManager fm, final ParcelableUser user) {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putParcelable(EXTRA_USER, user); args.putParcelable(EXTRA_USER, user);
final DestroyFriendshipDialogFragment f = new DestroyFriendshipDialogFragment(); final DestroyFriendshipDialogFragment f = new DestroyFriendshipDialogFragment();
f.setArguments(args); f.setArguments(args);
f.show(fm, FRAGMENT_TAG); f.show(fm, FRAGMENT_TAG);
return f; return f;
} }
} }

View File

@ -19,12 +19,13 @@
package org.mariotaku.twidere.fragment.support; package org.mariotaku.twidere.fragment.support;
import android.app.ActionBar;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.PorterDuff; import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
@ -45,8 +46,8 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ImageView.ScaleType; import android.widget.ImageView.ScaleType;
import android.widget.ListView; import android.widget.ListView;
@ -60,26 +61,25 @@ import com.squareup.otto.Subscribe;
import org.mariotaku.menucomponent.widget.PopupMenu; import org.mariotaku.menucomponent.widget.PopupMenu;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.ImagePickerActivity; import org.mariotaku.twidere.activity.support.ImagePickerActivity;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter; import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter;
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener; import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.loader.support.UserSearchLoader;
import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableDirectMessage;
import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.provider.TweetStore; import org.mariotaku.twidere.provider.TweetStore;
import org.mariotaku.twidere.provider.TweetStore.CachedUsers;
import org.mariotaku.twidere.provider.TweetStore.DirectMessages; import org.mariotaku.twidere.provider.TweetStore.DirectMessages;
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Conversation; import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Conversation;
import org.mariotaku.twidere.task.TwidereAsyncTask;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ClipboardUtils; import org.mariotaku.twidere.util.ClipboardUtils;
import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ParseUtils; import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereValidator; import org.mariotaku.twidere.util.TwidereValidator;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.util.message.TaskStateChangedEvent; import org.mariotaku.twidere.util.message.TaskStateChangedEvent;
import org.mariotaku.twidere.view.StatusTextCountView; import org.mariotaku.twidere.view.StatusTextCountView;
import org.mariotaku.twidere.view.iface.IColorLabelView; import org.mariotaku.twidere.view.iface.IColorLabelView;
@ -90,27 +90,29 @@ import java.util.Locale;
import static android.text.TextUtils.isEmpty; import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri; import static org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter; import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.getOldestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.showOkMessage; import static org.mariotaku.twidere.util.Utils.showOkMessage;
public class DirectMessagesConversationFragment extends BasePullToRefreshListFragment implements public class DirectMessagesConversationFragment extends BaseSupportFragment implements
LoaderCallbacks<Cursor>, OnMenuItemClickListener, TextWatcher, OnClickListener, LoaderCallbacks<Cursor>, OnMenuItemClickListener, TextWatcher, OnClickListener,
OnItemSelectedListener, OnEditorActionListener, MenuButtonClickListener { OnItemSelectedListener, OnEditorActionListener, MenuButtonClickListener {
private static final int LOADER_ID_SEARCH_USERS = 1;
private TwidereValidator mValidator; private TwidereValidator mValidator;
private AsyncTwitterWrapper mTwitterWrapper; private AsyncTwitterWrapper mTwitterWrapper;
private SharedPreferences mPreferences; private SharedPreferences mPreferences;
private ListView mListView; private ListView mMessagesListView, mUsersSearchList;
private EditText mEditText; private EditText mEditText;
private StatusTextCountView mTextCountView; private StatusTextCountView mTextCountView;
private View mSendButton; private View mSendButton;
private ImageView mAddImageButton; private ImageView mAddImageButton;
private View mConversationContainer, mRecipientSelectorContainer, mRecipientSelector; private View mConversationContainer, mRecipientSelectorContainer;
private Spinner mAccountSpinner; private Spinner mAccountSpinner;
private ImageView mSenderProfileImageView, mRecipientProfileImageView; private ImageView mSenderProfileImageView, mRecipientProfileImageView;
private EditText mUserQuery;
private View mUsersSearchProgress;
private View mQueryButton;
private PopupMenu mPopupMenu; private PopupMenu mPopupMenu;
@ -123,13 +125,37 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
private Locale mLocale; private Locale mLocale;
private DirectMessagesConversationAdapter mAdapter; private DirectMessagesConversationAdapter mAdapter;
private SimpleParcelableUsersAdapter mUsersSearchAdapter;
private ParcelableAccount mSender; private ParcelableAccount mSender;
private ParcelableUser mRecipient; private ParcelableUser mRecipient;
private ImageLoaderWrapper mImageLoader; private ImageLoaderWrapper mImageLoader;
private IColorLabelView mProfileImageContainer; private IColorLabelView mProfileImageContainer;
private LoaderCallbacks<List<ParcelableUser>> mSearchLoadersCallback = new LoaderCallbacks<List<ParcelableUser>>() {
@Override
public Loader<List<ParcelableUser>> onCreateLoader(int id, Bundle args) {
mUsersSearchList.setVisibility(View.GONE);
mUsersSearchProgress.setVisibility(View.VISIBLE);
final long accountId = args.getLong(EXTRA_ACCOUNT_ID);
final String query = args.getString(EXTRA_QUERY);
return new UserSearchLoader(getActivity(), accountId, query, 0, null);
}
@Override
public void onLoadFinished(Loader<List<ParcelableUser>> loader, List<ParcelableUser> data) {
mUsersSearchList.setVisibility(View.VISIBLE);
mUsersSearchProgress.setVisibility(View.GONE);
mUsersSearchAdapter.setData(data, true);
}
@Override
public void onLoaderReset(Loader<List<ParcelableUser>> loader) {
}
};
@Subscribe @Subscribe
public void notifyTaskStateChanged(TaskStateChangedEvent event) { public void notifyTaskStateChanged(TaskStateChangedEvent event) {
@ -150,35 +176,50 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
public void onActivityCreated(final Bundle savedInstanceState) { public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true); setHasOptionsMenu(true);
final FragmentActivity activity = getActivity();
final ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.actionbar_custom_view_message_user_picker);
final View actionBarView = actionBar.getCustomView();
mAccountSpinner = (Spinner) actionBarView.findViewById(R.id.account_spinner);
mUserQuery = (EditText) actionBarView.findViewById(R.id.user_query);
mQueryButton = actionBarView.findViewById(R.id.query_button);
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(activity, false);
final AccountsSpinnerAdapter adapter = new AccountsSpinnerAdapter(actionBar.getThemedContext(), R.layout.spinner_item_account_icon);
adapter.setDropDownViewResource(R.layout.list_item_user);
adapter.addAll(accounts);
mAccountSpinner.setAdapter(adapter);
mAccountSpinner.setOnItemSelectedListener(this);
mQueryButton.setOnClickListener(this);
}
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mImageLoader = TwidereApplication.getInstance(getActivity()).getImageLoaderWrapper(); mImageLoader = TwidereApplication.getInstance(getActivity()).getImageLoaderWrapper();
mTwitterWrapper = getTwitterWrapper(); mTwitterWrapper = getTwitterWrapper();
mValidator = new TwidereValidator(getActivity()); mValidator = new TwidereValidator(getActivity());
mLocale = getResources().getConfiguration().locale; mLocale = getResources().getConfiguration().locale;
mAdapter = new DirectMessagesConversationAdapter(getActivity()); mAdapter = new DirectMessagesConversationAdapter(getActivity());
setListAdapter(mAdapter); mMessagesListView.setAdapter(mAdapter);
mAdapter.setMenuButtonClickListener(this); mAdapter.setMenuButtonClickListener(this);
mListView = getListView(); mMessagesListView.setDivider(null);
mListView.setDivider(null); mMessagesListView.setSelector(android.R.color.transparent);
mListView.setSelector(android.R.color.transparent); mMessagesListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false)); mMessagesListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); mMessagesListView.setStackFromBottom(true);
mListView.setStackFromBottom(true);
setListShownNoAnimation(false); mUsersSearchAdapter = new SimpleParcelableUsersAdapter(activity);
mUsersSearchList.setAdapter(mUsersSearchAdapter);
if (mPreferences.getBoolean(KEY_QUICK_SEND, false)) { if (mPreferences.getBoolean(KEY_QUICK_SEND, false)) {
mEditText.setOnEditorActionListener(this); mEditText.setOnEditorActionListener(this);
} }
mEditText.addTextChangedListener(this); mEditText.addTextChangedListener(this);
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(getActivity(), false);
mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts));
mAccountSpinner.setOnItemSelectedListener(this);
mSendButton.setOnClickListener(this); mSendButton.setOnClickListener(this);
mAddImageButton.setOnClickListener(this); mAddImageButton.setOnClickListener(this);
mSendButton.setEnabled(false); mSendButton.setEnabled(false);
mRecipientSelector.setOnClickListener(this);
if (savedInstanceState != null) { if (savedInstanceState != null) {
final long accountId = savedInstanceState.getLong(EXTRA_ACCOUNT_ID, -1); final long accountId = savedInstanceState.getLong(EXTRA_ACCOUNT_ID, -1);
final long recipientId = savedInstanceState.getLong(EXTRA_RECIPIENT_ID, -1); final long recipientId = savedInstanceState.getLong(EXTRA_RECIPIENT_ID, -1);
@ -194,6 +235,9 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
final boolean isValid = mAccountId > 0 && mRecipientId > 0; final boolean isValid = mAccountId > 0 && mRecipientId > 0;
mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE); mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE);
mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE); mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE);
mUsersSearchList.setVisibility(View.GONE);
mUsersSearchProgress.setVisibility(View.GONE);
} }
@Override @Override
@ -235,6 +279,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
|| mSenderProfileImageView == null) { || mSenderProfileImageView == null) {
return; return;
} }
mProfileImageContainer.setVisibility(mRecipient != null ? View.VISIBLE : View.GONE);
if (mSender != null && mRecipient != null) { if (mSender != null && mRecipient != null) {
mImageLoader.displayProfileImage(mSenderProfileImageView, mSender.profile_image_url); mImageLoader.displayProfileImage(mSenderProfileImageView, mSender.profile_image_url);
mImageLoader.displayProfileImage(mRecipientProfileImageView, mRecipient.profile_image_url); mImageLoader.displayProfileImage(mRecipientProfileImageView, mRecipient.profile_image_url);
@ -262,14 +307,14 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
sendDirectMessage(); sendDirectMessage();
break; break;
} }
case R.id.recipient_selector: { // case R.id.recipient_selector: {
if (mAccountId <= 0) return; // if (mAccountId <= 0) return;
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER); // final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(getActivity(), UserListSelectorActivity.class); // intent.setClass(getActivity(), UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, mAccountId); // intent.putExtra(EXTRA_ACCOUNT_ID, mAccountId);
startActivityForResult(intent, REQUEST_SELECT_USER); // startActivityForResult(intent, REQUEST_SELECT_USER);
break; // break;
} // }
case R.id.add_image: { case R.id.add_image: {
final Intent intent = new Intent(getActivity(), ImagePickerActivity.class); final Intent intent = new Intent(getActivity(), ImagePickerActivity.class);
startActivityForResult(intent, REQUEST_PICK_IMAGE); startActivityForResult(intent, REQUEST_PICK_IMAGE);
@ -282,6 +327,26 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
recipient.screen_name, null); recipient.screen_name, null);
break; break;
} }
case R.id.query_button: {
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
searchUsers(account.account_id, ParseUtils.parseString(mUserQuery.getText()));
break;
}
}
}
private boolean mSearchUsersLoaderInitialized;
private void searchUsers(long accountId, String query) {
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, accountId);
args.putString(EXTRA_QUERY, query);
final LoaderManager lm = getLoaderManager();
if (mSearchUsersLoaderInitialized) {
lm.restartLoader(LOADER_ID_SEARCH_USERS, args, mSearchLoadersCallback);
} else {
mSearchUsersLoaderInitialized = true;
lm.initLoader(LOADER_ID_SEARCH_USERS, args, mSearchLoadersCallback);
} }
} }
@ -301,18 +366,16 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
@Override @Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_messages_conversation, null); return inflater.inflate(R.layout.fragment_messages_conversation, container, false);
final FrameLayout listContainer = (FrameLayout) view.findViewById(R.id.list_container); }
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT); @Override
listContainer.addView(super.onCreateView(inflater, container, savedInstanceState), lp); protected void fitSystemWindows(Rect insets) {
final ViewGroup inputSendContainer = (ViewGroup) view.findViewById(R.id.input_send_container); super.fitSystemWindows(insets);
final FragmentActivity activity = getActivity(); final View view = getView();
final int themeRes = ThemeUtils.getThemeResource(activity); if (view != null) {
ViewAccessor.setBackground(inputSendContainer, ThemeUtils.getActionBarSplitBackground(activity, themeRes)); view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
final Context actionBarContext = ThemeUtils.getActionBarContext(activity); }
View.inflate(actionBarContext, R.layout.fragment_messages_conversation_input_send, inputSendContainer);
return view;
} }
@Override @Override
@ -344,7 +407,6 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
@Override @Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) { public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
mAdapter.swapCursor(cursor); mAdapter.swapCursor(cursor);
setListShown(true);
} }
@Override @Override
@ -381,33 +443,33 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
} }
@Override // @Override
public void onRefreshFromEnd() { // public void onRefreshFromEnd() {
new TwidereAsyncTask<Void, Void, long[][]>() { // new TwidereAsyncTask<Void, Void, long[][]>() {
//
@Override // @Override
protected long[][] doInBackground(final Void... params) { // protected long[][] doInBackground(final Void... params) {
final long[][] result = new long[2][]; // final long[][] result = new long[2][];
result[0] = getActivatedAccountIds(getActivity()); // result[0] = getActivatedAccountIds(getActivity());
result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI); // result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
return result; // return result;
} // }
//
@Override // @Override
protected void onPostExecute(final long[][] result) { // protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = getTwitterWrapper(); // final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return; // if (twitter == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]); // twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
twitter.getSentDirectMessagesAsync(result[0], null, null); // twitter.getSentDirectMessagesAsync(result[0], null, null);
} // }
//
}.executeTask(); // }.executeTask();
} // }
//
@Override // @Override
public void onRefreshFromStart() { // public void onRefreshFromStart() {
loadMoreMessages(); // loadMoreMessages();
} // }
@Override @Override
public void onResume() { public void onResume() {
@ -462,24 +524,25 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
@Override @Override
public void onViewCreated(final View view, final Bundle savedInstanceState) { public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
mUsersSearchProgress = view.findViewById(R.id.users_search_progress);
mUsersSearchList = (ListView) view.findViewById(R.id.users_search_list);
mMessagesListView = (ListView) view.findViewById(android.R.id.list);
final View inputSendContainer = view.findViewById(R.id.input_send_container); final View inputSendContainer = view.findViewById(R.id.input_send_container);
mConversationContainer = view.findViewById(R.id.conversation_container); mConversationContainer = view.findViewById(R.id.conversation_container);
mRecipientSelectorContainer = view.findViewById(R.id.recipient_selector_container); mRecipientSelectorContainer = view.findViewById(R.id.recipient_selector_container);
mRecipientSelector = view.findViewById(R.id.recipient_selector);
mAccountSpinner = (Spinner) view.findViewById(R.id.account_selector);
mEditText = (EditText) inputSendContainer.findViewById(R.id.edit_text); mEditText = (EditText) inputSendContainer.findViewById(R.id.edit_text);
mTextCountView = (StatusTextCountView) inputSendContainer.findViewById(R.id.text_count); mTextCountView = (StatusTextCountView) inputSendContainer.findViewById(R.id.text_count);
mSendButton = inputSendContainer.findViewById(R.id.send); mSendButton = inputSendContainer.findViewById(R.id.send);
mAddImageButton = (ImageView) inputSendContainer.findViewById(R.id.add_image); mAddImageButton = (ImageView) inputSendContainer.findViewById(R.id.add_image);
mRecipientSelector = view.findViewById(R.id.recipient_selector); mUsersSearchList = (ListView) view.findViewById(R.id.users_search_list);
} }
@Override // @Override
public boolean scrollToStart() { // public boolean scrollToStart() {
if (mAdapter == null || mAdapter.isEmpty()) return false; // if (mAdapter == null || mAdapter.isEmpty()) return false;
setSelection(mAdapter.getCount() - 1); // setSelection(mAdapter.getCount() - 1);
return true; // return true;
} // }
public void showConversation(final long accountId, final long recipientId) { public void showConversation(final long accountId, final long recipientId) {
mAccountId = accountId; mAccountId = accountId;
@ -497,47 +560,56 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
mLoaderInitialized = true; mLoaderInitialized = true;
lm.initLoader(0, args, this); lm.initLoader(0, args, this);
} }
updateActionBar();
updateProfileImage(); updateProfileImage();
} }
@Override private void updateActionBar() {
protected void onReachedTop() { final FragmentActivity activity = getActivity();
if (!mLoadMoreAutomatically) return; final ActionBar actionBar = activity.getActionBar();
loadMoreMessages(); if (actionBar == null) return;
actionBar.setDisplayOptions(mRecipient != null ? ActionBar.DISPLAY_SHOW_TITLE : ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
} }
protected void updateRefreshState() { // @Override
final AsyncTwitterWrapper twitter = getTwitterWrapper(); // protected void onReachedTop() {
if (twitter == null || !getUserVisibleHint()) return; // if (!mLoadMoreAutomatically) return;
final boolean refreshing = twitter.isReceivedDirectMessagesRefreshing() // loadMoreMessages();
|| twitter.isSentDirectMessagesRefreshing(); // }
setProgressBarIndeterminateVisibility(refreshing);
setRefreshing(refreshing); private void updateRefreshState() {
// final AsyncTwitterWrapper twitter = getTwitterWrapper();
// if (twitter == null || !getUserVisibleHint()) return;
// final boolean refreshing = twitter.isReceivedDirectMessagesRefreshing()
// || twitter.isSentDirectMessagesRefreshing();
// setProgressBarIndeterminateVisibility(refreshing);
// setRefreshing(refreshing);
} }
private void loadMoreMessages() { // private void loadMoreMessages() {
if (isRefreshing()) return; // if (isRefreshing()) return;
new TwidereAsyncTask<Void, Void, long[][]>() { // new TwidereAsyncTask<Void, Void, long[][]>() {
//
@Override // @Override
protected long[][] doInBackground(final Void... params) { // protected long[][] doInBackground(final Void... params) {
final long[][] result = new long[3][]; // final long[][] result = new long[3][];
result[0] = getActivatedAccountIds(getActivity()); // result[0] = getActivatedAccountIds(getActivity());
result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI); // result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI); // result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
return result; // return result;
} // }
//
@Override // @Override
protected void onPostExecute(final long[][] result) { // protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = getTwitterWrapper(); // final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return; // if (twitter == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], result[1], null); // twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
twitter.getSentDirectMessagesAsync(result[0], result[2], null); // twitter.getSentDirectMessagesAsync(result[0], result[2], null);
} // }
//
}.executeTask(); // }.executeTask();
} // }
private void sendDirectMessage() { private void sendDirectMessage() {
final Editable text = mEditText.getText(); final Editable text = mEditText.getText();
@ -568,12 +640,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
} }
private void updateAddImageButton() { private void updateAddImageButton() {
final int color = ThemeUtils.getThemeColor(getActivity()); mAddImageButton.setActivated(mImageUri != null);
if (mImageUri != null) {
mAddImageButton.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
} else {
mAddImageButton.clearColorFilter();
}
} }
private void updateTextCount() { private void updateTextCount() {
@ -582,4 +649,83 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
mTextCountView.setTextCount(count); mTextCountView.setTextCount(count);
} }
private static class UsersSearchAdapter extends BaseAdapter {
private final LayoutInflater mInflater;
private Object mUsers;
private int mScreenNameIdx;
private long mAccountId;
public UsersSearchAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setUsers(List<ParcelableUser> users) {
mUsers = users;
notifyDataSetChanged();
}
public void setUsers(Cursor users) {
mUsers = users;
notifyDataSetChanged();
}
@Override
public int getCount() {
if (mUsers instanceof Cursor) {
final Cursor c = (Cursor) mUsers;
mScreenNameIdx = c.getColumnIndex(CachedUsers.SCREEN_NAME);
return c.getCount();
} else if (mUsers instanceof List) {
return ((List) mUsers).size();
}
return 0;
}
public void setAccountId(long accountId) {
mAccountId = accountId;
}
@Override
public ParcelableUser getItem(int position) {
if (mUsers instanceof Cursor) {
final Cursor c = (Cursor) mUsers;
return new ParcelableUser(c, mAccountId);
} else if (mUsers instanceof List) {
return (ParcelableUser) ((List) mUsers).get(position);
}
throw new IllegalStateException();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view;
if (convertView != null) {
view = convertView;
} else {
view = mInflater.inflate(R.layout.list_item_user, parent, false);
}
if (mUsers instanceof Cursor) {
final Cursor c = (Cursor) mUsers;
c.moveToPosition(position);
bindUser(view, c);
} else if (mUsers instanceof List) {
bindUser(view, getItem(position));
}
return view;
}
private void bindUser(View view, ParcelableUser user) {
}
private void bindUser(View view, Cursor cursor) {
}
}
} }

View File

@ -0,0 +1,110 @@
/*
* 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.fragment.support;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implements
DialogInterface.OnClickListener {
public static final String FRAGMENT_TAG = "retweet_quote";
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
final ParcelableStatus status = getStatus();
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (status == null || twitter == null) return;
if (isMyRetweet(status)) {
twitter.destroyStatusAsync(status.account_id, status.retweet_id);
} else {
twitter.retweetStatusAsync(status.account_id, status.id);
}
break;
default:
break;
}
}
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
final Context context = builder.getContext();
final ImageLoaderWrapper loader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress);
final LayoutInflater inflater = LayoutInflater.from(context);
@SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.dialog_scrollable_status, null);
final StatusViewHolder holder = new StatusViewHolder(view.findViewById(R.id.item_content));
final ParcelableStatus status = getStatus();
builder.setView(view);
builder.setTitle(R.string.retweet_quote_confirm_title);
builder.setPositiveButton(isMyRetweet(status) ? R.string.cancel_retweet : R.string.retweet, this);
builder.setNeutralButton(R.string.quote, this);
builder.setNegativeButton(android.R.string.cancel, null);
holder.displayStatus(context, loader, handler, getStatus());
view.findViewById(R.id.item_menu).setVisibility(View.GONE);
view.findViewById(R.id.action_buttons).setVisibility(View.GONE);
view.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);
return builder.create();
}
private ParcelableStatus getStatus() {
final Bundle args = getArguments();
if (!args.containsKey(EXTRA_STATUS)) return null;
return args.getParcelable(EXTRA_STATUS);
}
public static RetweetQuoteDialogFragment show(final FragmentManager fm, final ParcelableStatus status) {
final Bundle args = new Bundle();
args.putParcelable(EXTRA_STATUS, status);
final RetweetQuoteDialogFragment f = new RetweetQuoteDialogFragment();
f.setArguments(args);
f.show(fm, FRAGMENT_TAG);
return f;
}
}

View File

@ -123,12 +123,21 @@ public class StatusFragment extends BaseSupportFragment
private static final int LOADER_ID_DETAIL_STATUS = 1; private static final int LOADER_ID_DETAIL_STATUS = 1;
private static final int LOADER_ID_STATUS_REPLIES = 2; private static final int LOADER_ID_STATUS_REPLIES = 2;
private static final int STATE_LOADED = 1;
private static final int STATE_LOADING = 2;
private static final int STATE_ERROR = 3;
private RecyclerView mRecyclerView; private RecyclerView mRecyclerView;
private StatusAdapter mStatusAdapter; private StatusAdapter mStatusAdapter;
private boolean mRepliesLoaderInitialized; private boolean mRepliesLoaderInitialized;
private LoadConversationTask mLoadConversationTask; private LoadConversationTask mLoadConversationTask;
private LinearLayoutManager mLayoutManager;
private View mStatusContent;
private View mProgressContainer;
private View mErrorContainer;
private LoaderCallbacks<List<ParcelableStatus>> mRepliesLoaderCallback = new LoaderCallbacks<List<ParcelableStatus>>() { private LoaderCallbacks<List<ParcelableStatus>> mRepliesLoaderCallback = new LoaderCallbacks<List<ParcelableStatus>>() {
@Override @Override
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) { public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
@ -153,7 +162,6 @@ public class StatusFragment extends BaseSupportFragment
} }
}; };
private LinearLayoutManager mLayoutManager;
@Override @Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
@ -214,12 +222,14 @@ public class StatusFragment extends BaseSupportFragment
mStatusAdapter = new StatusAdapter(this, compact); mStatusAdapter = new StatusAdapter(this, compact);
mRecyclerView.setAdapter(mStatusAdapter); mRecyclerView.setAdapter(mStatusAdapter);
setState(STATE_LOADING);
getLoaderManager().initLoader(LOADER_ID_DETAIL_STATUS, getArguments(), this); getLoaderManager().initLoader(LOADER_ID_DETAIL_STATUS, getArguments(), this);
} }
@Override @Override
public void onMediaClick(View view, ParcelableMedia media) { public void onMediaClick(View view, ParcelableMedia media, long accountId) {
Utils.openImageDirectly(getActivity(), accountId, media.url);
} }
@Override @Override
@ -240,15 +250,26 @@ public class StatusFragment extends BaseSupportFragment
final int position = mStatusAdapter.findPositionById(itemId); final int position = mStatusAdapter.findPositionById(itemId);
mLayoutManager.scrollToPositionWithOffset(position, top); mLayoutManager.scrollToPositionWithOffset(position, top);
} }
setState(STATE_LOADED);
} else { } else {
//TODO show errors //TODO show errors
setState(STATE_ERROR);
} }
} }
private void setState(int state) {
mStatusContent.setVisibility(state == STATE_LOADED ? View.VISIBLE : View.GONE);
mProgressContainer.setVisibility(state == STATE_LOADING ? View.VISIBLE : View.GONE);
mErrorContainer.setVisibility(state == STATE_ERROR ? View.VISIBLE : View.GONE);
}
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
mStatusContent = view.findViewById(R.id.status_content);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
mProgressContainer = view.findViewById(R.id.progress_container);
mErrorContainer = view.findViewById(R.id.error_retry_container);
} }
@Override @Override
@ -318,12 +339,13 @@ public class StatusFragment extends BaseSupportFragment
private static final int VIEW_TYPE_SPACE = 4; private static final int VIEW_TYPE_SPACE = 4;
private final Context mContext; private final Context mContext;
private final StatusFragment mFragment;
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private final ImageLoaderWrapper mImageLoader; private final ImageLoaderWrapper mImageLoader;
private final boolean mNameFirst, mNicknameOnly; private final boolean mNameFirst, mNicknameOnly;
private final int mCardLayoutResource; private final int mCardLayoutResource;
private final StatusFragment mFragment; private final int mTextSize;
private ParcelableStatus mStatus; private ParcelableStatus mStatus;
@ -332,6 +354,7 @@ public class StatusFragment extends BaseSupportFragment
public StatusAdapter(StatusFragment fragment, boolean compact) { public StatusAdapter(StatusFragment fragment, boolean compact) {
final Context context = fragment.getActivity(); final Context context = fragment.getActivity();
final Resources res = context.getResources();
final SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, final SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE); Context.MODE_PRIVATE);
mFragment = fragment; mFragment = fragment;
@ -340,6 +363,7 @@ public class StatusFragment extends BaseSupportFragment
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper(); mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true); mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, true); mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, true);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size));
if (compact) { if (compact) {
mCardLayoutResource = R.layout.card_item_status_compat; mCardLayoutResource = R.layout.card_item_status_compat;
} else { } else {
@ -390,6 +414,10 @@ public class StatusFragment extends BaseSupportFragment
return getConversationCount() + 1 + getRepliesCount() + 1; return getConversationCount() + 1 + getRepliesCount() + 1;
} }
public int getTextSize() {
return mTextSize;
}
@Override @Override
public void onStatusClick(StatusViewHolder holder, int position) { public void onStatusClick(StatusViewHolder holder, int position) {
openStatus(mFragment.getActivity(), getStatus(position), null); openStatus(mFragment.getActivity(), getStatus(position), null);
@ -603,11 +631,10 @@ public class StatusFragment extends BaseSupportFragment
} }
} }
private static class DetailStatusViewHolder extends ViewHolder implements OnClickListener, OnMediaClickListener, OnMenuItemClickListener { private static class DetailStatusViewHolder extends ViewHolder implements OnClickListener, OnMenuItemClickListener {
private final StatusAdapter adapter; private final StatusAdapter adapter;
private final View cardContent, progressContainer;
private final CardView cardView; private final CardView cardView;
private final TwidereMenuBar menuBar; private final TwidereMenuBar menuBar;
@ -631,8 +658,6 @@ public class StatusFragment extends BaseSupportFragment
super(itemView); super(itemView);
this.adapter = adapter; this.adapter = adapter;
cardView = (CardView) itemView.findViewById(R.id.card); cardView = (CardView) itemView.findViewById(R.id.card);
cardContent = itemView.findViewById(R.id.card_content);
progressContainer = itemView.findViewById(R.id.progress_container);
menuBar = (TwidereMenuBar) itemView.findViewById(R.id.menu_bar); menuBar = (TwidereMenuBar) itemView.findViewById(R.id.menu_bar);
nameView = (TextView) itemView.findViewById(R.id.name); nameView = (TextView) itemView.findViewById(R.id.name);
screenNameView = (TextView) itemView.findViewById(R.id.screen_name); screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
@ -702,7 +727,7 @@ public class StatusFragment extends BaseSupportFragment
} else { } else {
final long id_to_retweet = status.is_retweet && status.retweet_id > 0 ? status.retweet_id final long id_to_retweet = status.is_retweet && status.retweet_id > 0 ? status.retweet_id
: status.id; : status.id;
twitter.retweetStatus(status.account_id, id_to_retweet); twitter.retweetStatusAsync(status.account_id, id_to_retweet);
} }
break; break;
} }
@ -789,7 +814,6 @@ public class StatusFragment extends BaseSupportFragment
public void showStatus(ParcelableStatus status) { public void showStatus(ParcelableStatus status) {
if (status == null) return; if (status == null) return;
progressContainer.setVisibility(View.GONE);
final Context context = adapter.getContext(); final Context context = adapter.getContext();
final Resources resources = context.getResources(); final Resources resources = context.getResources();
final ImageLoaderWrapper loader = adapter.getImageLoader(); final ImageLoaderWrapper loader = adapter.getImageLoader();
@ -857,7 +881,7 @@ public class StatusFragment extends BaseSupportFragment
mediaPreviewGrid.removeAllViews(); mediaPreviewGrid.removeAllViews();
final int maxColumns = resources.getInteger(R.integer.grid_column_image_preview); final int maxColumns = resources.getInteger(R.integer.grid_column_image_preview);
MediaPreviewUtils.addToLinearLayout(mediaPreviewGrid, loader, status.media, MediaPreviewUtils.addToLinearLayout(mediaPreviewGrid, loader, status.media,
maxColumns, this); status.account_id, maxColumns, adapter.getFragment());
} else { } else {
mediaPreviewContainer.setVisibility(View.VISIBLE); mediaPreviewContainer.setVisibility(View.VISIBLE);
mediaPreviewLoad.setVisibility(View.VISIBLE); mediaPreviewLoad.setVisibility(View.VISIBLE);
@ -868,17 +892,17 @@ public class StatusFragment extends BaseSupportFragment
menuBar.show(); menuBar.show();
} }
@Override
public void onMediaClick(View view, ParcelableMedia media) {
adapter.mFragment.onMediaClick(view, media);
}
private void initViews() { private void initViews() {
menuBar.setOnMenuItemClickListener(this); menuBar.setOnMenuItemClickListener(this);
menuBar.inflate(R.menu.menu_status); menuBar.inflate(R.menu.menu_status);
mediaPreviewLoad.setOnClickListener(this); mediaPreviewLoad.setOnClickListener(this);
profileContainer.setOnClickListener(this); profileContainer.setOnClickListener(this);
final int defaultTextSize = adapter.getTextSize();
nameView.setTextSize(defaultTextSize * 1.25f);
textView.setTextSize(defaultTextSize * 1.25f);
screenNameView.setTextSize(defaultTextSize * 0.85f);
timeSourceView.setTextSize(defaultTextSize * 0.85f);
} }

View File

@ -645,7 +645,7 @@ public class StatusFragmentOld extends ParcelableStatusesListFragment implements
} }
@Override @Override
public void onMediaClick(final View view, final ParcelableMedia media) { public void onMediaClick(final View view, final ParcelableMedia media, long accountId) {
final ParcelableStatus status = mStatus; final ParcelableStatus status = mStatus;
if (status == null) return; if (status == null) return;
// UCD // UCD
@ -756,7 +756,7 @@ public class StatusFragmentOld extends ParcelableStatusesListFragment implements
} else { } else {
final long id_to_retweet = status.is_retweet && status.retweet_id > 0 ? status.retweet_id final long id_to_retweet = status.is_retweet && status.retweet_id > 0 ? status.retweet_id
: status.id; : status.id;
mTwitterWrapper.retweetStatus(status.account_id, id_to_retweet); mTwitterWrapper.retweetStatusAsync(status.account_id, id_to_retweet);
} }
break; break;
} }
@ -905,13 +905,15 @@ public class StatusFragmentOld extends ParcelableStatusesListFragment implements
} }
private void loadPreviewImages() { private void loadPreviewImages() {
if (mStatus == null) return; final ParcelableStatus status = mStatus;
if (status == null) return;
mLoadImagesIndicator.setVisibility(View.GONE); mLoadImagesIndicator.setVisibility(View.GONE);
mImagePreviewGrid.setVisibility(View.VISIBLE); mImagePreviewGrid.setVisibility(View.VISIBLE);
mImagePreviewGrid.removeAllViews(); mImagePreviewGrid.removeAllViews();
if (mStatus.media != null) { if (mStatus.media != null) {
final int maxColumns = getResources().getInteger(R.integer.grid_column_image_preview); final int maxColumns = getResources().getInteger(R.integer.grid_column_image_preview);
MediaPreviewUtils.addToLinearLayout(mImagePreviewGrid, mImageLoader, mStatus.media, maxColumns, this); MediaPreviewUtils.addToLinearLayout(mImagePreviewGrid, mImageLoader, status.media,
status.account_id, maxColumns, this);
} }
} }

View File

@ -357,7 +357,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mProgressContainer.setVisibility(View.GONE); mProgressContainer.setVisibility(View.GONE);
mUser = user; mUser = user;
final int userColor = getUserColor(getActivity(), user.id, true); final int userColor = getUserColor(getActivity(), user.id, true);
mProfileImageView.setBorderColor(userColor != 0 ? userColor : Color.WHITE); mProfileImageView.setBorderColor(userColor);
mProfileNameContainer.drawEnd(getAccountColor(getActivity(), user.account_id)); mProfileNameContainer.drawEnd(getAccountColor(getActivity(), user.account_id));
final String nick = getUserNickname(getActivity(), user.id, true); final String nick = getUserNickname(getActivity(), user.id, true);
mNameView mNameView
@ -374,7 +374,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mDescriptionContainer.setVisibility(userIsMe || !isEmpty(user.description_html) ? View.VISIBLE : View.GONE); mDescriptionContainer.setVisibility(userIsMe || !isEmpty(user.description_html) ? View.VISIBLE : View.GONE);
mDescriptionView.setText(user.description_html != null ? Html.fromHtml(user.description_html) : null); mDescriptionView.setText(user.description_html != null ? Html.fromHtml(user.description_html) : null);
final TwidereLinkify linkify = new TwidereLinkify(this); final TwidereLinkify linkify = new TwidereLinkify(this);
linkify.setLinkTextColor(ThemeUtils.getUserLinkTextColor(getActivity())); linkify.setLinkTextColor(user.link_color);
linkify.applyAllLinks(mDescriptionView, user.account_id, false); linkify.applyAllLinks(mDescriptionView, user.account_id, false);
mDescriptionView.setMovementMethod(null); mDescriptionView.setMovementMethod(null);
mLocationContainer.setVisibility(userIsMe || !isEmpty(user.location) ? View.VISIBLE : View.GONE); mLocationContainer.setVisibility(userIsMe || !isEmpty(user.location) ? View.VISIBLE : View.GONE);
@ -382,6 +382,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mURLContainer.setVisibility(userIsMe || !isEmpty(user.url) || !isEmpty(user.url_expanded) ? View.VISIBLE mURLContainer.setVisibility(userIsMe || !isEmpty(user.url) || !isEmpty(user.url_expanded) ? View.VISIBLE
: View.GONE); : View.GONE);
mURLView.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded); mURLView.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded);
mURLView.setLinkTextColor(user.link_color);
mURLView.setMovementMethod(null); mURLView.setMovementMethod(null);
final String createdAt = formatToLongTimeString(getActivity(), user.created_at); final String createdAt = formatToLongTimeString(getActivity(), user.created_at);
final float daysSinceCreated = (System.currentTimeMillis() - user.created_at) / 1000 / 60 / 60 / 24; final float daysSinceCreated = (System.currentTimeMillis() - user.created_at) / 1000 / 60 / 60 / 24;
@ -700,6 +701,15 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
break; break;
} }
case R.id.follow: { case R.id.follow: {
if (user.id == user.account_id) {
final Bundle extras = new Bundle();
extras.putLong(EXTRA_ACCOUNT_ID, user.account_id);
final Intent intent = new Intent(INTENT_ACTION_EDIT_USER_PROFILE);
intent.setClass(getActivity(), UserProfileEditorActivity.class);
intent.putExtras(extras);
startActivity(intent);
break;
}
final Relationship relationship = mRelationship; final Relationship relationship = mRelationship;
final AsyncTwitterWrapper twitter = getTwitterWrapper(); final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (relationship == null || twitter == null) return; if (relationship == null || twitter == null) return;
@ -988,15 +998,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
startActivityForResult(intent, REQUEST_SELECT_ACCOUNT); startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
break; break;
} }
case MENU_EDIT: {
final Bundle extras = new Bundle();
extras.putLong(EXTRA_ACCOUNT_ID, user.account_id);
final Intent intent = new Intent(INTENT_ACTION_EDIT_USER_PROFILE);
intent.setClass(getActivity(), UserProfileEditorActivity.class);
intent.putExtras(extras);
startActivity(intent);
return true;
}
case MENU_FOLLOW: { case MENU_FOLLOW: {
if (relationship == null) return false; if (relationship == null) return false;
final boolean isFollowing = relationship.isSourceFollowingTarget(); final boolean isFollowing = relationship.isSourceFollowingTarget();
@ -1067,7 +1068,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final Relationship relationship = mRelationship; final Relationship relationship = mRelationship;
if (twitter == null || user == null) return; if (twitter == null || user == null) return;
final boolean isMyself = user.account_id == user.id; final boolean isMyself = user.account_id == user.id;
setMenuItemAvailability(menu, MENU_EDIT, isMyself);
final MenuItem mentionItem = menu.findItem(MENU_MENTION); final MenuItem mentionItem = menu.findItem(MENU_MENTION);
if (mentionItem != null) { if (mentionItem != null) {
mentionItem.setTitle(getString(R.string.mention_user_name, getDisplayName(getActivity(), user))); mentionItem.setTitle(getString(R.string.mention_user_name, getDisplayName(getActivity(), user)));

View File

@ -136,8 +136,8 @@ public class CardPreviewPreference extends Preference implements Constants, OnSh
@Override @Override
protected View onCreateView(final ViewGroup parent) { protected View onCreateView(final ViewGroup parent) {
if (mPreferences != null && mPreferences.getBoolean(KEY_COMPACT_CARDS, false)) if (mPreferences != null && mPreferences.getBoolean(KEY_COMPACT_CARDS, false))
return mInflater.inflate(R.layout.card_item_status_compact_deprecated, parent, false); return mInflater.inflate(R.layout.list_item_status_compact_deprecated, parent, false);
return mInflater.inflate(R.layout.card_item_status_deprecated, parent, false); return mInflater.inflate(R.layout.list_item_status_deprecated, parent, false);
} }
} }

View File

@ -104,7 +104,7 @@ public class ThemePreviewPreference extends Preference implements Constants, OnS
if (statusContentView != null) { if (statusContentView != null) {
ViewAccessor.setBackground(statusContentView, ThemeUtils.getWindowBackground(context)); ViewAccessor.setBackground(statusContentView, ThemeUtils.getWindowBackground(context));
final View profileView = statusContentView.findViewById(R.id.profile); final View profileView = statusContentView.findViewById(R.id.profile_container);
final ImageView profileImageView = (ImageView) statusContentView.findViewById(R.id.profile_image); final ImageView profileImageView = (ImageView) statusContentView.findViewById(R.id.profile_image);
final TextView nameView = (TextView) statusContentView.findViewById(R.id.name); final TextView nameView = (TextView) statusContentView.findViewById(R.id.name);
final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name); final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name);

View File

@ -366,7 +366,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return mAsyncTaskManager.add(task, true); return mAsyncTaskManager.add(task, true);
} }
public int retweetStatus(final long accountId, final long status_id) { public int retweetStatusAsync(final long accountId, final long status_id) {
final RetweetStatusTask task = new RetweetStatusTask(accountId, status_id); final RetweetStatusTask task = new RetweetStatusTask(accountId, status_id);
return mAsyncTaskManager.add(task, true); return mAsyncTaskManager.add(task, true);
} }

View File

@ -194,8 +194,8 @@ public class MediaPreviewUtils {
private static final String URL_PHOTOZOU_PHOTO_INFO = "https://api.photozou.jp/rest/photo_info.json"; private static final String URL_PHOTOZOU_PHOTO_INFO = "https://api.photozou.jp/rest/photo_info.json";
public static void addToLinearLayout(final LinearLayout container, final ImageLoaderWrapper loader, public static void addToLinearLayout(final LinearLayout container, final ImageLoaderWrapper loader,
final List<ParcelableMedia> mediaList, final int maxColumnCount, final List<ParcelableMedia> mediaList, final long accountId,
final OnMediaClickListener mediaClickListener) { final int maxColumnCount, final OnMediaClickListener mediaClickListener) {
if (container.getOrientation() != LinearLayout.VERTICAL) if (container.getOrientation() != LinearLayout.VERTICAL)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
final Context context = container.getContext(); final Context context = container.getContext();
@ -207,7 +207,7 @@ public class MediaPreviewUtils {
final int bestColumnCount = imageCountSqrt % 1 == 0 ? (int) imageCountSqrt : maxColumnCount; final int bestColumnCount = imageCountSqrt % 1 == 0 ? (int) imageCountSqrt : maxColumnCount;
final int firstColumn = imageCount % bestColumnCount, fullRowCount = imageCount / bestColumnCount; final int firstColumn = imageCount % bestColumnCount, fullRowCount = imageCount / bestColumnCount;
final int rowCount = fullRowCount + (firstColumn > 0 ? 1 : 0); final int rowCount = fullRowCount + (firstColumn > 0 ? 1 : 0);
final View.OnClickListener clickListener = new ImageGridClickListener(mediaClickListener); final View.OnClickListener clickListener = new ImageGridClickListener(mediaClickListener, accountId);
container.setMotionEventSplittingEnabled(false); container.setMotionEventSplittingEnabled(false);
for (int currentRow = 0; currentRow < rowCount; currentRow++) { for (int currentRow = 0; currentRow < rowCount; currentRow++) {
final LinearLayout rowContainer = new LinearLayout(context); final LinearLayout rowContainer = new LinearLayout(context);
@ -233,9 +233,10 @@ public class MediaPreviewUtils {
} }
public static void addToLinearLayout(final LinearLayout container, final ImageLoaderWrapper loader, public static void addToLinearLayout(final LinearLayout container, final ImageLoaderWrapper loader,
final ParcelableMedia[] mediaArray, final int maxColumnCount, final ParcelableMedia[] mediaArray, final long accountId,
final OnMediaClickListener listener) { final int maxColumnCount, final OnMediaClickListener listener) {
addToLinearLayout(container, loader, Arrays.asList(mediaArray), maxColumnCount, listener); addToLinearLayout(container, loader, Arrays.asList(mediaArray), accountId, maxColumnCount,
listener);
} }
public static ParcelableMedia getAllAvailableImage(final String link, final boolean fullImage) { public static ParcelableMedia getAllAvailableImage(final String link, final boolean fullImage) {
@ -461,20 +462,22 @@ public class MediaPreviewUtils {
} }
public interface OnMediaClickListener { public interface OnMediaClickListener {
void onMediaClick(View view, ParcelableMedia media); void onMediaClick(View view, ParcelableMedia media, long accountId);
} }
private static class ImageGridClickListener implements View.OnClickListener { private static class ImageGridClickListener implements View.OnClickListener {
private final OnMediaClickListener mListener; private final OnMediaClickListener mListener;
private final long mAccountId;
ImageGridClickListener(final OnMediaClickListener listener) { ImageGridClickListener(final OnMediaClickListener listener, final long accountId) {
mListener = listener; mListener = listener;
mAccountId = accountId;
} }
@Override @Override
public void onClick(final View v) { public void onClick(final View v) {
if (mListener == null) return; if (mListener == null) return;
mListener.onMediaClick(v, (ParcelableMedia) v.getTag()); mListener.onMediaClick(v, (ParcelableMedia) v.getTag(), mAccountId);
} }
} }

View File

@ -93,7 +93,7 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
} }
protected void openLink(final String link) { protected void openLink(final String link) {
if (context == null || manager.isActive()) return; if (context == null || (manager != null && manager.isActive())) return;
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try { try {

View File

@ -36,8 +36,7 @@ import org.mariotaku.twidere.R;
*/ */
public class ActionIconTextView extends TextView { public class ActionIconTextView extends TextView {
private int mColor; private int mColor, mDisabledColor, mActivatedColor;
private int mActivatedColor;
public ActionIconTextView(Context context) { public ActionIconTextView(Context context) {
this(context, null); this(context, null);
@ -49,19 +48,18 @@ public class ActionIconTextView extends TextView {
public ActionIconTextView(Context context, AttributeSet attrs, int defStyleAttr) { public ActionIconTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
final TypedArray defaultValues = context.obtainStyledAttributes(
new int[]{android.R.attr.colorActivatedHighlight});
final int defaultActivatedColor = defaultValues.getColor(0, 0);
defaultValues.recycle();
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton);
mColor = a.getColor(R.styleable.IconActionButton_iabColor, 0); mColor = a.getColor(R.styleable.IconActionButton_iabColor, 0);
mActivatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, defaultActivatedColor); mDisabledColor = a.getColor(R.styleable.IconActionButton_iabDisabledColor, 0);
mActivatedColor = a.getColor(R.styleable.IconActionButton_iabActivatedColor, 0);
a.recycle(); a.recycle();
updateColorFilter();
} }
public int getActivatedColor() { public int getActivatedColor() {
return mActivatedColor; if (mActivatedColor != 0) return mActivatedColor;
final ColorStateList colors = getLinkTextColors();
if (colors != null) return colors.getDefaultColor();
return getCurrentTextColor();
} }
public int getColor() { public int getColor() {
@ -71,32 +69,46 @@ public class ActionIconTextView extends TextView {
return getCurrentTextColor(); return getCurrentTextColor();
} }
public int getDisabledColor() {
if (mDisabledColor != 0) return mDisabledColor;
final ColorStateList colors = getTextColors();
if (colors != null) return colors.getColorForState(new int[0], colors.getDefaultColor());
return getCurrentTextColor();
}
@Override @Override
public void setActivated(boolean activated) { public void setActivated(boolean activated) {
super.setActivated(activated); super.setActivated(activated);
updateColorFilter(); }
@Override
public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
super.setCompoundDrawables(left, top, right, bottom);
} }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override @Override
public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end, Drawable bottom) { public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end, Drawable bottom) {
super.setCompoundDrawablesRelative(start, top, end, bottom); super.setCompoundDrawablesRelative(start, top, end, bottom);
updateColorFilter();
} }
@Override @Override
public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { protected void drawableStateChanged() {
super.setCompoundDrawables(left, top, right, bottom); super.drawableStateChanged();
updateColorFilter();
}
private void updateColorFilter() {
for (Drawable d : getCompoundDrawables()) { for (Drawable d : getCompoundDrawables()) {
if (d != null) { if (d != null) {
d.mutate(); d.mutate();
d.setColorFilter(isActivated() ? getActivatedColor() : getColor(), Mode.SRC_ATOP); final int color;
if (isActivated()) {
color = getActivatedColor();
} else if (isEnabled()) {
color = getColor();
} else {
color = getDisabledColor();
}
d.setColorFilter(color, Mode.SRC_ATOP);
} }
} }
} }
} }

View File

@ -49,9 +49,6 @@ public class ComposeSelectAccountButton extends ViewGroup {
private final AccountIconsAdapter mAccountIconsAdapter; private final AccountIconsAdapter mAccountIconsAdapter;
private final Helper mColorLabelHelper; private final Helper mColorLabelHelper;
private OnClickListener mOnClickListener;
private OnLongClickListener mOnLongClickListener;
public ComposeSelectAccountButton(Context context) { public ComposeSelectAccountButton(Context context) {
this(context, null); this(context, null);
} }
@ -213,7 +210,11 @@ public class ComposeSelectAccountButton extends ViewGroup {
final int idx = findChildIndex(child); final int idx = findChildIndex(child);
if (firstVisibleItem < 1 && idx == 0) { if (firstVisibleItem < 1 && idx == 0) {
// when firstVisibleItem is 0 or -1, assume view with idx == 0 is first view // when firstVisibleItem is 0 or -1, assume view with idx == 0 is first view
layoutParams.leftMargin = 0; if (itemCount == 1) {
layoutParams.leftMargin = (contentWidth - contentHeight) / 2 - child.getPaddingLeft() - child.getPaddingRight();
} else {
layoutParams.leftMargin = 0;
}
} else { } else {
layoutParams.leftMargin = -Math.min((contentHeight * itemCount - contentWidth) layoutParams.leftMargin = -Math.min((contentHeight * itemCount - contentWidth)
/ (itemCount - 1) + child.getPaddingLeft() + child.getPaddingRight(), contentHeight); / (itemCount - 1) + child.getPaddingLeft() + child.getPaddingRight(), contentHeight);
@ -223,7 +224,15 @@ public class ComposeSelectAccountButton extends ViewGroup {
@Override @Override
public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) { public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
final int height = MeasureSpec.getSize(heightSpec), width = Math.round(height * 1.5f); final int height = MeasureSpec.getSize(heightSpec), width;
if (getItemCount() > 1) {
width = Math.round(height * 1.5f);
} else if (getChildCount() > 0) {
final View firstChild = getChildAt(0);
width = height + firstChild.getPaddingLeft() + firstChild.getPaddingRight();
} else {
width = height;
}
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
super.onMeasure(recycler, state, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); super.onMeasure(recycler, state, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec);

View File

@ -15,6 +15,7 @@ import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices; import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.UserColorNicknameUtils; import org.mariotaku.twidere.util.UserColorNicknameUtils;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CircularImageView; import org.mariotaku.twidere.view.CircularImageView;
@ -42,11 +43,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
private final View mediaPreviewContainer; private final View mediaPreviewContainer;
private final TextView replyCountView, retweetCountView, favoriteCountView; private final TextView replyCountView, retweetCountView, favoriteCountView;
public StatusViewHolder(View itemView) {
this(null, itemView);
}
public StatusViewHolder(IStatusesAdapter<?> adapter, View itemView) { public StatusViewHolder(IStatusesAdapter<?> adapter, View itemView) {
super(itemView); super(itemView);
this.adapter = adapter; this.adapter = adapter;
itemView.findViewById(R.id.item_content).setOnClickListener(this);
itemView.findViewById(R.id.menu).setOnClickListener(this);
profileImageView = (CircularImageView) itemView.findViewById(R.id.profile_image); profileImageView = (CircularImageView) itemView.findViewById(R.id.profile_image);
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type); profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
textView = (TextView) itemView.findViewById(R.id.text); textView = (TextView) itemView.findViewById(R.id.text);
@ -64,6 +68,11 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
favoriteCountView = (TextView) itemView.findViewById(R.id.favorite_count); favoriteCountView = (TextView) itemView.findViewById(R.id.favorite_count);
//TODO //TODO
// profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext())); // profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
}
public void setupViews() {
itemView.findViewById(R.id.item_content).setOnClickListener(this);
itemView.findViewById(R.id.item_menu).setOnClickListener(this);
itemView.setOnClickListener(this); itemView.setOnClickListener(this);
profileImageView.setOnClickListener(this); profileImageView.setOnClickListener(this);
@ -73,9 +82,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
favoriteCountView.setOnClickListener(this); favoriteCountView.setOnClickListener(this);
} }
public void displayStatus(ParcelableStatus status) { public void displayStatus(final ParcelableStatus status) {
final ImageLoaderWrapper loader = adapter.getImageLoader(); displayStatus(adapter.getContext(), adapter.getImageLoader(),
final Context context = adapter.getContext(); adapter.getImageLoadingHandler(), status);
}
public void displayStatus(final Context context, final ImageLoaderWrapper loader,
final ImageLoadingHandler handler, final ParcelableStatus status) {
final ParcelableMedia[] media = status.media; final ParcelableMedia[] media = status.media;
if (status.retweet_id > 0) { if (status.retweet_id > 0) {
@ -121,13 +134,9 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
if (media != null && media.length > 0) { if (media != null && media.length > 0) {
final ParcelableMedia firstMedia = media[0]; final ParcelableMedia firstMedia = media[0];
if (status.text_plain.codePointCount(0, status.text_plain.length()) == firstMedia.end) { textView.setText(status.text_unescaped);
textView.setText(status.text_unescaped.substring(0, firstMedia.start));
} else {
textView.setText(status.text_unescaped);
}
loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url, loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url,
status.account_id, adapter.getImageLoadingHandler()); status.account_id, handler);
mediaPreviewContainer.setVisibility(View.VISIBLE); mediaPreviewContainer.setVisibility(View.VISIBLE);
} else { } else {
loader.cancelDisplayTask(mediaPreviewView); loader.cancelDisplayTask(mediaPreviewView);
@ -228,14 +237,9 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
loader.displayProfileImage(profileImageView, user_profile_image_url); loader.displayProfileImage(profileImageView, user_profile_image_url);
if (media != null && media.length > 0) { if (media != null && media.length > 0) {
final String text_plain = cursor.getString(indices.text_plain); final String textUnescaped = cursor.getString(indices.text_unescaped);
final String text_unescaped = cursor.getString(indices.text_unescaped);
final ParcelableMedia firstMedia = media[0]; final ParcelableMedia firstMedia = media[0];
if (text_plain.codePointCount(0, text_plain.length()) == firstMedia.end) { textView.setText(textUnescaped);
textView.setText(text_unescaped.substring(0, firstMedia.start));
} else {
textView.setText(text_unescaped);
}
loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url, loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url,
account_id, adapter.getImageLoadingHandler()); account_id, adapter.getImageLoadingHandler());
mediaPreviewContainer.setVisibility(View.VISIBLE); mediaPreviewContainer.setVisibility(View.VISIBLE);
@ -288,7 +292,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
adapter.onStatusClick(this, position); adapter.onStatusClick(this, position);
break; break;
} }
case R.id.menu: { case R.id.item_menu: {
adapter.onItemMenuClick(this, position); adapter.onItemMenuClick(this, position);
break; break;
} }
@ -296,7 +300,9 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
adapter.onUserProfileClick(this, position); adapter.onUserProfileClick(this, position);
break; break;
} }
case R.id.reply_count: { case R.id.reply_count:
case R.id.retweet_count:
case R.id.favorite_count: {
adapter.onItemActionClick(this, v.getId(), position); adapter.onItemActionClick(this, v.getId(), position);
break; break;
} }

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeActionButton <org.mariotaku.twidere.view.HomeActionButton
android:id="@+id/actions_button" android:id="@+id/action_buttons"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/float_action_button_size" android:layout_width="@dimen/float_action_button_size"
android:layout_height="@dimen/float_action_button_size" android:layout_height="@dimen/float_action_button_size"

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:layout_height="?android:actionBarSize">
<Spinner
android:id="@+id/account_spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0"
tools:listitem="@layout/spinner_item_account_icon"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="@dimen/element_spacing_small">
<EditText
android:id="@+id/user_query"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:gravity="bottom"
android:inputType="textPersonName"/>
<org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/query_button"
style="?cardActionButtonStyle"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_gravity="right"
android:padding="@dimen/element_spacing_normal"
android:scaleType="centerInside"
android:src="@drawable/ic_action_search"/>
</FrameLayout>
</LinearLayout>

View File

@ -13,220 +13,6 @@
app:cardCornerRadius="2dp" app:cardCornerRadius="2dp"
app:cardElevation="2dp"> app:cardElevation="2dp">
<RelativeLayout <include layout="@layout/card_item_status_common"/>
android:id="@+id/item_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="vertical">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/retweet_profile_image"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_marginBottom="@dimen/element_spacing_small"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_small"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/reply_retweet_status"
android:layout_width="match_parent"
android:layout_height="@dimen/element_size_small"
android:layout_marginBottom="@dimen/element_spacing_minus_normal"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_small"
android:layout_toRightOf="@id/retweet_profile_image"
android:ellipsize="end"
android:gravity="center_vertical"
android:minHeight="@dimen/element_size_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="10sp"/>
<RelativeLayout
android:id="@+id/profile_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/retweet_profile_image"
android:layout_below="@id/reply_retweet_status"
android:layout_marginTop="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_mlarge">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_status_profile_image"
android:layout_height="@dimen/icon_size_status_profile_image"
android:layout_centerVertical="true"
android:layout_margin="@dimen/element_spacing_small"
android:contentDescription="@string/profile_image"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/profile_type"
android:layout_width="@dimen/icon_size_profile_type"
android:layout_height="@dimen/icon_size_profile_type"
android:layout_alignBottom="@id/profile_image"
android:layout_alignRight="@id/profile_image"
android:scaleType="fitCenter"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_toLeftOf="@+id/menu"
android:layout_toRightOf="@id/profile_image"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/element_spacing_xsmall"
android:layout_marginTop="@dimen/element_spacing_small"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
android:textSize="10sp"/>
</LinearLayout>
<org.mariotaku.twidere.view.ShortTimeView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/element_spacing_small"
android:paddingTop="@dimen/element_spacing_xsmall"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textSize="10sp"/>
</LinearLayout>
<org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/menu"
style="?cardActionButtonStyle"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_action_more_vertical"/>
</RelativeLayout>
<org.mariotaku.twidere.view.ImagePreviewContainer
android:id="@+id/media_preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/profile_container"
android:layout_marginTop="@dimen/element_spacing_normal"
android:foreground="?android:selectableItemBackground">
<ImageView
android:id="@+id/media_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/media"
android:scaleType="centerCrop"/>
<ProgressBar
android:id="@+id/media_preview_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_large"/>
</org.mariotaku.twidere.view.ImagePreviewContainer>
<org.mariotaku.twidere.view.HandleSpanClickTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/media_preview_container"
android:layout_marginBottom="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"/>
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@+id/text"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_reply"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_reply"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_retweet"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_retweet"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_star"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_favorite"/>
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>

View File

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/item_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="vertical">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/retweet_profile_image"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_marginBottom="@dimen/element_spacing_small"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_small"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/reply_retweet_status"
android:layout_width="match_parent"
android:layout_height="@dimen/element_size_small"
android:layout_marginBottom="@dimen/element_spacing_minus_normal"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_small"
android:layout_toRightOf="@id/retweet_profile_image"
android:ellipsize="end"
android:gravity="center_vertical"
android:minHeight="@dimen/element_size_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="10sp"/>
<RelativeLayout
android:id="@+id/profile_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/retweet_profile_image"
android:layout_below="@id/reply_retweet_status"
android:layout_marginTop="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_mlarge">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_status_profile_image"
android:layout_height="@dimen/icon_size_status_profile_image"
android:layout_centerVertical="true"
android:layout_margin="@dimen/element_spacing_small"
android:contentDescription="@string/profile_image"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/profile_type"
android:layout_width="@dimen/icon_size_profile_type"
android:layout_height="@dimen/icon_size_profile_type"
android:layout_alignBottom="@id/profile_image"
android:layout_alignRight="@id/profile_image"
android:scaleType="fitCenter"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_toLeftOf="@+id/item_menu"
android:layout_toRightOf="@id/profile_image"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/element_spacing_xsmall"
android:layout_marginTop="@dimen/element_spacing_small"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
android:textSize="10sp"/>
</LinearLayout>
<org.mariotaku.twidere.view.ShortTimeView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/element_spacing_small"
android:paddingTop="@dimen/element_spacing_xsmall"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textSize="10sp"/>
</LinearLayout>
<org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/item_menu"
style="?cardActionButtonStyle"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_action_more_vertical"/>
</RelativeLayout>
<org.mariotaku.twidere.view.ImagePreviewContainer
android:id="@+id/media_preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/profile_container"
android:layout_marginTop="@dimen/element_spacing_normal"
android:foreground="?android:selectableItemBackground">
<ImageView
android:id="@+id/media_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/media"
android:scaleType="centerCrop"/>
<ProgressBar
android:id="@+id/media_preview_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_large"/>
</org.mariotaku.twidere.view.ImagePreviewContainer>
<org.mariotaku.twidere.view.HandleSpanClickTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/media_preview_container"
android:layout_marginBottom="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"/>
<HorizontalScrollView
android:id="@+id/action_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@+id/text"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_reply"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_reply"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_retweet"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_retweet"/>
<org.mariotaku.twidere.view.ActionIconTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_star"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_favorite"/>
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
</merge>

View File

@ -199,11 +199,11 @@
<Space <Space
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/menu" android:layout_toLeftOf="@+id/item_menu"
android:layout_toRightOf="@+id/actions_scroller"/> android:layout_toRightOf="@+id/actions_scroller"/>
<org.mariotaku.twidere.view.ActionIconButton <org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/menu" android:id="@+id/item_menu"
style="?cardActionButtonStyle" style="?cardActionButtonStyle"
android:layout_width="@dimen/button_size_content_card" android:layout_width="@dimen/button_size_content_card"
android:layout_height="@dimen/button_size_content_card" android:layout_height="@dimen/button_size_content_card"

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView
android:id="@+id/status_container" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:id="@+id/status_container"
android:layout_height="wrap_content"> android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/card_item_status_deprecated"/> <include layout="@layout/card_item_status_common"/>
</ScrollView> </ScrollView>

View File

@ -1,65 +1,63 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout
xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent" android:layout_width="match_parent"
tools:context=".fragment.DirectMessagesConversationFragment"> android:layout_height="match_parent"
tools:context=".fragment.DirectMessagesConversationFragment">
<RelativeLayout <LinearLayout
android:id="@+id/conversation_container" android:id="@+id/conversation_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone"> android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<FrameLayout <FrameLayout
android:id="@+id/list_container" android:id="@+id/list_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_above="@+id/input_send_container"/> android:layout_weight="1">
<FrameLayout <ListView
android:id="@+id/input_send_container" android:id="@android:id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"/>
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<LinearLayout </FrameLayout>
android:id="@+id/recipient_selector_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout <FrameLayout
android:layout_width="300dp" android:id="@+id/input_send_container"
android:layout_height="0dp" android:layout_width="match_parent"
android:layout_gravity="center" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0">
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<Spinner <include layout="@layout/fragment_messages_conversation_input_send"/>
android:id="@+id/account_selector" </FrameLayout>
android:layout_width="match_parent" </LinearLayout>
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeightSmall"
android:padding="@dimen/element_spacing_normal"
tools:listitem="@layout/list_item_two_line_small"/>
<TextView <FrameLayout
android:id="@+id/recipient_selector" android:id="@+id/recipient_selector_container"
style="?android:dropDownSpinnerStyle" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="wrap_content" android:visibility="visible"
android:clickable="true" tools:visibility="gone">
android:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeightSmall" <ListView
android:padding="@dimen/element_spacing_normal" android:id="@+id/users_search_list"
android:text="@string/select_user" android:layout_width="match_parent"
android:textAppearance="?android:textAppearanceMedium"/> android:layout_height="match_parent"
</LinearLayout> android:scrollbarStyle="outsideInset"
</LinearLayout> android:padding="@dimen/element_spacing_normal"/>
<ProgressBar
android:id="@+id/users_search_progress"
style="?android:progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
</FrameLayout>
</FrameLayout> </FrameLayout>

View File

@ -25,25 +25,29 @@
android:descendantFocusability="beforeDescendants" android:descendantFocusability="beforeDescendants"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<requestFocus/>
</android.support.v7.widget.RecyclerView>
<RelativeLayout <RelativeLayout
android:id="@+id/status_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:visibility="gone"> android:visibility="gone">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<requestFocus/>
</android.support.v7.widget.RecyclerView>
<org.mariotaku.twidere.view.themed.ThemedMultiAutoCompleteTextView <org.mariotaku.twidere.view.themed.ThemedMultiAutoCompleteTextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
</RelativeLayout> </RelativeLayout>
<include layout="@layout/layout_content_fragment_common"/>
</FrameLayout> </FrameLayout>

View File

@ -296,6 +296,5 @@
</LinearLayout> </LinearLayout>
<include layout="@layout/layout_content_fragment_common"/>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>
</FrameLayout> </FrameLayout>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeActionButtonCompat <org.mariotaku.twidere.view.HomeActionButtonCompat
android:id="@+id/actions_button" android:id="@+id/action_buttons"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeightSmall"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.CircularImageView
android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small"
android:contentDescription="@string/icon"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/element_spacing_small">
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<org.mariotaku.twidere.view.SquareFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tools:layout_height="?android:actionBarSize"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.CircularImageView
android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small"
android:layout_gravity="center"
android:contentDescription="@string/profile_image"
android:scaleType="centerCrop"
tools:src="@drawable/ic_profile_image_default"/>
</org.mariotaku.twidere.view.SquareFrameLayout>

View File

@ -4,6 +4,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/card_item_status_deprecated"/> <include layout="@layout/list_item_status_deprecated"/>
</LinearLayout> </LinearLayout>

View File

@ -1,12 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/edit"
android:icon="@drawable/ic_action_edit"
android:showAsAction="always"
android:title="@string/edit_profile"
android:visible="false"/>
<item <item
android:id="@id/mention" android:id="@id/mention"
android:icon="@drawable/ic_action_at" android:icon="@drawable/ic_action_at"

View File

@ -6,6 +6,7 @@
<attr name="profileImageStyle" format="reference"/> <attr name="profileImageStyle" format="reference"/>
<attr name="profileImageStyleLarge" format="reference"/> <attr name="profileImageStyleLarge" format="reference"/>
<attr name="menuIconColor" format="color"/> <attr name="menuIconColor" format="color"/>
<attr name="menuIconColorDisabled" format="color"/>
<attr name="menuIconColorActionBar" format="color"/> <attr name="menuIconColorActionBar" format="color"/>
<attr name="messageBubbleColor" format="color"/> <attr name="messageBubbleColor" format="color"/>
<attr name="cardItemBackground" format="reference"/> <attr name="cardItemBackground" format="reference"/>
@ -75,6 +76,7 @@
<declare-styleable name="IconActionButton"> <declare-styleable name="IconActionButton">
<attr name="iabColor" format="color"/> <attr name="iabColor" format="color"/>
<attr name="iabActivatedColor" format="color"/> <attr name="iabActivatedColor" format="color"/>
<attr name="iabDisabledColor" format="color"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="CircularImageView"> <declare-styleable name="CircularImageView">
<attr name="civBorder" format="boolean"/> <attr name="civBorder" format="boolean"/>

View File

@ -687,5 +687,6 @@
<string name="profile_text_color">Text color</string> <string name="profile_text_color">Text color</string>
<string name="profile_background_color">Background color</string> <string name="profile_background_color">Background color</string>
<string name="profile_link_color_main_color">Link color (main color)</string> <string name="profile_link_color_main_color">Link color (main color)</string>
<string name="retweet_quote_confirm_title">Retweet to your followers?</string>
</resources> </resources>

View File

@ -109,15 +109,6 @@
<style name="TextAppearance.TabPageIndicator" parent="android:TextAppearance.Small"/> <style name="TextAppearance.TabPageIndicator" parent="android:TextAppearance.Small"/>
<style name="SwipeBackLayout">
<item name="edgeSize">16dip</item>
<item name="shadowLeft">@drawable/shadow_left</item>
<item name="shadowRight">@drawable/shadow_right</item>
<item name="shadowBottom">@drawable/shadow_bottom</item>
<item name="scalePercent">@fraction/swipeback_scale_exit</item>
<item name="scrimAlpha">0.75</item>
</style>
<style name="Widget.CardItemView" parent="Widget.Base"> <style name="Widget.CardItemView" parent="Widget.Base">
<item name="cardBackground">?cardItemBackground</item> <item name="cardBackground">?cardItemBackground</item>
<item name="cardBackgroundAlpha">50%p</item> <item name="cardBackgroundAlpha">50%p</item>

View File

@ -104,6 +104,7 @@
<!-- Twidere specific styles --> <!-- Twidere specific styles -->
<item name="menuIconColor">@color/action_icon_dark</item> <item name="menuIconColor">@color/action_icon_dark</item>
<item name="menuIconColorDisabled">@color/action_icon_dark_disabled</item>
<item name="menuIconColorActionBar">@color/action_icon_light</item> <item name="menuIconColorActionBar">@color/action_icon_light</item>
<item name="messageBubbleColor">@color/message_bubble_color_light</item> <item name="messageBubbleColor">@color/message_bubble_color_light</item>
</style> </style>