diff --git a/build.gradle b/build.gradle
index 301f12951..888109126 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.github.ben-manes.versions'
-apply plugin: 'com.github.hierynomus.license'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
@@ -15,7 +14,6 @@ buildscript {
// should be excluded to avoid conflict
exclude group: 'xerces'
}
- classpath 'gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.12.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 30d399d8d..fd7e590e5 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 50c99ee33..5d18332f7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Aug 19 14:17:02 CST 2015
+#Sun Nov 08 17:18:47 CST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
diff --git a/twidere/build.gradle b/twidere/build.gradle
index 5a6574f82..e8e5eb6a8 100644
--- a/twidere/build.gradle
+++ b/twidere/build.gradle
@@ -93,11 +93,12 @@ dependencies {
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1'
compile 'com.github.mariotaku:PickNCrop:1dff3ed574'
+ compile 'com.github.mariotaku:RestFu:0.9.2'
compile 'com.diogobernardino:williamchart:2.0.1'
compile 'com.lnikkila:extendedtouchview:0.1.0'
compile 'com.google.dagger:dagger:2.0.1'
compile 'org.attoparser:attoparser:1.4.0.RELEASE'
- googleCompile 'com.google.android.gms:play-services-maps:8.1.0'
+ googleCompile 'com.google.android.gms:play-services-maps:8.3.0'
googleCompile 'com.google.maps.android:android-maps-utils:0.4'
fdroidCompile 'org.osmdroid:osmdroid-android:4.3'
fdroidCompile 'org.slf4j:slf4j-simple:1.7.12'
diff --git a/twidere/src/main/AndroidManifest.xml b/twidere/src/main/AndroidManifest.xml
index 2b75df2a3..135c5eba2 100644
--- a/twidere/src/main/AndroidManifest.xml
+++ b/twidere/src/main/AndroidManifest.xml
@@ -341,6 +341,10 @@
+
+ *
+ * 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 .
+ */
+
+/*
+ * Created on Nov 21, 2005
+ */
+package jopt.csp.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.collections.primitives.ArrayIntList;
+import org.apache.commons.collections.primitives.IntCollection;
+import org.apache.commons.collections.primitives.IntList;
+import org.apache.commons.collections.primitives.RandomAccessIntList;
+
+
+/**
+ * A flexible, sortable list of int primitives. Borrows much
+ * of its functionality from the ArrayIntList implementation
+ * given in the Commons Primitives project
+ * (http://jakarta.apache.org/commons/primitives/index.html)
+ *
+ * @author Chris Johnson
+ */
+public class SortableIntList extends RandomAccessIntList implements IntList, Serializable {
+
+ private transient int[] data = null;
+ private int size = 0;
+
+ /**
+ * Construct an empty list with the default
+ * initial capacity.
+ */
+ public SortableIntList() {
+ this(8);
+ }
+
+ /**
+ * Construct an empty list with the given
+ * initial capacity.
+ *
+ * @throws IllegalArgumentException when initialCapacity is negative
+ */
+ public SortableIntList(int initialCapacity) {
+ if (initialCapacity < 0) {
+ throw new IllegalArgumentException("capacity " + initialCapacity + " cannot be negative");
+ }
+ data = new int[initialCapacity];
+ size = 0;
+ }
+
+ /**
+ * Constructs a list containing the elements of the given collection,
+ * in the order they are returned by that collection's iterator.
+ *
+ * @param that the non-null collection of ints
+ * to add
+ * @throws NullPointerException if that is null
+ * @see ArrayIntList#addAll(org.apache.commons.collections.primitives.IntCollection)
+ */
+ public SortableIntList(IntCollection that) {
+ this(that.size());
+ addAll(that);
+ }
+
+ @Override
+ public int get(int index) {
+ checkRange(index);
+ return data[index];
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Removes the element at the specified position in
+ * (optional operation). Any subsequent elements
+ * are shifted to the left, subtracting one from their
+ * indices. Returns the element that was removed.
+ *
+ * @param index the index of the element to remove
+ * @return the value of the element that was removed
+ * @throws UnsupportedOperationException when this operation is not
+ * supported
+ * @throws IndexOutOfBoundsException if the specified index is out of range
+ */
+ @Override
+ public int removeElementAt(int index) {
+ checkRange(index);
+ incrModCount();
+ int oldval = data[index];
+ int numtomove = size - index - 1;
+ if (numtomove > 0) {
+ System.arraycopy(data, index + 1, data, index, numtomove);
+ }
+ size--;
+ return oldval;
+ }
+
+ /**
+ * Replaces the element at the specified
+ * position in me with the specified element
+ * (optional operation). If specified index is
+ * beyond the current size, the list grows
+ * to accommodate it. No IndexOutOfBoundsException
+ * will occur during the set operation.
+ *
+ * @param index the index of the element to change
+ * @param element the value to be stored at the specified position
+ * @return the value previously stored at the specified position
+ * @throws UnsupportedOperationException when this operation is not
+ * supported
+ */
+ @Override
+ public int set(int index, int element) {
+ ensureCapacity(index + 1);
+ ensureSize(index + 1);
+ incrModCount();
+ int oldval = data[index];
+ data[index] = element;
+ return oldval;
+ }
+
+ /**
+ * Inserts the specified element at the specified position
+ * (optional operation). Shifts the element currently
+ * at that position (if any) and any subsequent elements to the
+ * right, increasing their indices. If the specified index is
+ * beyond the current size, this method behaves like a call
+ * to {@link #set(int, int)}.
+ *
+ * @param index the index at which to insert the element
+ * @param element the value to insert
+ * @throws UnsupportedOperationException when this operation is not
+ * supported
+ * @throws IllegalArgumentException if some aspect of the specified element
+ * prevents it from being added to me
+ */
+ @Override
+ public void add(int index, int element) {
+ if (index >= size) {
+ set(index, element);
+ } else {
+ incrModCount();
+ ensureCapacity(size + 1);
+ int numtomove = size - index;
+ System.arraycopy(data, index, data, index + 1, numtomove);
+ data[index] = element;
+ size++;
+ }
+ }
+
+ /**
+ * Increases my capacity, if necessary, to ensure that I can hold at
+ * least the number of elements specified by the minimum capacity
+ * argument without growing.
+ */
+ public void ensureCapacity(int mincap) {
+ incrModCount();
+ if (mincap > data.length) {
+ int newcap = (data.length * 3) / 2 + 1;
+ int[] olddata = data;
+ data = new int[newcap < mincap ? mincap : newcap];
+ System.arraycopy(olddata, 0, data, 0, size);
+ }
+ }
+
+ /**
+ * Reduce my capacity, if necessary, to match my
+ * current {@link #size size}.
+ */
+ public void trimToSize() {
+ incrModCount();
+ if (size < data.length) {
+ int[] olddata = data;
+ data = new int[size];
+ System.arraycopy(olddata, 0, data, 0, size);
+ }
+ }
+
+ /**
+ * Sorts the list into ascending numerical order via {@link java.util.Arrays#sort(int[])}
+ *
+ * Sorts the list of ints into ascending numerical order. The sorting algorithm
+ * is a tuned quicksort, adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering
+ * a Sort Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
+ * 1993). This algorithm offers n*log(n) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance.
+ */
+ public void sort() {
+ trimToSize();
+ Arrays.sort(data);
+ }
+
+ /**
+ * Reverses the order of the elements
+ */
+ public void reverse() {
+ for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--)
+ swap(i, j);
+ }
+
+ /**
+ * Swaps the two specified elements.
+ * (If the specified positions are equal, invoking this method leaves
+ * the list unchanged.)
+ */
+ public void swap(int i, int j) {
+ int tmp = data[i];
+ data[i] = data[j];
+ data[j] = tmp;
+ }
+
+ /**
+ * Searches the list for the specified key via {@link java.util.Arrays#binarySearch(int[], int)}
+ *
+ * The array must be sorted (as by the sort method, above) prior to making this call.
+ * If it is not sorted, the results are undefined. If the list contains multiple elements
+ * with the specified value, there is no guarantee which one will be found.
+ *
+ * @param key the value to be searched for
+ * @return index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1)
+ */
+ public int binarySearch(int key) {
+ trimToSize();
+ return Arrays.binarySearch(data, key);
+ }
+
+ /**
+ * Sorts the specified range of the list into ascending numerical order
+ * via {@link java.util.Arrays#sort(int[], int, int)}
+ *
+ * @param fromIndex the index of the first element (inclusive) to be sorted
+ * @param toIndex the index of the last element (exclusive) to be sorted
+ */
+ public void sort(int fromIndex, int toIndex) {
+ trimToSize();
+ Arrays.sort(data, fromIndex, toIndex);
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(data.length);
+ for (int i = 0; i < size; i++) {
+ out.writeInt(data[i]);
+ }
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ data = new int[in.readInt()];
+ for (int i = 0; i < size; i++) {
+ data[i] = in.readInt();
+ }
+ }
+
+ private void ensureSize(int potentialSize) {
+ if (potentialSize > size) {
+ size = potentialSize;
+ }
+ }
+
+ private void checkRange(int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException("Should be at least 0 and less than " + size + ", found " + index);
+ }
+ }
+
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/CopyLinkActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/CopyLinkActivity.java
new file mode 100644
index 000000000..8575c2ff9
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/CopyLinkActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Twidere - Twitter client for Android
+ *
+ * Copyright (C) 2012-2015 Mariotaku Lee
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.mariotaku.twidere.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import org.mariotaku.twidere.Constants;
+import org.mariotaku.twidere.R;
+import org.mariotaku.twidere.util.ClipboardUtils;
+
+public class CopyLinkActivity extends Activity implements Constants {
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ClipboardUtils.setText(this, getIntent().getDataString());
+ Toast.makeText(this, R.string.link_copied_to_clipboard, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java
index b15418e10..484e4b765 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/QuickSearchBarActivity.java
@@ -19,6 +19,7 @@
package org.mariotaku.twidere.activity.support;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -44,38 +45,42 @@ import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
-import com.mobeta.android.dslv.DragSortCursorAdapter;
-
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableCredentials;
+import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory;
import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions;
import org.mariotaku.twidere.util.EditTextEnterHandler;
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.ParseUtils;
+import org.mariotaku.twidere.util.SwipeDismissListViewTouchListener;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.util.Utils;
+import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.view.ExtendedRelativeLayout;
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener;
import java.util.List;
+import jopt.csp.util.SortableIntList;
+
/**
* Created by mariotaku on 15/1/6.
*/
public class QuickSearchBarActivity extends ThemedFragmentActivity implements OnClickListener,
LoaderCallbacks, OnItemSelectedListener, OnItemClickListener,
- OnFitSystemWindowsListener {
+ OnFitSystemWindowsListener, SwipeDismissListViewTouchListener.DismissCallbacks {
private Spinner mAccountSpinner;
private EditText mSearchQuery;
@@ -86,19 +91,24 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
private Rect mSystemWindowsInsets = new Rect();
private boolean mTextChanged;
+ @Override
+ public boolean canDismiss(int position) {
+ return mUsersSearchAdapter.getItemViewType(position) == SuggestionsAdapter.VIEW_TYPE_SEARCH_HISTORY;
+ }
+
+ @Override
public void onDismiss(ListView listView, int[] reverseSortedPositions) {
-// final long[] ids = new long[reverseSortedPositions.length];
-// for (int i = 0, j = reverseSortedPositions.length; i < j; i++) {
-// final int position = reverseSortedPositions[i];
-// final SearchHistoryItem item = (SearchHistoryItem) mUsersSearchAdapter.getItem(position);
-// mUsersSearchAdapter.removeItemAt(position);
-// ids[i] = item.getCursorId();
-// }
-// final ContentResolver cr = getContentResolver();
-// final Long[] idsObject = ArrayUtils.toObject(ids);
-// ContentResolverUtils.bulkDelete(cr, SearchHistory.CONTENT_URI, SearchHistory._ID, idsObject,
-// null, false);
-// getSupportLoaderManager().restartLoader(0, null, this);
+ final Long[] ids = new Long[reverseSortedPositions.length];
+ for (int i = 0, j = reverseSortedPositions.length; i < j; i++) {
+ final int position = reverseSortedPositions[i];
+ final SuggestionItem item = mUsersSearchAdapter.getSuggestionItem(position);
+ ids[i] = item._id;
+ }
+ mUsersSearchAdapter.addRemovedPositions(reverseSortedPositions);
+ final ContentResolver cr = getContentResolver();
+ ContentResolverUtils.bulkDelete(cr, SearchHistory.CONTENT_URI, SearchHistory._ID, ids,
+ null, false);
+ getSupportLoaderManager().restartLoader(0, null, this);
}
@Override
@@ -224,6 +234,10 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
mUsersSearchAdapter = new SuggestionsAdapter(this);
mSuggestionsList.setAdapter(mUsersSearchAdapter);
mSuggestionsList.setOnItemClickListener(this);
+
+ final SwipeDismissListViewTouchListener listener = new SwipeDismissListViewTouchListener(mSuggestionsList, this);
+ mSuggestionsList.setOnTouchListener(listener);
+ mSuggestionsList.setOnScrollListener(listener.makeScrollListener());
mSearchSubmit.setOnClickListener(this);
EditTextEnterHandler.attach(mSearchQuery, new EnterListener() {
@@ -296,16 +310,17 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
public final String title, summary;
- private final long extra_id;
+ public final long _id, extra_id;
public SuggestionItem(Cursor cursor, SuggestionsAdapter.Indices indices) {
+ _id = cursor.getLong(indices._id);
title = cursor.getString(indices.title);
summary = cursor.getString(indices.summary);
extra_id = cursor.getLong(indices.extra_id);
}
}
- public static class SuggestionsAdapter extends DragSortCursorAdapter implements OnClickListener {
+ public static class SuggestionsAdapter extends CursorAdapter implements OnClickListener {
static final int VIEW_TYPE_SEARCH_HISTORY = 0;
static final int VIEW_TYPE_SAVED_SEARCH = 1;
@@ -316,24 +331,21 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
private final MediaLoaderWrapper mImageLoader;
private final UserColorNameManager mUserColorNameManager;
private final QuickSearchBarActivity mActivity;
+ private final SortableIntList mRemovedPositions;
private Indices mIndices;
SuggestionsAdapter(QuickSearchBarActivity activity) {
super(activity, null, 0);
+ mRemovedPositions = new SortableIntList();
mActivity = activity;
mImageLoader = activity.mImageLoader;
mUserColorNameManager = activity.mUserColorNameManager;
mInflater = LayoutInflater.from(activity);
}
- @Override
- public long getItemId(int position) {
- return position;
- }
-
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- switch (getItemViewType(cursor.getPosition())) {
+ switch (getActualItemViewType(cursor.getPosition())) {
case VIEW_TYPE_SEARCH_HISTORY:
case VIEW_TYPE_SAVED_SEARCH: {
final View view = mInflater.inflate(R.layout.list_item_suggestion_search, parent, false);
@@ -353,13 +365,13 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
}
public SuggestionItem getSuggestionItem(int position) {
- final Cursor cursor = (Cursor) super.getItem(position);
+ final Cursor cursor = (Cursor) getItem(position);
return new SuggestionItem(cursor, mIndices);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- switch (getItemViewType(cursor.getPosition())) {
+ switch (getActualItemViewType(cursor.getPosition())) {
case VIEW_TYPE_SEARCH_HISTORY: {
final SearchViewHolder holder = (SearchViewHolder) view.getTag();
final String title = cursor.getString(mIndices.title);
@@ -400,7 +412,11 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
@Override
public int getItemViewType(int position) {
- final Cursor cursor = (Cursor) getItem(position);
+ return getActualItemViewType(getActualPosition(position));
+ }
+
+ public int getActualItemViewType(int position) {
+ final Cursor cursor = (Cursor) super.getItem(position);
switch (cursor.getString(mIndices.type)) {
case Suggestions.Search.TYPE_SAVED_SEARCH: {
return VIEW_TYPE_SAVED_SEARCH;
@@ -440,9 +456,55 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
} else {
mIndices = null;
}
+ mRemovedPositions.clear();
return super.swapCursor(newCursor);
}
+ @Override
+ public int getCount() {
+ if (mRemovedPositions == null) return super.getCount();
+ return super.getCount() - mRemovedPositions.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return super.getItem(getActualPosition(position));
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return super.getItemId(getActualPosition(position));
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return super.getView(getActualPosition(position), convertView, parent);
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return super.getDropDownView(getActualPosition(position), convertView, parent);
+ }
+
+ private int getActualPosition(int position) {
+ if (mRemovedPositions == null) return position;
+ int skipped = 0;
+ for (int i = 0, j = mRemovedPositions.size(); i < j; i++) {
+ if (position + skipped >= mRemovedPositions.get(i)) {
+ skipped++;
+ }
+ }
+ return position + skipped;
+ }
+
+ public void addRemovedPositions(int[] positions) {
+ for (int position : positions) {
+ mRemovedPositions.add(getActualPosition(position));
+ }
+ mRemovedPositions.sort();
+ notifyDataSetChanged();
+ }
+
static class SearchViewHolder {
private final ImageView icon;
@@ -471,6 +533,7 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
}
private static class Indices {
+ private final int _id;
private final int type;
private final int title;
private final int summary;
@@ -478,6 +541,7 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
private final int extra_id;
public Indices(Cursor cursor) {
+ _id = cursor.getColumnIndex(Suggestions._ID);
type = cursor.getColumnIndex(Suggestions.TYPE);
title = cursor.getColumnIndex(Suggestions.TITLE);
summary = cursor.getColumnIndex(Suggestions.SUMMARY);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java
index caf8c0948..80d77dafa 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java
@@ -58,7 +58,8 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
* Created by mariotaku on 15/1/3.
*/
public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter implements Constants,
- IActivitiesAdapter, IStatusViewHolder.StatusClickListener, OnLinkClickListener, ActivityTitleSummaryViewHolder.ActivityClickListener {
+ IActivitiesAdapter, IStatusViewHolder.StatusClickListener, OnLinkClickListener,
+ ActivityTitleSummaryViewHolder.ActivityClickListener {
private static final int ITEM_VIEW_TYPE_STUB = 0;
private static final int ITEM_VIEW_TYPE_GAP = 1;
@@ -75,6 +76,7 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter<
private final boolean mDisplayMediaPreview;
private final boolean mNameFirst;
private final boolean mDisplayProfileImage;
+ private final boolean mShouldUseStarsForLikes;
private final TwidereLinkify mLinkify;
private final DummyStatusHolderAdapter mStatusAdapterDelegate;
private ActivityAdapterListener mActivityAdapterListener;
@@ -87,6 +89,7 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter<
mInflater = LayoutInflater.from(context);
mLoadingHandler = new MediaLoadingHandler(R.id.media_preview_progress);
mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
+ mShouldUseStarsForLikes = mPreferences.getBoolean(KEY_I_WANT_MY_STARS_BACK);
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(mPreferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
@@ -175,6 +178,11 @@ public abstract class AbsActivitiesAdapter extends LoadMoreSupportAdapter<
}
+ @Override
+ public boolean shouldUseStarsForLikes() {
+ return mShouldUseStarsForLikes;
+ }
+
@Override
public void onUserProfileClick(IStatusViewHolder holder, int position) {
final Context context = getContext();
diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java
index 690785bfc..868781fea 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IActivitiesAdapter.java
@@ -19,10 +19,7 @@
package org.mariotaku.twidere.adapter.iface;
-import android.support.annotation.NonNull;
-
import org.mariotaku.twidere.model.ParcelableActivity;
-import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
@@ -40,9 +37,7 @@ public interface IActivitiesAdapter extends IContentCardAdapter, IGapSuppo
@PreviewStyle
int getMediaPreviewStyle();
- @NonNull
- @Override
- MediaLoaderWrapper getMediaLoader();
+ boolean shouldUseStarsForLikes();
MediaLoadingHandler getMediaLoadingHandler();
}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
index 41a50cd76..e759fa460 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
@@ -34,6 +34,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
+import org.mariotaku.twidere.util.LinkCreator;
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
import org.mariotaku.twidere.util.RecyclerViewUtils;
import org.mariotaku.twidere.util.Utils;
@@ -121,7 +122,9 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi
if (status == null) return false;
if (item.getItemId() == R.id.share) {
final Intent shareIntent = Utils.createStatusShareIntent(getActivity(), status);
- startActivity(Intent.createChooser(shareIntent, getString(R.string.share_status)));
+ final Intent chooser = Intent.createChooser(shareIntent, getString(R.string.share_status));
+ Utils.addCopyLinkIntent(getContext(), chooser, LinkCreator.getTwitterStatusLink(status));
+ startActivity(chooser);
return true;
}
return Utils.handleMenuItemClick(getActivity(), AbsStatusesFragment.this,
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/RetweetQuoteDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/RetweetQuoteDialogFragment.java
index 7d5eded23..8fb147175 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/RetweetQuoteDialogFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/RetweetQuoteDialogFragment.java
@@ -203,7 +203,7 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
} else {
positiveButton.setText(isMyRetweet(status) ? R.string.cancel_retweet : R.string.retweet);
}
- final String statusLink = LinkCreator.getTwitterStatusLink(status.user_screen_name, status.id).toString();
+ final String statusLink = LinkCreator.getTwitterStatusLink(status).toString();
final StatusTextCountView textCountView = (StatusTextCountView) alertDialog.findViewById(R.id.comment_text_count);
textCountView.setTextCount(mValidator.getTweetLength(s + " " + statusLink));
}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
index 3c02a14be..b003c8e59 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
@@ -288,7 +288,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final ParcelableStatus status = getStatus();
if (status == null) return null;
return new NdefMessage(new NdefRecord[]{
- NdefRecord.createUri(LinkCreator.getTwitterStatusLink(status.user_screen_name, status.id)),
+ NdefRecord.createUri(LinkCreator.getTwitterStatusLink(status)),
});
}
});
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
index 38b2b6353..8832c8e24 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
@@ -62,7 +62,6 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.internal.widget.ActionBarContainer;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
-import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -869,9 +868,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
final MenuItem muteItem = menu.findItem(R.id.mute_user);
if (muteItem != null) {
- final boolean muting = relationship.isSourceMutingTarget();
- ActionIconDrawable.setMenuHighlight(muteItem, new TwidereMenuInfo(muting));
- muteItem.setTitle(muting ? R.string.unmute : R.string.mute);
+ muteItem.setChecked(relationship.isSourceMutingTarget());
}
final MenuItem filterItem = menu.findItem(R.id.add_to_filter);
if (filterItem != null) {
@@ -881,7 +878,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
final MenuItem wantRetweetsItem = menu.findItem(R.id.enable_retweets);
if (wantRetweetsItem != null) {
-
wantRetweetsItem.setChecked(relationship.isSourceWantRetweetsFromTarget());
}
} else {
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java
index fb3c17bd9..9ebe31621 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java
@@ -400,7 +400,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
private void setupUserPages() {
final Bundle args = getArguments(), tabArgs = new Bundle();
- if (args.containsKey(EXTRA_USER)) {
+ if (args.containsKey(EXTRA_USER_LIST)) {
final ParcelableUserList userList = args.getParcelable(EXTRA_USER_LIST);
tabArgs.putLong(EXTRA_ACCOUNT_ID, userList.account_id);
tabArgs.putLong(EXTRA_USER_ID, userList.user_id);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java
index ac8eeaec4..af9b81664 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListMembersFragment.java
@@ -26,17 +26,15 @@ import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
-import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
-import org.mariotaku.twidere.loader.support.UserListMembersLoader;
-import org.mariotaku.twidere.model.ParcelableUserList;
-import org.mariotaku.twidere.util.AsyncTaskUtils;
-import org.mariotaku.twidere.util.TwitterAPIFactory;
-
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.UserList;
-
-import static org.mariotaku.twidere.util.TwitterAPIFactory.getTwitterInstance;
+import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
+import org.mariotaku.twidere.loader.support.UserListMembersLoader;
+import org.mariotaku.twidere.model.ParcelableUserList;
+import org.mariotaku.twidere.model.SingleResponse;
+import org.mariotaku.twidere.util.AsyncTaskUtils;
+import org.mariotaku.twidere.util.TwitterAPIFactory;
public class UserListMembersFragment extends CursorSupportUsersListFragment {
@@ -107,7 +105,7 @@ public class UserListMembersFragment extends CursorSupportUsersListFragment {
super.onStop();
}
- private class GetUserListTask extends AsyncTask
+ *
+ * @see SwipeDismissListViewTouchListener
+ */
+ public AbsListView.OnScrollListener makeScrollListener() {
+ return new AbsListView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(AbsListView absListView, int scrollState) {
+ setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ }
+
+ @Override
+ public void onScroll(AbsListView absListView, int i, int i1, int i2) {
+ }
+ };
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (mViewWidth < 2) {
+ mViewWidth = mListView.getWidth();
+ }
+
+ switch (motionEvent.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN: {
+ if (mPaused) {
+ return false;
+ }
+
+ // TODO: ensure this is a finger, and set a flag
+
+ // Find the child view that was touched (perform a hit test)
+ Rect rect = new Rect();
+ int childCount = mListView.getChildCount();
+ int[] listViewCoords = new int[2];
+ mListView.getLocationOnScreen(listViewCoords);
+ int x = (int) motionEvent.getRawX() - listViewCoords[0];
+ int y = (int) motionEvent.getRawY() - listViewCoords[1];
+ View child;
+ for (int i = 0; i < childCount; i++) {
+ child = mListView.getChildAt(i);
+ child.getHitRect(rect);
+ if (rect.contains(x, y)) {
+ mDownView = child;
+ break;
+ }
+ }
+
+ if (mDownView != null) {
+ mDownX = motionEvent.getRawX();
+ mDownY = motionEvent.getRawY();
+ mDownPosition = mListView.getPositionForView(mDownView);
+ if (mCallbacks.canDismiss(mDownPosition)) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mVelocityTracker.addMovement(motionEvent);
+ } else {
+ mDownView = null;
+ }
+ }
+ return false;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ if (mDownView != null && mSwiping) {
+ // cancel
+ mDownView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mDownX = 0;
+ mDownY = 0;
+ mDownView = null;
+ mDownPosition = ListView.INVALID_POSITION;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ if (mVelocityTracker == null) {
+ break;
+ }
+
+ float deltaX = motionEvent.getRawX() - mDownX;
+ mVelocityTracker.addMovement(motionEvent);
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float velocityX = mVelocityTracker.getXVelocity();
+ float absVelocityX = Math.abs(velocityX);
+ float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
+ boolean dismiss = false;
+ boolean dismissRight = false;
+ if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) {
+ dismiss = true;
+ dismissRight = deltaX > 0;
+ } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
+ && absVelocityY < absVelocityX && mSwiping) {
+ // dismiss only if flinging in the same direction as dragging
+ dismiss = (velocityX < 0) == (deltaX < 0);
+ dismissRight = mVelocityTracker.getXVelocity() > 0;
+ }
+ if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
+ // dismiss
+ final View downView = mDownView; // mDownView gets null'd before animation ends
+ final int downPosition = mDownPosition;
+ ++mDismissAnimationRefCount;
+ mDownView.animate()
+ .translationX(dismissRight ? mViewWidth : -mViewWidth)
+ .alpha(0)
+ .setDuration(mAnimationTime)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ performDismiss(downView, downPosition);
+ }
+ });
+ } else {
+ // cancel
+ mDownView.animate()
+ .translationX(0)
+ .alpha(1)
+ .setDuration(mAnimationTime)
+ .setListener(null);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mDownX = 0;
+ mDownY = 0;
+ mDownView = null;
+ mDownPosition = ListView.INVALID_POSITION;
+ mSwiping = false;
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ if (mVelocityTracker == null || mPaused) {
+ break;
+ }
+
+ mVelocityTracker.addMovement(motionEvent);
+ float deltaX = motionEvent.getRawX() - mDownX;
+ float deltaY = motionEvent.getRawY() - mDownY;
+ if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
+ mSwiping = true;
+ mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
+ mListView.requestDisallowInterceptTouchEvent(true);
+
+ // Cancel ListView's touch (un-highlighting the item)
+ MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
+ (motionEvent.getActionIndex()
+ << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
+ mListView.onTouchEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
+ if (mSwiping) {
+ mDownView.setTranslationX(deltaX - mSwipingSlop);
+ mDownView.setAlpha(Math.max(0f, Math.min(1f,
+ 1f - 2f * Math.abs(deltaX) / mViewWidth)));
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+
+ class PendingDismissData implements Comparable {
+ public int position;
+ public View view;
+
+ public PendingDismissData(int position, View view) {
+ this.position = position;
+ this.view = view;
+ }
+
+ @Override
+ public int compareTo(@NonNull PendingDismissData other) {
+ // Sort by descending position
+ return other.position - position;
+ }
+ }
+
+ private void performDismiss(final View dismissView, final int dismissPosition) {
+ // Animate the dismissed list item to zero-height and fire the dismiss callback when
+ // all dismissed list item animations have completed. This triggers layout on each animation
+ // frame; in the future we may want to do something smarter and more performant.
+
+ final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
+ final int originalHeight = dismissView.getHeight();
+
+ ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
+
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ --mDismissAnimationRefCount;
+ if (mDismissAnimationRefCount == 0) {
+ // No active animations, process all pending dismisses.
+ // Sort by descending position
+ Collections.sort(mPendingDismisses);
+
+ int[] dismissPositions = new int[mPendingDismisses.size()];
+ for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
+ dismissPositions[i] = mPendingDismisses.get(i).position;
+ }
+ mCallbacks.onDismiss(mListView, dismissPositions);
+
+ // Reset mDownPosition to avoid MotionEvent.ACTION_UP trying to start a dismiss
+ // animation with a stale position
+ mDownPosition = ListView.INVALID_POSITION;
+
+ ViewGroup.LayoutParams lp;
+ for (PendingDismissData pendingDismiss : mPendingDismisses) {
+ // Reset view presentation
+ pendingDismiss.view.setAlpha(1f);
+ pendingDismiss.view.setTranslationX(0);
+ lp = pendingDismiss.view.getLayoutParams();
+ lp.height = originalHeight;
+ pendingDismiss.view.setLayoutParams(lp);
+ }
+
+ // Send a cancel event
+ long time = SystemClock.uptimeMillis();
+ MotionEvent cancelEvent = MotionEvent.obtain(time, time,
+ MotionEvent.ACTION_CANCEL, 0, 0, 0);
+ mListView.dispatchTouchEvent(cancelEvent);
+
+ mPendingDismisses.clear();
+ }
+ }
+ });
+
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ lp.height = (Integer) valueAnimator.getAnimatedValue();
+ dismissView.setLayoutParams(lp);
+ }
+ });
+
+ mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
+ animator.start();
+ }
+}
\ No newline at end of file
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
index 2c38dddc2..082c97a0b 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
@@ -134,6 +134,7 @@ import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
+import org.mariotaku.twidere.activity.CopyLinkActivity;
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
import org.mariotaku.twidere.activity.support.MediaViewerActivity;
@@ -197,6 +198,7 @@ import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
+import org.mariotaku.twidere.model.ParcelableUserMention;
import org.mariotaku.twidere.model.PebbleMessage;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
@@ -1181,7 +1183,7 @@ public final class Utils implements Constants {
}
public static String getStatusShareText(@NonNull final Context context, @NonNull final ParcelableStatus status) {
- final Uri link = LinkCreator.getTwitterStatusLink(status.user_screen_name, status.id);
+ final Uri link = LinkCreator.getTwitterStatusLink(status);
return context.getString(R.string.status_share_text_format_with_link,
status.text_plain, link.toString());
}
@@ -1631,6 +1633,15 @@ public final class Utils implements Constants {
return textView;
}
+ public static boolean setLastSeen(Context context, ParcelableUserMention[] entities, long time) {
+ if (entities == null) return false;
+ boolean result = false;
+ for (ParcelableUserMention entity : entities) {
+ result |= setLastSeen(context, entity.id, time);
+ }
+ return result;
+ }
+
public static boolean setLastSeen(Context context, UserMentionEntity[] entities, long time) {
if (entities == null) return false;
boolean result = false;
@@ -3379,11 +3390,20 @@ public final class Utils implements Constants {
addIntentToMenu(context, shareSubMenu, shareIntent, MENU_GROUP_STATUS_SHARE);
} else {
final Intent shareIntent = createStatusShareIntent(context, status);
- shareItem.setIntent(Intent.createChooser(shareIntent, context.getString(R.string.share_status)));
+ final Intent chooserIntent = Intent.createChooser(shareIntent, context.getString(R.string.share_status));
+ addCopyLinkIntent(context, chooserIntent, LinkCreator.getTwitterStatusLink(status));
+ shareItem.setIntent(chooserIntent);
}
}
+ public static void addCopyLinkIntent(Context context, Intent chooserIntent, Uri uri) {
+ final Intent copyLinkIntent = new Intent(context, CopyLinkActivity.class);
+ copyLinkIntent.setData(uri);
+ final Intent[] alternateIntents = {copyLinkIntent};
+ chooserIntent.putExtra(Intent.EXTRA_ALTERNATE_INTENTS, alternateIntents);
+ }
+
private static boolean isMyStatus(ParcelableStatus status) {
if (isMyRetweet(status)) return true;
return status.account_id == status.user_id;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.java
index 0d6c700d3..7e37dcc35 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.java
@@ -102,14 +102,28 @@ public class ActivityTitleSummaryViewHolder extends ViewHolder implements View.O
break;
}
case Activity.ACTION_FAVORITE: {
- activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
- activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
- if (byFriends) {
- titleView.setText(getTitleStringByFriends(R.string.activity_by_friends_favorite,
- R.string.activity_by_friends_favorite_multi, activity.sources, activity.target_statuses));
+ if (adapter.shouldUseStarsForLikes()) {
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_favorite), Mode.SRC_ATOP);
+
+ if (byFriends) {
+ titleView.setText(getTitleStringByFriends(R.string.activity_by_friends_favorite,
+ R.string.activity_by_friends_favorite_multi, activity.sources, activity.target_statuses));
+ } else {
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_favorite,
+ R.string.activity_about_me_favorite_multi, activity.sources));
+ }
} else {
- titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_favorite,
- R.string.activity_about_me_favorite_multi, activity.sources));
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_like);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
+
+ if (byFriends) {
+ titleView.setText(getTitleStringByFriends(R.string.activity_by_friends_like,
+ R.string.activity_by_friends_like_multi, activity.sources, activity.target_statuses));
+ } else {
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_like,
+ R.string.activity_about_me_like_multi, activity.sources));
+ }
}
displayUserProfileImages(activity.sources);
summaryView.setText(activity.target_statuses[0].text_unescaped);
@@ -135,10 +149,17 @@ public class ActivityTitleSummaryViewHolder extends ViewHolder implements View.O
showNotSupported();
return;
}
- activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
- activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
- titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_favorited_retweet,
- R.string.activity_about_me_favorited_retweet_multi, activity.sources));
+ if (adapter.shouldUseStarsForLikes()) {
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_favorite), Mode.SRC_ATOP);
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_favorited_retweet,
+ R.string.activity_about_me_favorited_retweet_multi, activity.sources));
+ } else {
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_like);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_liked_retweet,
+ R.string.activity_about_me_liked_retweet_multi, activity.sources));
+ }
displayUserProfileImages(activity.sources);
summaryView.setText(activity.target_statuses[0].text_unescaped);
summaryView.setVisibility(View.VISIBLE);
@@ -177,10 +198,17 @@ public class ActivityTitleSummaryViewHolder extends ViewHolder implements View.O
showNotSupported();
return;
}
- activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
- activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
- titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_liked_mention,
- R.string.activity_about_me_liked_mention_multi, activity.sources));
+ if (adapter.shouldUseStarsForLikes()) {
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_favorite);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_favorite), Mode.SRC_ATOP);
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_favorited_mention,
+ R.string.activity_about_me_favorited_mention_multi, activity.sources));
+ } else {
+ activityTypeView.setImageResource(R.drawable.ic_activity_action_like);
+ activityTypeView.setColorFilter(ContextCompat.getColor(context, R.color.highlight_like), Mode.SRC_ATOP);
+ titleView.setText(getTitleStringAboutMe(R.string.activity_about_me_liked_mention,
+ R.string.activity_about_me_liked_mention_multi, activity.sources));
+ }
displayUserProfileImages(activity.sources);
summaryView.setText(activity.target_statuses[0].text_unescaped);
summaryView.setVisibility(View.VISIBLE);
diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_favorite.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_favorite.png
new file mode 100644
index 000000000..c4b71586c
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_favorite.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_like.png b/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_like.png
new file mode 100644
index 000000000..76bf2a7ed
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-hdpi/ic_activity_action_like.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_favorite.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_favorite.png
new file mode 100644
index 000000000..24d927383
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_favorite.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_like.png b/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_like.png
new file mode 100644
index 000000000..616d6198b
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-mdpi/ic_activity_action_like.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_favorite.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_favorite.png
new file mode 100644
index 000000000..dd5d17e18
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_favorite.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_like.png b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_like.png
new file mode 100644
index 000000000..db9f1d6d4
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xhdpi/ic_activity_action_like.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_favorite.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_favorite.png
new file mode 100644
index 000000000..d1aaf4f68
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_favorite.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_like.png b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_like.png
new file mode 100644
index 000000000..152adbf0e
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxhdpi/ic_activity_action_like.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_favorite.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_favorite.png
new file mode 100644
index 000000000..a2e8fb55e
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_favorite.png differ
diff --git a/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_like.png b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_like.png
new file mode 100644
index 000000000..e6ab25af5
Binary files /dev/null and b/twidere/src/main/res-svg2png/drawable-xxxhdpi/ic_activity_action_like.png differ
diff --git a/twidere/src/main/res/drawable-hdpi/ic_activity_action_favorite.png b/twidere/src/main/res/drawable-hdpi/ic_activity_action_favorite.png
deleted file mode 100755
index 6d5a9b300..000000000
Binary files a/twidere/src/main/res/drawable-hdpi/ic_activity_action_favorite.png and /dev/null differ
diff --git a/twidere/src/main/res/drawable-mdpi/ic_activity_action_favorite.png b/twidere/src/main/res/drawable-mdpi/ic_activity_action_favorite.png
deleted file mode 100755
index 09d662b7f..000000000
Binary files a/twidere/src/main/res/drawable-mdpi/ic_activity_action_favorite.png and /dev/null differ
diff --git a/twidere/src/main/res/drawable-xhdpi/ic_activity_action_favorite.png b/twidere/src/main/res/drawable-xhdpi/ic_activity_action_favorite.png
deleted file mode 100755
index b2ef3e478..000000000
Binary files a/twidere/src/main/res/drawable-xhdpi/ic_activity_action_favorite.png and /dev/null differ
diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_activity_action_favorite.png b/twidere/src/main/res/drawable-xxhdpi/ic_activity_action_favorite.png
deleted file mode 100755
index fe555ff11..000000000
Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_activity_action_favorite.png and /dev/null differ
diff --git a/twidere/src/main/res/layout/list_item_compose_account.xml b/twidere/src/main/res/layout/list_item_compose_account.xml
new file mode 100644
index 000000000..acc025d68
--- /dev/null
+++ b/twidere/src/main/res/layout/list_item_compose_account.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/twidere/src/main/res/menu/menu_user_profile.xml b/twidere/src/main/res/menu/menu_user_profile.xml
index fb80c3467..f371d91f4 100644
--- a/twidere/src/main/res/menu/menu_user_profile.xml
+++ b/twidere/src/main/res/menu/menu_user_profile.xml
@@ -51,6 +51,7 @@
android:title="@string/enable_retweets" />
%1$s and %2$s favorited your tweet.
%s favorited your retweet.%1$s and %2$s favorited your retweet.
+ %s liked your tweet.
+ %1$s and %2$s liked your tweet.
+ %s liked your retweet.
+ %1$s and %2$s liked your retweet.%s is following you.%1$s and %2$s are following you.%s retweeted your tweet.
@@ -296,6 +300,8 @@
%1$s and %2$s added you to their lists.%1$s favorited %2$s\'s tweet.%1$s favorited %2$s and %3$s\'s tweet.
+ %1$s liked %2$s\'s tweet.
+ %1$s liked %2$s and %3$s\'s tweet.%1$s is following %2$s.%1$s is following %2$s and %3$s.%1$s retweeted %2$s\'s tweet.
@@ -811,4 +817,6 @@
Use special search terms to improve search results like exclude retweetsI want my stars back!Show use favorite (star) instead of like (heart)
+ Copy link
+ Link copied to clipboard
\ No newline at end of file
diff --git a/twidere/src/main/svg/drawable/ic_activity_action_favorite-mdpi.svg b/twidere/src/main/svg/drawable/ic_activity_action_favorite-mdpi.svg
new file mode 100644
index 000000000..fa3a669f6
--- /dev/null
+++ b/twidere/src/main/svg/drawable/ic_activity_action_favorite-mdpi.svg
@@ -0,0 +1,5 @@
+
diff --git a/twidere/src/main/svg/drawable/ic_activity_action_like-mdpi.svg b/twidere/src/main/svg/drawable/ic_activity_action_like-mdpi.svg
new file mode 100644
index 000000000..97d0679f0
--- /dev/null
+++ b/twidere/src/main/svg/drawable/ic_activity_action_like-mdpi.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file