updated build tools version
This commit is contained in:
Mariotaku Lee 2015-03-11 22:15:32 +08:00
parent 511b1abf38
commit 880deb116b
38 changed files with 507 additions and 540 deletions

View File

@ -21,4 +21,5 @@ allprojects {
jcenter()
mavenCentral()
}
}

0
build.properties Normal file
View File

22
global.gradle Normal file
View File

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

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -196,10 +196,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
public static final String TASK_TAG_GET_SENT_DIRECT_MESSAGES = "get_sent_direct_messages";
public static final String TASK_TAG_GET_RECEIVED_DIRECT_MESSAGES = "get_received_direct_messages";
public static final String TASK_TAG_GET_TRENDS = "get_trends";
public static final String TASK_TAG_STORE_HOME_TIMELINE = "store_home_tomeline";
public static final String TASK_TAG_STORE_MENTIONS = "store_mentions";
public static final String TASK_TAG_STORE_SENT_DIRECT_MESSAGES = "store_sent_direct_messages";
public static final String TASK_TAG_STORE_RECEIVED_DIRECT_MESSAGES = "store_received_direct_messages";
public static final String TASK_TAG_STORE_TRENDS = "store_trends";
public static final String SERVICE_COMMAND_REFRESH_ALL = "refresh_all";

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -18,12 +18,10 @@
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.twidere.donate.nyanwp"
minSdkVersion 20

View File

@ -18,12 +18,10 @@
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.twidere.donate.nyanwp"
minSdkVersion 14

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.twidere.extension.push.xiaomi"
minSdkVersion 14

View File

@ -18,12 +18,10 @@
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.twidere.extension.streaming"
minSdkVersion 14

View File

@ -18,12 +18,10 @@
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.extension.twitlonger"
minSdkVersion 14

View File

@ -18,11 +18,9 @@
*/
apply plugin: 'com.android.library'
apply from: rootProject.file('global.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21

View File

@ -1,10 +1,28 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
apply plugin: 'com.android.application'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.mariotaku.twidere"
minSdkVersion 20

View File

@ -2,16 +2,15 @@ import java.text.SimpleDateFormat
apply plugin: 'com.android.application'
apply plugin: 'aar-link-sources'
apply from: rootProject.file('global.gradle')
apply from: rootProject.file('signing.gradle')
android {
compileSdkVersion 21
buildToolsVersion '21.1.2'
defaultConfig {
applicationId "org.mariotaku.twidere"
minSdkVersion 14
targetSdkVersion 21
targetSdkVersion 22
versionCode 99
versionName "0.3.0"
multiDexEnabled true

View File

@ -1561,7 +1561,6 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
true, nameFirst, nicknameOnly, profileImageStyle, mediaPreviewStyle, status, null);
mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);
}

View File

@ -28,24 +28,29 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IContentCardAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.MessageEntryViewHolder;
import static org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NICKNAME_ONLY;
public class MessageEntriesAdapter extends Adapter<ViewHolder> implements OnClickListener {
public class MessageEntriesAdapter extends Adapter<ViewHolder> implements Constants, IContentCardAdapter, OnClickListener {
private final Context mContext;
private final LayoutInflater mInflater;
private final ImageLoaderWrapper mImageLoader;
private final MultiSelectManager mMultiSelectManager;
private final boolean mNicknameOnly;
private final int mTextSize;
private final int mProfileImageStyle;
private final int mMediaPreviewStyle;
private Cursor mCursor;
private MessageEntriesAdapterListener mListener;
@ -53,10 +58,45 @@ public class MessageEntriesAdapter extends Adapter<ViewHolder> implements OnClic
return mContext;
}
@Override
public ImageLoadingHandler getImageLoadingHandler() {
return null;
}
@Override
public int getProfileImageStyle() {
return mProfileImageStyle;
}
@Override
public int getMediaPreviewStyle() {
return mMediaPreviewStyle;
}
@Override
public AsyncTwitterWrapper getTwitterWrapper() {
return null;
}
@Override
public float getTextSize() {
return mTextSize;
}
public ImageLoaderWrapper getImageLoader() {
return mImageLoader;
}
@Override
public boolean isGapItem(int position) {
return false;
}
@Override
public void onGapClick(ViewHolder holder, int position) {
}
public boolean isNicknameOnly() {
return mNicknameOnly;
}
@ -74,6 +114,16 @@ public class MessageEntriesAdapter extends Adapter<ViewHolder> implements OnClic
((MessageEntryViewHolder) holder).displayMessage(c);
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
}
@Override
public void onItemMenuClick(ViewHolder holder, View menuView, int position) {
}
public void onMessageClick(int position) {
if (mListener == null) return;
mListener.onEntryClick(position, getEntry(position));
@ -97,8 +147,12 @@ public class MessageEntriesAdapter extends Adapter<ViewHolder> implements OnClic
final TwidereApplication app = TwidereApplication.getInstance(context);
mMultiSelectManager = app.getMultiSelectManager();
mImageLoader = app.getImageLoaderWrapper();
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mNicknameOnly = prefs.getBoolean(KEY_NICKNAME_ONLY, false);
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
}
public static class DirectMessageEntry {

View File

@ -41,7 +41,7 @@ import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
public class TabsAdapter extends FragmentStatePagerAdapter implements TabProvider, TabListener, Constants {
private final ArrayList<TabSpec> mTabs = new ArrayList<TabSpec>();
private final ArrayList<TabSpec> mTabs = new ArrayList<>();
private final Context mContext;
private final PagerIndicator mIndicator;

View File

@ -67,6 +67,7 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
private OnScrollListener mOnScrollListener = new OnScrollListener() {
private int mScrollState;
private int mScrollSum;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
@ -76,9 +77,14 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (Math.abs(dy) > mTouchSlop) {
//Reset mScrollSum when scrolling in reverse direction
if (dy * mScrollSum < 0) {
mScrollSum = 0;
}
mScrollSum += dy;
if (Math.abs(mScrollSum) > mTouchSlop) {
setControlVisible(dy < 0);
mScrollSum = 0;
}
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (!isRefreshing() && mAdapter.hasLoadMoreIndicator() && mScrollState != RecyclerView.SCROLL_STATE_IDLE
@ -153,6 +159,7 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
}
public void setRefreshing(boolean refreshing) {
if (refreshing == mSwipeRefreshLayout.isRefreshing()) return;
mSwipeRefreshLayout.setRefreshing(refreshing);
}
@ -305,13 +312,13 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
twitter.destroyFavoriteAsync(status.account_id, status.id);
//spice
SpiceProfilingUtil.profile(getActivity(), status.account_id, status.id + ",Unfavor," + status.account_id + "," + status.user_id + "," + status.timestamp);
SpiceProfilingUtil.log(getActivity(),status.id + ",Unfavor," + status.account_id + "," + status.user_id + "," + status.timestamp);
SpiceProfilingUtil.log(getActivity(), status.id + ",Unfavor," + status.account_id + "," + status.user_id + "," + status.timestamp);
//end
} else {
twitter.createFavoriteAsync(status.account_id, status.id);
//spice
SpiceProfilingUtil.profile(getActivity(),status.account_id, status.id + ",Favor," + status.account_id + "," + status.user_id + "," + status.timestamp);
SpiceProfilingUtil.log(getActivity(),status.id + ",Favor," + status.account_id + "," + status.user_id + "," + status.timestamp);
SpiceProfilingUtil.profile(getActivity(), status.account_id, status.id + ",Favor," + status.account_id + "," + status.user_id + "," + status.timestamp);
SpiceProfilingUtil.log(getActivity(), status.id + ",Favor," + status.account_id + "," + status.user_id + "," + status.timestamp);
//end
}
break;

View File

@ -105,7 +105,26 @@ public class DirectMessagesFragment extends BaseSupportFragment implements Loade
@Override
public void onRefresh() {
if (isRefreshing()) return;
new TwidereAsyncTask<Void, Void, long[][]>() {
@Override
protected long[][] doInBackground(final Void... params) {
final long[][] result = new long[2][];
result[0] = Utils.getActivatedAccountIds(getActivity());
result[1] = Utils.getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
return result;
}
@Override
protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
twitter.getSentDirectMessagesAsync(result[0], null, null);
}
}.executeTask();
}
private void setListShown(boolean shown) {
@ -205,26 +224,6 @@ public class DirectMessagesFragment extends BaseSupportFragment implements Loade
// @Override
// public void onRefresh() {
// if (isRefreshing()) return;
// new TwidereAsyncTask<Void, Void, long[][]>() {
//
// @Override
// protected long[][] doInBackground(final Void... params) {
// final long[][] result = new long[2][];
// result[0] = getActivatedAccountIds(getActivity());
// result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
// return result;
// }
//
// @Override
// protected void onPostExecute(final long[][] result) {
// final AsyncTwitterWrapper twitter = getTwitterWrapper();
// if (twitter == null) return;
// twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
// twitter.getSentDirectMessagesAsync(result[0], null, null);
// }
//
// }.executeTask();
// }
@ -326,6 +325,10 @@ public class DirectMessagesFragment extends BaseSupportFragment implements Loade
// setRefreshing(twitter.isReceivedDirectMessagesRefreshing() || twitter.isSentDirectMessagesRefreshing());
// }
public boolean isRefreshing() {
return mSwipeRefreshLayout.isRefreshing();
}
private void addReadPosition(final int firstVisibleItem) {
if (mFirstVisibleItem != firstVisibleItem) {
mReadPositions.add(firstVisibleItem);

View File

@ -107,7 +107,6 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
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();
}

View File

@ -53,12 +53,13 @@ import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Inbox;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Outbox;
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
import org.mariotaku.twidere.provider.TwidereDataStore.Mentions;
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.task.CacheUsersStatusesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.task.TwidereAsyncTask;
import org.mariotaku.twidere.util.collection.LongSparseMap;
@ -73,7 +74,6 @@ import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@ -380,8 +380,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public boolean isHomeTimelineRefreshing() {
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_HOME_TIMELINE)
|| mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_HOME_TIMELINE);
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_HOME_TIMELINE);
}
public boolean isLocalTrendsRefreshing() {
@ -390,18 +389,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public boolean isMentionsTimelineRefreshing() {
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_MENTIONS)
|| mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_MENTIONS);
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_MENTIONS);
}
public boolean isReceivedDirectMessagesRefreshing() {
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_RECEIVED_DIRECT_MESSAGES)
|| mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_RECEIVED_DIRECT_MESSAGES);
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_RECEIVED_DIRECT_MESSAGES);
}
public boolean isSentDirectMessagesRefreshing() {
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_SENT_DIRECT_MESSAGES)
|| mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_SENT_DIRECT_MESSAGES);
return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_SENT_DIRECT_MESSAGES);
}
public int refreshAll() {
@ -1763,35 +1759,35 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected List<MessageListResponse> doInBackground(final Void... params) {
final List<MessageListResponse> result = new ArrayList<MessageListResponse>();
final List<MessageListResponse> result = new ArrayList<>();
if (account_ids == null) return result;
int idx = 0;
final int load_item_limit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
for (final long account_id : account_ids) {
final Twitter twitter = getTwitterInstance(mContext, account_id, true);
if (twitter != null) {
try {
final Paging paging = new Paging();
paging.setCount(load_item_limit);
long max_id = -1, since_id = -1;
if (isMaxIdsValid() && max_ids[idx] > 0) {
max_id = max_ids[idx];
paging.setMaxId(max_id);
}
if (isSinceIdsValid() && since_ids[idx] > 0) {
since_id = since_ids[idx];
paging.setSinceId(since_id - 1);
}
final List<DirectMessage> messages = new ArrayList<>();
final boolean truncated = truncateMessages(getDirectMessages(twitter, paging), messages,
since_id);
result.add(new MessageListResponse(account_id, max_id, since_id, load_item_limit, messages,
truncated));
} catch (final TwitterException e) {
result.add(new MessageListResponse(account_id, e));
for (final long accountId : account_ids) {
final Twitter twitter = getTwitterInstance(mContext, accountId, true);
if (twitter == null) continue;
try {
final Paging paging = new Paging();
paging.setCount(load_item_limit);
long max_id = -1, since_id = -1;
if (isMaxIdsValid() && max_ids[idx] > 0) {
max_id = max_ids[idx];
paging.setMaxId(max_id);
}
if (isSinceIdsValid() && since_ids[idx] > 0) {
since_id = since_ids[idx];
paging.setSinceId(since_id - 1);
}
final List<DirectMessage> messages = new ArrayList<>();
final boolean truncated = truncateMessages(getDirectMessages(twitter, paging), messages,
since_id);
result.add(new MessageListResponse(accountId, max_id, since_id, load_item_limit, messages,
truncated));
storeMessages(accountId, messages, isOutgoing(), true);
} catch (final TwitterException e) {
result.add(new MessageListResponse(accountId, e));
}
idx++;
}
@ -1799,6 +1795,35 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
protected abstract boolean isOutgoing();
private boolean storeMessages(long accountId, List<DirectMessage> messages, boolean isOutgoing, boolean notify) {
if (messages == null) return true;
final Uri uri = getDatabaseUri();
final ContentValues[] valuesArray = new ContentValues[messages.size()];
final long[] messageIds = new long[messages.size()];
for (int i = 0, j = messages.size(); i < j; i++) {
final DirectMessage message = messages.get(i);
messageIds[i] = message.getId();
valuesArray[i] = createDirectMessage(message, accountId, isOutgoing);
}
// Delete all rows conflicting before new data inserted.
final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds)));
final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY,
false));
mResolver.delete(deleteUri, deleteWhere.getSQL(), null);
// Insert previously fetched items.
final Uri insertUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, notify));
bulkInsert(mResolver, insertUri, valuesArray);
return false;
}
protected abstract Uri getDatabaseUri();
final boolean isSinceIdsValid() {
return since_ids != null && since_ids.length == account_ids.length;
}
@ -1823,6 +1848,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_HOME_TIMELINE);
}
@Override
protected Uri getDatabaseUri() {
return Statuses.CONTENT_URI;
}
@Override
public ResponseList<twitter4j.Status> getStatuses(final Twitter twitter, final Paging paging)
throws TwitterException {
@ -1832,7 +1862,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@Override
protected void onPostExecute(final List<StatusListResponse> responses) {
super.onPostExecute(responses);
mAsyncTaskManager.add(new StoreHomeTimelineTask(responses, !isMaxIdsValid()), true);
mGetHomeTimelineTaskId = -1;
for (final StatusListResponse response : responses) {
if (response.list == null) {
@ -1885,16 +1914,22 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_MENTIONS);
}
@Override
public ResponseList<twitter4j.Status> getStatuses(final Twitter twitter, final Paging paging)
throws TwitterException {
return twitter.getMentionsTimeline(paging);
}
@Override
protected Uri getDatabaseUri() {
return Mentions.CONTENT_URI;
}
@Override
protected void onPostExecute(final List<StatusListResponse> responses) {
super.onPostExecute(responses);
mAsyncTaskManager.add(new StoreMentionsTask(responses, !isMaxIdsValid()), true);
// mAsyncTaskManager.add(new StoreMentionsTask(responses, !isMaxIdsValid()), true);
mGetMentionsTaskId = -1;
for (final StatusListResponse response : responses) {
if (response.list == null) {
@ -1921,16 +1956,26 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_RECEIVED_DIRECT_MESSAGES);
}
@Override
protected Uri getDatabaseUri() {
return Inbox.CONTENT_URI;
}
@Override
public ResponseList<DirectMessage> getDirectMessages(final Twitter twitter, final Paging paging)
throws TwitterException {
return twitter.getDirectMessages(paging);
}
@Override
protected boolean isOutgoing() {
return false;
}
@Override
protected void onPostExecute(final List<MessageListResponse> responses) {
super.onPostExecute(responses);
mAsyncTaskManager.add(new StoreReceivedDirectMessagesTask(responses, !isMaxIdsValid()), true);
// mAsyncTaskManager.add(new StoreReceivedDirectMessagesTask(responses, !isMaxIdsValid()), true);
mGetReceivedDirectMessagesTaskId = -1;
}
@ -1955,10 +2000,20 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return twitter.getSentDirectMessages(paging);
}
@Override
protected boolean isOutgoing() {
return true;
}
@Override
protected Uri getDatabaseUri() {
return Outbox.CONTENT_URI;
}
@Override
protected void onPostExecute(final List<MessageListResponse> responses) {
super.onPostExecute(responses);
mAsyncTaskManager.add(new StoreSentDirectMessagesTask(responses, !isMaxIdsValid()), true);
// mAsyncTaskManager.add(new StoreSentDirectMessagesTask(responses, !isMaxIdsValid()), true);
mGetSentDirectMessagesTaskId = -1;
}
@ -1982,41 +2037,90 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return mMaxIds != null && mMaxIds.length == mAccountIds.length;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// new CacheUsersStatusesTask(mContext, responses.toArray(array)).executeTask();
}
private boolean storeStatus(long accountId, List<twitter4j.Status> statuses, long maxId, boolean truncated, boolean notify) {
if (statuses == null || statuses.isEmpty()) {
return true;
}
final Uri uri = getDatabaseUri();
final boolean noItemsBefore = getStatusCountInDatabase(mContext, uri, accountId) <= 0;
final ContentValues[] values = new ContentValues[statuses.size()];
final long[] statusIds = new long[statuses.size()];
for (int i = 0, j = statuses.size(); i < j; i++) {
final twitter4j.Status status = statuses.get(i);
values[i] = createStatus(status, accountId);
statusIds[i] = status.getId();
}
// Delete all rows conflicting before new data inserted.
final Expression accountWhere = Expression.equals(Statuses.ACCOUNT_ID, accountId);
final Expression statusWhere = Expression.in(new Column(Statuses.STATUS_ID), new RawItemArray(statusIds));
final String deleteWhere = Expression.and(accountWhere, statusWhere).getSQL();
final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, false));
final int rowsDeleted = mResolver.delete(deleteUri, deleteWhere, null);
// UCD
ProfilingUtil.profile(mContext, accountId,
"Download tweets, " + TwidereArrayUtils.toString(statusIds, ',', true));
//spice
SpiceProfilingUtil.profile(mContext, accountId, accountId + ",Refresh," + TwidereArrayUtils.toString(statusIds, ',', true));
//end
// Insert previously fetched items.
final Uri insertUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, notify));
bulkInsert(mResolver, insertUri, values);
// Insert a gap.
final long minId = statusIds.length != 0 ? TwidereArrayUtils.min(statusIds) : -1;
final boolean deletedOldGap = rowsDeleted > 0 && ArrayUtils.contains(statusIds, maxId);
final boolean noRowsDeleted = rowsDeleted == 0;
final boolean insertGap = minId > 0 && (noRowsDeleted || deletedOldGap) && !truncated
&& !noItemsBefore && statuses.size() > 1;
if (insertGap) {
final ContentValues gapValue = new ContentValues();
gapValue.put(Statuses.IS_GAP, 1);
final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
Expression.equals(Statuses.STATUS_ID, minId));
final Uri updateUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, true));
mResolver.update(updateUri, gapValue, where.getSQL(), null);
}
return false;
}
protected abstract Uri getDatabaseUri();
@Override
protected List<StatusListResponse> doInBackground(final Void... params) {
final List<StatusListResponse> result = new ArrayList<>();
if (mAccountIds == null) return result;
int idx = 0;
final int load_item_limit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
for (final long account_id : mAccountIds) {
final Twitter twitter = getTwitterInstance(mContext, account_id, true);
if (twitter != null) {
try {
final Paging paging = new Paging();
paging.setCount(load_item_limit);
final long maxId, sinceId;
if (isMaxIdsValid() && mMaxIds[idx] > 0) {
maxId = mMaxIds[idx];
paging.setMaxId(maxId);
} else {
maxId = -1;
}
if (isSinceIdsValid() && mSinceIds[idx] > 0) {
sinceId = mSinceIds[idx];
paging.setSinceId(sinceId - 1);
} else {
sinceId = -1;
}
final List<twitter4j.Status> statuses = new ArrayList<>();
final boolean truncated = truncateStatuses(getStatuses(twitter, paging), statuses, sinceId);
result.add(new StatusListResponse(account_id, maxId, sinceId, load_item_limit, statuses,
truncated));
} catch (final TwitterException e) {
result.add(new StatusListResponse(account_id, e));
final int loadItemLimit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
for (final long accountId : mAccountIds) {
final Twitter twitter = getTwitterInstance(mContext, accountId, true);
if (twitter == null) continue;
try {
final Paging paging = new Paging();
paging.setCount(loadItemLimit);
final long maxId, sinceId;
if (isMaxIdsValid() && mMaxIds[idx] > 0) {
maxId = mMaxIds[idx];
paging.setMaxId(maxId);
} else {
maxId = -1;
}
if (isSinceIdsValid() && mSinceIds[idx] > 0) {
sinceId = mSinceIds[idx];
paging.setSinceId(sinceId - 1);
} else {
sinceId = -1;
}
final List<twitter4j.Status> statuses = new ArrayList<>();
final boolean truncated = truncateStatuses(getStatuses(twitter, paging), statuses, sinceId);
storeStatus(accountId, statuses, maxId, truncated, true);
} catch (final TwitterException e) {
result.add(new StatusListResponse(accountId, e));
}
idx++;
}
@ -2233,76 +2337,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
abstract class StoreDirectMessagesTask extends ManagedAsyncTask<Void, Void, SingleResponse<Boolean>> {
private final List<MessageListResponse> responses;
private final Uri uri;
private final boolean notify;
public StoreDirectMessagesTask(final List<MessageListResponse> result, final Uri uri, final boolean notify,
final String tag) {
super(mContext, mAsyncTaskManager, tag);
responses = result;
this.uri = uri;
this.notify = notify;
}
abstract boolean isOutgoing();
@Override
protected SingleResponse<Boolean> doInBackground(final Void... args) {
boolean succeed = false;
for (final TwitterListResponse<DirectMessage> response : responses) {
final long accountId = response.account_id;
final List<DirectMessage> messages = response.list;
if (messages != null) {
final ContentValues[] values_array = new ContentValues[messages.size()];
final long[] messageIds = new long[messages.size()];
for (int i = 0, j = messages.size(); i < j; i++) {
final DirectMessage message = messages.get(i);
messageIds[i] = message.getId();
values_array[i] = createDirectMessage(message, accountId, isOutgoing());
}
// Delete all rows conflicting before new data inserted.
{
final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds)));
final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY,
false));
mResolver.delete(deleteUri, deleteWhere.getSQL(), null);
}
// Insert previously fetched items.
final Uri insertUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, notify));
bulkInsert(mResolver, insertUri, values_array);
}
succeed = true;
}
return SingleResponse.getInstance(succeed);
}
}
class StoreHomeTimelineTask extends StoreStatusesTask {
public StoreHomeTimelineTask(final List<StatusListResponse> result, final boolean notify) {
super(result, Statuses.CONTENT_URI, notify, TASK_TAG_STORE_HOME_TIMELINE);
}
@Override
protected void onPostExecute(final SingleResponse<Boolean> response) {
if (Boolean.TRUE.equals(response.getData())) {
//TODO notify if necessary?
}
super.onPostExecute(response);
}
}
class StoreLocalTrendsTask extends StoreTrendsTask {
@ -2312,125 +2346,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
class StoreMentionsTask extends StoreStatusesTask {
public StoreMentionsTask(final List<StatusListResponse> result, final boolean notify) {
super(result, Mentions.CONTENT_URI, notify, TASK_TAG_STORE_MENTIONS);
}
@Override
protected void onPostExecute(final SingleResponse<Boolean> response) {
if (Boolean.TRUE.equals(response.getData())) {
//TODO notify if necessary?
}
super.onPostExecute(response);
}
}
class StoreReceivedDirectMessagesTask extends StoreDirectMessagesTask {
public StoreReceivedDirectMessagesTask(final List<MessageListResponse> result, final boolean notify) {
super(result, DirectMessages.Inbox.CONTENT_URI, notify, TASK_TAG_STORE_RECEIVED_DIRECT_MESSAGES);
}
@Override
boolean isOutgoing() {
return false;
}
}
class StoreSentDirectMessagesTask extends StoreDirectMessagesTask {
public StoreSentDirectMessagesTask(final List<MessageListResponse> result, final boolean notify) {
super(result, DirectMessages.Outbox.CONTENT_URI, notify, TASK_TAG_STORE_SENT_DIRECT_MESSAGES);
}
@Override
boolean isOutgoing() {
return true;
}
}
abstract class StoreStatusesTask extends ManagedAsyncTask<Void, Void, SingleResponse<Boolean>> {
private final List<StatusListResponse> responses;
private final Uri uri;
private final ArrayList<ContentValues> all_statuses = new ArrayList<>();
private final boolean notify;
public StoreStatusesTask(final List<StatusListResponse> result, final Uri uri, final boolean notify,
final String tag) {
super(mContext, mAsyncTaskManager, tag);
responses = result;
this.uri = uri;
this.notify = notify;
}
@Override
protected SingleResponse<Boolean> doInBackground(final Void... args) {
boolean succeed = false;
for (final StatusListResponse response : responses) {
final long accountId = response.account_id;
final List<twitter4j.Status> statuses = response.list;
if (statuses == null || statuses.isEmpty()) {
continue;
}
final boolean noItemsBefore = getStatusCountInDatabase(mContext, uri, accountId) <= 0;
final ContentValues[] values = new ContentValues[statuses.size()];
final long[] statusIds = new long[statuses.size()];
for (int i = 0, j = statuses.size(); i < j; i++) {
final twitter4j.Status status = statuses.get(i);
values[i] = createStatus(status, accountId);
statusIds[i] = status.getId();
}
// Delete all rows conflicting before new data inserted.
final Expression accountWhere = Expression.equals(Statuses.ACCOUNT_ID, accountId);
final Expression statusWhere = Expression.in(new Column(Statuses.STATUS_ID), new RawItemArray(statusIds));
final String deleteWhere = Expression.and(accountWhere, statusWhere).getSQL();
final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, false));
final int rowsDeleted = mResolver.delete(deleteUri, deleteWhere, null);
// UCD
ProfilingUtil.profile(mContext, accountId,
"Download tweets, " + TwidereArrayUtils.toString(statusIds, ',', true));
//spice
SpiceProfilingUtil.profile(mContext, accountId, accountId + ",Refresh," + TwidereArrayUtils.toString(statusIds, ',', true));
//end
all_statuses.addAll(Arrays.asList(values));
// Insert previously fetched items.
final Uri insertUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, notify));
bulkInsert(mResolver, insertUri, values);
// Insert a gap.
final long minId = statusIds.length != 0 ? TwidereArrayUtils.min(statusIds) : -1;
final boolean deletedOldGap = rowsDeleted > 0 && ArrayUtils.contains(statusIds, response.max_id);
final boolean noRowsDeleted = rowsDeleted == 0;
final boolean insertGap = minId > 0 && (noRowsDeleted || deletedOldGap) && !response.truncated
&& !noItemsBefore && statuses.size() > 1;
if (insertGap) {
final ContentValues gapValue = new ContentValues();
gapValue.put(Statuses.IS_GAP, 1);
final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
Expression.equals(Statuses.STATUS_ID, minId));
final Uri updateUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, true));
mResolver.update(updateUri, gapValue, where.getSQL(), null);
}
succeed = true;
}
return SingleResponse.getInstance(succeed, null);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
final StatusListResponse[] array = new StatusListResponse[responses.size()];
new CacheUsersStatusesTask(mContext, responses.toArray(array)).executeTask();
}
}
class StoreTrendsTask extends ManagedAsyncTask<Void, Void, SingleResponse<Boolean>> {
private final ListResponse<Trends> response;

View File

@ -1954,18 +1954,18 @@ public final class Utils implements Constants, TwitterConstants {
}
public static long[] getNewestMessageIdsFromDatabase(final Context context, final Uri uri) {
final long[] account_ids = getActivatedAccountIds(context);
return getNewestMessageIdsFromDatabase(context, uri, account_ids);
final long[] accountIds = getActivatedAccountIds(context);
return getNewestMessageIdsFromDatabase(context, uri, accountIds);
}
public static long[] getNewestMessageIdsFromDatabase(final Context context, final Uri uri, final long[] account_ids) {
if (context == null || uri == null || account_ids == null) return null;
public static long[] getNewestMessageIdsFromDatabase(final Context context, final Uri uri, final long[] accountIds) {
if (context == null || uri == null || accountIds == null) return null;
final String[] cols = new String[]{DirectMessages.MESSAGE_ID};
final ContentResolver resolver = context.getContentResolver();
final long[] status_ids = new long[account_ids.length];
final long[] messageIds = new long[accountIds.length];
int idx = 0;
for (final long account_id : account_ids) {
final String where = Statuses.ACCOUNT_ID + " = " + account_id;
for (final long accountId : accountIds) {
final String where = Statuses.ACCOUNT_ID + " = " + accountId;
final Cursor cur = ContentResolverUtils.query(resolver, uri, cols, where, null,
DirectMessages.DEFAULT_SORT_ORDER);
if (cur == null) {
@ -1974,12 +1974,12 @@ public final class Utils implements Constants, TwitterConstants {
if (cur.getCount() > 0) {
cur.moveToFirst();
status_ids[idx] = cur.getLong(cur.getColumnIndexOrThrow(DirectMessages.MESSAGE_ID));
messageIds[idx] = cur.getLong(cur.getColumnIndexOrThrow(DirectMessages.MESSAGE_ID));
}
cur.close();
idx++;
}
return status_ids;
return messageIds;
}
public static long[] getNewestStatusIdsFromDatabase(final Context context, final Uri uri) {
@ -3800,12 +3800,12 @@ public final class Utils implements Constants, TwitterConstants {
showWarnMessage(context, context.getText(resId), long_message);
}
public static void startProfilingServiceIfNeeded(final Context context) {
public static void startProfilingServiceIfNeeded(final Context context) {
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final Intent profilingServiceIntent = new Intent(context, UCDService.class);
//spice
final Intent spiceProfilingServiceIntent = new Intent(context, SpiceService.class);
if (prefs.getBoolean(KEY_UCD_DATA_PROFILING, false) ||prefs.getBoolean(KEY_SPICE_DATA_PROFILING, false) ) {
if (prefs.getBoolean(KEY_UCD_DATA_PROFILING, false) || prefs.getBoolean(KEY_SPICE_DATA_PROFILING, false)) {
context.startService(profilingServiceIntent);
//spice
context.startService(spiceProfilingServiceIntent);

View File

@ -152,7 +152,9 @@ public class HeaderDrawerLayout extends ViewGroup {
public int getHeaderTop() {
return mContainer.getTop();
} @Override
}
@Override
public void computeScroll() {
boolean invalidate = mDragHelper.continueSettling(true);
if (!mTouchDown && mScroller.computeScrollOffset()) {
@ -187,7 +189,9 @@ public class HeaderDrawerLayout extends ViewGroup {
private boolean canScrollCallback(float dy) {
return mDrawerCallback.canScroll(dy);
} @Override
}
@Override
protected void onFinishInflate() {
if (getChildCount() != 1) {
throw new IllegalArgumentException("Add subview by XML is not allowed.");
@ -263,7 +267,9 @@ public class HeaderDrawerLayout extends ViewGroup {
private void setScrollingHeaderByGesture(boolean scrolling) {
mScrollingHeaderByGesture = scrolling;
} @Override
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final View child = getChildAt(0);
@ -543,10 +549,4 @@ public class HeaderDrawerLayout extends ViewGroup {
}
}
}

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.view.holder;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.view.View;
@ -32,7 +33,10 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.MessageEntriesAdapter;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ShortTimeView;
import org.mariotaku.twidere.view.iface.IColorLabelView;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.UserColorNameUtils.getUserNickname;
@ -43,19 +47,20 @@ public class MessageEntryViewHolder extends ViewHolder implements OnClickListene
public final TextView nameView, screenNameView, textView;
public final ShortTimeView timeView;
private final MessageEntriesAdapter adapter;
private float text_size;
private final IColorLabelView content;
private boolean account_color_enabled;
public MessageEntryViewHolder(final MessageEntriesAdapter adapter, final View itemView) {
super(itemView);
this.adapter = adapter;
final Context context = itemView.getContext();
content = (IColorLabelView) itemView.findViewById(R.id.content);
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
nameView = (TextView) itemView.findViewById(R.id.name);
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
textView = (TextView) itemView.findViewById(R.id.text);
timeView = (ShortTimeView) itemView.findViewById(R.id.time);
setTextSize(adapter.getTextSize());
itemView.setOnClickListener(this);
}
@ -78,6 +83,10 @@ public class MessageEntryViewHolder extends ViewHolder implements OnClickListene
textView.setText(toPlainText(cursor.getString(ConversationEntries.IDX_TEXT)));
timeView.setTime(timestamp);
setIsOutgoing(isOutgoing);
if (account_color_enabled) {
content.drawEnd(Utils.getAccountColor(context, accountId));
}
content.drawStart(UserColorNameUtils.getUserColor(context, conversationId));
final String profileImage = cursor.getString(ConversationEntries.IDX_PROFILE_IMAGE_URL);
loader.displayProfileImage(profileImageView, profileImage);
@ -98,15 +107,11 @@ public class MessageEntryViewHolder extends ViewHolder implements OnClickListene
}
}
public void setAccountColor(final int color) {
// content.drawEnd(account_color_enabled ? color : Color.TRANSPARENT);
}
public void setAccountColorEnabled(final boolean enabled) {
if (account_color_enabled == enabled) return;
account_color_enabled = enabled;
if (!account_color_enabled) {
// content.drawEnd(Color.TRANSPARENT);
content.drawEnd(Color.TRANSPARENT);
}
}
@ -114,11 +119,11 @@ public class MessageEntryViewHolder extends ViewHolder implements OnClickListene
timeView.setCompoundDrawablesWithIntrinsicBounds(0, 0, is_outgoing ? R.drawable.ic_indicator_sent : 0, 0);
}
public void setTextSize(final float text_size) {
if (this.text_size == text_size) return;
this.text_size = text_size;
textView.setTextSize(text_size);
nameView.setTextSize(text_size);
public void setTextSize(final float textSize) {
nameView.setTextSize(textSize * 1.1f);
screenNameView.setTextSize(textSize);
textView.setTextSize(textSize);
timeView.setTextSize(textSize);
}
public void setUserColor(final int color) {

View File

@ -116,25 +116,26 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP);
if (status.retweet_id > 0) {
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
final String retweetedBy = UserColorNameUtils.getDisplayName(context, status.retweeted_by_id,
status.retweeted_by_name, status.retweeted_by_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_retweet);
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0 && displayInReplyTo) {
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0 && displayInReplyTo) {
final String inReplyTo = UserColorNameUtils.getDisplayName(context, status.in_reply_to_user_id,
status.in_reply_to_name, status.in_reply_to_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_reply);
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
} else {
replyRetweetView.setText(null);
replyRetweetView.setVisibility(View.GONE);
replyRetweetIcon.setVisibility(View.GONE);
replyRetweetView.setText(null);
}
final int typeIconRes = getUserTypeIconRes(status.user_is_verified, status.user_is_protected);
if (typeIconRes != 0) {
profileTypeView.setImageResource(typeIconRes);

View File

@ -68,8 +68,11 @@ public interface IColorLabelView {
public Helper(final View view, final Context context, final AttributeSet attrs, final int defStyle) {
mView = view;
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Twidere);
mIgnorePadding = a.getBoolean(R.styleable.Twidere_ignorePadding, false);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorLabelView);
mIgnorePadding = a.getBoolean(R.styleable.ColorLabelView_ignorePadding, false);
if (a.hasValue(R.styleable.ColorLabelView_backgroundColor)) {
drawBackground(a.getColor(R.styleable.ColorLabelView_backgroundColor, 0));
}
a.recycle();
final Resources res = context.getResources();
mDensity = res.getDisplayMetrics().density;

View File

@ -24,6 +24,7 @@ import android.support.v4.view.ViewPager;
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
@SuppressWarnings("unused")
public interface PagerIndicator extends ViewPager.OnPageChangeListener {
/**
* Notify the indicator that the fragment list has changed.

View File

@ -29,8 +29,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:paddingTop="@dimen/element_spacing_small"
android:orientation="vertical">
android:orientation="vertical"
android:paddingTop="@dimen/element_spacing_small">
<Space
android:id="@+id/reply_retweet_space"
@ -56,20 +56,20 @@
tools:src="@drawable/ic_activity_action_retweet"
tools:visibility="visible"/>
<org.mariotaku.twidere.view.ActionIconThemedTextView
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/reply_retweet_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_toRightOf="@id/reply_retweet_space"
android:layout_toRightOf="@+id/reply_retweet_space"
android:ellipsize="end"
android:gravity="center_vertical"
android:minHeight="@dimen/element_size_small"
tools:text="Mariotaku and 10 others retweeted this"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone"
tools:text="Mariotaku and 10 others retweeted"
tools:visibility="visible"/>
<RelativeLayout
@ -90,7 +90,8 @@
android:layout_marginRight="@dimen/element_spacing_small"
android:layout_marginTop="@dimen/element_spacing_small"
android:contentDescription="@string/profile_image"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop"
tools:src="@drawable/profile_image_nyan_sakamoto"/>
<org.mariotaku.twidere.view.BoundsImageView
android:id="@+id/profile_type"
@ -174,8 +175,8 @@
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/profile_container"
android:layout_marginTop="@dimen/element_spacing_normal"
android:horizontalSpacing="@dimen/element_spacing_normal"
android:verticalSpacing="@dimen/element_spacing_normal">
android:horizontalSpacing="@dimen/element_spacing_xsmall"
android:verticalSpacing="@dimen/element_spacing_xsmall">
<include layout="@layout/layout_card_media_preview"/>
@ -195,85 +196,67 @@
android:textColor="?android:attr/textColorPrimary"
tools:text="@string/sample_status_text"/>
<LinearLayout
android:layout_below="@+id/text"
android:layout_alignLeft="@+id/profile_container"
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@+id/text"
android:gravity="center_vertical"
android:gravity="center_vertical|left"
android:orientation="horizontal">
<HorizontalScrollView
android:id="@+id/action_buttons"
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:overScrollMode="never"
android:scrollbars="none">
android:layout_height="@dimen/button_size_content_card"
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"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
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.ActionIconThemedTextView
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.ActionIconThemedTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
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"/>
<org.mariotaku.twidere.view.ActionIconThemedTextView
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.ActionIconThemedTextView
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>
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<org.mariotaku.twidere.view.ActionIconView
android:id="@+id/extra_type"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_gravity="center|right"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_weight="0"
android:color="?android:textColorSecondary"
tools:src="@drawable/ic_action_gallery"/>
</LinearLayout>
<org.mariotaku.twidere.view.ActionIconView
android:id="@+id/extra_type"
android:layout_width="@dimen/element_size_small"
android:layout_below="@+id/text"
android:layout_height="@dimen/element_size_small"
android:layout_gravity="center|right"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/action_buttons"
android:layout_alignBottom="@+id/action_buttons"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_weight="0"
android:color="?android:textColorSecondary"
tools:src="@drawable/ic_action_gallery"/>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
</merge>

View File

@ -77,7 +77,8 @@
android:layout_alignWithParentIfMissing="true"
android:layout_below="@+id/reply_retweet_status"
android:contentDescription="@string/profile_image"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop"
tools:src="@drawable/profile_image_nyan_sakamoto"/>
<org.mariotaku.twidere.view.BoundsImageView
android:id="@+id/profile_type"
@ -116,7 +117,8 @@
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold"
tools:text="User"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/screen_name"
@ -126,6 +128,7 @@
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="\@username"
tools:textSize="10sp"/>
</LinearLayout>
@ -151,7 +154,9 @@
android:id="@+id/media_preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_small">
android:layout_marginTop="@dimen/element_spacing_small"
android:horizontalSpacing="@dimen/element_spacing_xsmall"
android:verticalSpacing="@dimen/element_spacing_xsmall">
<include layout="@layout/layout_card_media_preview"/>
@ -168,80 +173,66 @@
</LinearLayout>
<HorizontalScrollView
android:id="@+id/actions_scroller"
<LinearLayout
android:id="@+id/action_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/status_content"
android:layout_below="@+id/status_content"
android:layout_marginTop="@dimen/element_spacing_small"
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.ActionIconThemedTextView
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.ActionIconThemedTextView
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.ActionIconThemedTextView
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>
<Space
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/item_menu"
android:layout_toRightOf="@+id/actions_scroller"/>
android:gravity="center_vertical"
android:orientation="horizontal">
<org.mariotaku.twidere.view.ActionIconThemedTextView
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.ActionIconThemedTextView
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.ActionIconThemedTextView
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>
<org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/item_menu"
style="?cardActionButtonStyle"
android:layout_width="@dimen/button_size_content_card"
android:layout_height="@dimen/button_size_content_card"
android:layout_alignBottom="@+id/actions_scroller"
android:layout_alignBottom="@+id/action_buttons"
android:layout_alignParentRight="true"
android:layout_weight="0"
android:src="@drawable/ic_action_more_horizontal"/>
</RelativeLayout>

View File

@ -18,9 +18,12 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
tools:showIn="@layout/card_item_status_common"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/media_preview_item_0"
@ -46,29 +49,12 @@
<include layout="@layout/layout_card_media_preview_item"/>
</FrameLayout>
<FrameLayout
android:id="@+id/media_preview_item_3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/layout_card_media_preview_item"/>
</FrameLayout>
<FrameLayout
android:id="@+id/media_preview_item_4"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/layout_card_media_preview_item"/>
</FrameLayout>
<FrameLayout
android:id="@+id/media_preview_item_5"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/layout_card_media_preview_item"/>
<TextView
android:id="@+id/more_media"

View File

@ -19,6 +19,7 @@
-->
<merge 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">
@ -27,7 +28,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/media"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop"
tools:src="@drawable/profile_image_nyan_sakamoto"/>
<ProgressBar
android:id="@+id/media_preview_progress"
@ -35,5 +37,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_large"/>
android:layout_margin="@dimen/element_spacing_large"
android:visibility="gone"/>
</merge>

View File

@ -30,6 +30,7 @@
android:orientation="horizontal"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
app:backgroundColor="?cardItemBackgroundColor"
app:ignorePadding="true"
tools:context=".adapter.DirectMessagesEntryAdapter">
@ -74,6 +75,7 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
tools:text="Mariotaku Lee"/>
<org.mariotaku.twidere.view.HandleSpanClickTextView

View File

@ -10,9 +10,12 @@
<attr name="menuIconColorActionBar" format="color"/>
<attr name="messageBubbleColor" format="color"/>
<attr name="cardItemBackgroundColor" format="color"/>
<attr name="ignorePadding" format="boolean"/>
<attr name="linePageIndicatorStyle" format="reference"/>
</declare-styleable>
<declare-styleable name="ColorLabelView" >
<attr name="ignorePadding" format="boolean"/>
<attr name="backgroundColor" format="color"/>
</declare-styleable>
<declare-styleable name="TabPagerIndicator">
<attr name="tabStripColor" format="color"/>
<attr name="tabIconColor" format="color"/>

View File

@ -4,7 +4,7 @@
<color name="nyan_background">#003366</color>
<color name="bg_color_light">#e5e5e5</color>
<color name="bg_color_dark">#101010</color>
<color name="bg_refresh_progress_color_light">#e5e5e5</color>
<color name="bg_refresh_progress_color_light">#f5f5f5</color>
<color name="bg_refresh_progress_color_dark">#333333</color>
<color name="bg_color_transparent_dark">#ff000000</color>
<color name="bg_color_transparent_light">#ffffffff</color>