removing old theme engine

supported multiple medias
added material icon resources
This commit is contained in:
Mariotaku Lee 2014-11-02 00:57:31 +08:00
parent 9b329b22cc
commit 22cce2c10f
146 changed files with 2908 additions and 4111 deletions

@ -1 +1 @@
Subproject commit 656190baf4700e7f6fe14394bb350690bdefbd53
Subproject commit e29a94571fc82349d46b2911729a55e7ab9e34c4

View File

@ -29,14 +29,12 @@ import android.view.MenuItem;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.MapView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.iface.IMapFragment;
import org.mariotaku.twidere.fragment.support.GoogleMapFragment;
import org.mariotaku.twidere.fragment.support.WebMapFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
@ -48,8 +46,8 @@ public class GoogleMapViewerActivity extends BaseSupportActivity implements Cons
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_google_maps_viewer, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_google_maps_viewer, menu);
return true;
}

View File

@ -49,7 +49,6 @@ import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.SaveImageTask;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
@ -150,8 +149,8 @@ public final class ImageViewerGLActivity extends BaseSupportActivity implements
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_image_viewer_action_bar, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_image_viewer_action_bar, menu);
return true;
}

View File

@ -1,46 +0,0 @@
package org.mariotaku.harmony.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
import android.widget.ListAdapter;
public class HorizontalGridView extends GridView {
public HorizontalGridView(final Context context) {
this(context, null);
}
public HorizontalGridView(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.gridViewStyle);
}
public HorizontalGridView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
setPivotX(0);
setPivotY(0);
setRotation(90);
setRotationY(180);
}
@Override
public ListAdapter getAdapter() {
final ListAdapter adapter = super.getAdapter();
return adapter instanceof HorizontalWrapperAdapter ? ((HorizontalWrapperAdapter) adapter).getWrapped()
: adapter;
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int w = MeasureSpec.getSize(widthMeasureSpec), h = MeasureSpec.getSize(heightMeasureSpec);
final int wSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY), hSpec = MeasureSpec.makeMeasureSpec(w,
MeasureSpec.EXACTLY);
setMeasuredDimension(h, w);
super.onMeasure(wSpec, hSpec);
}
@Override
public void setAdapter(final ListAdapter adapter) {
super.setAdapter(new HorizontalWrapperAdapter(adapter));
}
}

View File

@ -1,46 +0,0 @@
package org.mariotaku.harmony.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListAdapter;
import android.widget.ListView;
public class HorizontalListView extends ListView {
public HorizontalListView(final Context context) {
this(context, null);
}
public HorizontalListView(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.listViewStyle);
}
public HorizontalListView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
setPivotX(0);
setPivotY(0);
setRotation(90);
setRotationY(180);
}
@Override
public ListAdapter getAdapter() {
final ListAdapter adapter = super.getAdapter();
return adapter instanceof HorizontalWrapperAdapter ? ((HorizontalWrapperAdapter) adapter).getWrapped()
: adapter;
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int w = MeasureSpec.getSize(widthMeasureSpec), h = MeasureSpec.getSize(heightMeasureSpec);
final int wSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY), hSpec = MeasureSpec.makeMeasureSpec(w,
MeasureSpec.EXACTLY);
setMeasuredDimension(h, w);
super.onMeasure(wSpec, hSpec);
}
@Override
public void setAdapter(final ListAdapter adapter) {
super.setAdapter(new HorizontalWrapperAdapter(adapter));
}
}

View File

@ -1,87 +0,0 @@
package org.mariotaku.harmony.view;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
public final class HorizontalWrapperAdapter implements ListAdapter {
private final ListAdapter mAdapter;
HorizontalWrapperAdapter(final ListAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean areAllItemsEnabled() {
return mAdapter.areAllItemsEnabled();
}
@Override
public int getCount() {
return mAdapter.getCount();
}
@Override
public Object getItem(final int position) {
return mAdapter.getItem(position);
}
@Override
public long getItemId(final int position) {
return mAdapter.getItemId(position);
}
@Override
public int getItemViewType(final int position) {
return mAdapter.getItemViewType(position);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = mAdapter.getView(position, convertView, parent);
if (convertView == null) {
view.setPivotX(0);
view.setPivotX(0);
view.setRotation(view.getRotation() + 90);
view.setRotationY(view.getRotationY() + 180);
}
return view;
}
@Override
public int getViewTypeCount() {
return mAdapter.getViewTypeCount();
}
public ListAdapter getWrapped() {
return mAdapter;
}
@Override
public boolean hasStableIds() {
return mAdapter.hasStableIds();
}
@Override
public boolean isEmpty() {
return mAdapter.isEmpty();
}
@Override
public boolean isEnabled(final int position) {
return mAdapter.isEnabled(position);
}
@Override
public void registerDataSetObserver(final DataSetObserver observer) {
mAdapter.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(final DataSetObserver observer) {
mAdapter.unregisterDataSetObserver(observer);
}
}

View File

@ -19,9 +19,9 @@
package org.mariotaku.twidere.activity;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.v4.app.NavUtils;
@ -29,38 +29,18 @@ import android.view.Menu;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.content.res.NoAccentResources;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.theme.TwidereResourceHelper;
import static org.mariotaku.twidere.util.Utils.restartActivity;
public abstract class BasePreferenceActivity extends PreferenceActivity implements Constants,
IThemedActivity{
IThemedActivity {
private int mCurrentThemeResource;
private Theme mTheme;
private TwidereMenuInflater mMenuInflater;
@Override
public boolean onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
return false;
}
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
return onCreateOptionsMenu(menu, getTwidereMenuInflater());
}
@Override
public TwidereMenuInflater getTwidereMenuInflater() {
if (mMenuInflater != null) return mMenuInflater;
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
return mMenuInflater = new TwidereMenuInflater(actionBar.getThemedContext());
}
return mMenuInflater = new TwidereMenuInflater(this);
public boolean onMenuOpened(int featureId, Menu menu) {
return super.onMenuOpened(featureId, menu);
}
@Override
@ -79,19 +59,6 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
return super.getResources();
}
@Override
public Theme getTheme() {
if (mTheme == null) {
mTheme = getResources().newTheme();
mTheme.setTo(super.getTheme());
final int getThemeResourceId = getThemeResourceId();
if (getThemeResourceId != 0) {
mTheme.applyStyle(getThemeResourceId, true);
}
}
return mTheme;
}
@Override
public int getThemeBackgroundAlpha() {
return 0;

View File

@ -19,16 +19,13 @@
package org.mariotaku.twidere.activity;
import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.CompareUtils;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
@ -41,7 +38,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;
private String mCurrentThemeFontFamily;
private Theme mTheme;
private TwidereMenuInflater mMenuInflater;
@Override
public void finish() {
@ -49,27 +45,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
overrideCloseAnimationIfNeeded();
}
@Override
public boolean onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
return false;
}
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
return onCreateOptionsMenu(menu, getTwidereMenuInflater());
}
@Override
public TwidereMenuInflater getTwidereMenuInflater() {
if (mMenuInflater != null) return mMenuInflater;
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
return mMenuInflater = new TwidereMenuInflater(actionBar.getThemedContext());
}
return mMenuInflater = new TwidereMenuInflater(this);
}
@Override
public Resources getDefaultResources() {
return super.getResources();

View File

@ -58,7 +58,6 @@ import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.provider.TweetStore.Filters;
import org.mariotaku.twidere.util.ContentValuesCreator;
@ -101,8 +100,8 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_filters, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_filters, menu);
return true;
}

View File

@ -27,7 +27,9 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
@ -42,7 +44,6 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.DataExportActivity;
import org.mariotaku.twidere.activity.support.DataImportActivity;
import org.mariotaku.twidere.adapter.ArrayAdapter;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.CompareUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.holder.ViewHolder;
@ -77,7 +78,7 @@ public class SettingsActivity extends BasePreferenceActivity {
public HeaderAdapter getHeaderAdapter() {
if (mAdapter != null) return mAdapter;
return mAdapter = new HeaderAdapter(ThemeUtils.getThemedContextForActionIcons(this, getThemeResourceId()));
return mAdapter = new HeaderAdapter(this);
}
@Override
@ -98,14 +99,14 @@ public class SettingsActivity extends BasePreferenceActivity {
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public boolean onCreateOptionsMenu(final Menu menu) {
if (getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) != null) return false;
inflater.inflate(R.menu.menu_settings, menu);
getMenuInflater().inflate(R.menu.menu_settings, menu);
return true;
}
@Override
public void onHeaderClick(final Header header, final int position) {
public void onHeaderClick(@NonNull final Header header, final int position) {
if (header.id == HEADER_ID_RESTORE_ICON) {
final ComponentName main = new ComponentName(this, MainActivity.class);
final ComponentName main2 = new ComponentName(this, MainHondaJOJOActivity.class);
@ -211,11 +212,13 @@ public class SettingsActivity extends BasePreferenceActivity {
private final Context mContext;
private final Resources mResources;
private final int mActionIconColor;
public HeaderAdapter(final Context context) {
super(context, R.layout.list_item_preference_header);
mContext = context;
mResources = context.getResources();
mActionIconColor = ThemeUtils.getThemeForegroundColor(context);
}
@Override
@ -262,10 +265,11 @@ public class SettingsActivity extends BasePreferenceActivity {
holder.summary.setVisibility(View.GONE);
}
if (header.iconRes != 0) {
holder.icon.setImageDrawable(mResources.getDrawable(header.iconRes));
holder.icon.setImageResource(header.iconRes);
} else {
holder.icon.setImageDrawable(null);
}
holder.icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
break;
}
}

View File

@ -20,34 +20,28 @@
package org.mariotaku.twidere.activity.iface;
import android.content.res.Resources;
import android.view.Menu;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
public interface IThemedActivity {
public interface IThemedActivity extends ITwidereContextWrapper {
public int getCurrentThemeResourceId();
public int getCurrentThemeResourceId();
public Resources getDefaultResources();
public Resources getDefaultResources();
public int getThemeBackgroundAlpha();
public int getThemeBackgroundAlpha();
public int getThemeColor();
public int getThemeColor();
public String getThemeFontFamily();
public TwidereMenuInflater getTwidereMenuInflater();
int getThemeResourceId();
public String getThemeFontFamily();
public boolean isDarkDrawerEnabled();
public boolean isDarkDrawerEnabled();
public void navigateUpFromSameTask();
public void navigateUpFromSameTask();
public void overrideCloseAnimationIfNeeded();
public void overrideCloseAnimationIfNeeded();
public void restart();
public void restart();
public boolean onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater);
public boolean shouldOverrideActivityAnimation();
public boolean shouldOverrideActivityAnimation();
}

View File

@ -20,15 +20,12 @@
package org.mariotaku.twidere.activity.support;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.os.Bundle;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.content.res.NoAccentResources;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.theme.TwidereResourceHelper;
@SuppressLint("Registered")
public class BaseSupportDialogActivity extends BaseSupportThemedActivity implements Constants, IThemedActivity {

View File

@ -19,7 +19,6 @@
package org.mariotaku.twidere.activity.support;
import android.app.ActionBar;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
@ -27,11 +26,9 @@ import android.support.v4.app.NavUtils;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.view.Menu;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
@ -41,7 +38,6 @@ import static org.mariotaku.twidere.util.Utils.restartActivity;
public abstract class BaseSupportThemedActivity extends FragmentActivity implements Constants, IThemedActivity {
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;
private TwidereMenuInflater mMenuInflater;
@Override
public void finish() {
@ -49,31 +45,11 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
overrideCloseAnimationIfNeeded();
}
@Override
public boolean onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
return false;
}
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
return onCreateOptionsMenu(menu, getTwidereMenuInflater());
}
@Override
public Resources getDefaultResources() {
return super.getResources();
}
@Override
public TwidereMenuInflater getTwidereMenuInflater() {
if (mMenuInflater != null) return mMenuInflater;
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
return mMenuInflater = new TwidereMenuInflater(actionBar.getThemedContext());
}
return mMenuInflater = new TwidereMenuInflater(this);
}
@Override
public final int getCurrentThemeResourceId() {
return mCurrentThemeResource;
@ -84,18 +60,11 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
return ThemeUtils.isTransparentBackground(this) ? ThemeUtils.getUserThemeBackgroundAlpha(this) : 0xff;
}
@Override
public abstract int getThemeColor();
@Override
public String getThemeFontFamily() {
return ThemeUtils.getThemeFontFamily(this);
}
@Override
public abstract int getThemeResourceId();
@Override
public boolean isDarkDrawerEnabled() {
return ThemeUtils.isDarkDrawerEnabled(this);

View File

@ -19,10 +19,6 @@
package org.mariotaku.twidere.activity.support;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.getNonEmptyString;
import static org.mariotaku.twidere.util.Utils.setUserAgent;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
@ -47,10 +43,14 @@ import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.task.AsyncTask;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.net.TwidereHostResolverFactory;
import org.mariotaku.twidere.util.net.TwidereHttpClientFactory;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.StringReader;
import twitter4j.Twitter;
import twitter4j.TwitterConstants;
import twitter4j.TwitterException;
@ -58,251 +58,256 @@ import twitter4j.TwitterFactory;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;
import java.io.IOException;
import java.io.StringReader;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.getNonEmptyString;
@SuppressLint("SetJavaScriptEnabled")
public class BrowserSignInActivity extends BaseSupportDialogActivity implements TwitterConstants {
private static final String INJECT_CONTENT = "javascript:window.injector.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');";
private static final String INJECT_CONTENT = "javascript:window.injector.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');";
private SharedPreferences mPreferences;
private SharedPreferences mPreferences;
private WebView mWebView;
private View mProgressContainer;
private WebView mWebView;
private View mProgressContainer;
private WebSettings mWebSettings;
private WebSettings mWebSettings;
private RequestToken mRequestToken;
private RequestToken mRequestToken;
private GetRequestTokenTask mTask;
private GetRequestTokenTask mTask;
@Override
public void onContentChanged() {
super.onContentChanged();
mWebView = (WebView) findViewById(R.id.webview);
mProgressContainer = findViewById(R.id.progress_container);
}
@Override
public void onContentChanged() {
super.onContentChanged();
mWebView = (WebView) findViewById(R.id.webview);
mProgressContainer = findViewById(R.id.progress_container);
}
@Override
public void onDestroy() {
getLoaderManager().destroyLoader(0);
super.onDestroy();
}
@Override
public void onDestroy() {
getLoaderManager().destroyLoader(0);
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
finish();
return true;
}
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
finish();
return true;
}
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
setContentView(R.layout.activity_browser_sign_in);
mWebView.setWebViewClient(new AuthorizationWebViewClient(this));
mWebView.setVerticalScrollBarEnabled(false);
mWebView.addJavascriptInterface(new InjectorJavaScriptInterface(this), "injector");
mWebSettings = mWebView.getSettings();
mWebSettings.setLoadsImagesAutomatically(true);
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setBlockNetworkImage(false);
mWebSettings.setSaveFormData(true);
getRequestToken();
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
setContentView(R.layout.activity_browser_sign_in);
mWebView.setWebViewClient(new AuthorizationWebViewClient(this));
mWebView.setVerticalScrollBarEnabled(false);
mWebView.addJavascriptInterface(new InjectorJavaScriptInterface(this), "injector");
mWebSettings = mWebView.getSettings();
mWebSettings.setLoadsImagesAutomatically(true);
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setBlockNetworkImage(false);
mWebSettings.setSaveFormData(true);
getRequestToken();
}
private void getRequestToken() {
if (mRequestToken != null || mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return;
mTask = new GetRequestTokenTask(this);
mTask.execute();
}
private void getRequestToken() {
if (mRequestToken != null || mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING)
return;
mTask = new GetRequestTokenTask(this);
mTask.execute();
}
private void loadUrl(final String url) {
if (mWebView == null) return;
mWebView.loadUrl(url);
}
private void loadUrl(final String url) {
if (mWebView == null) return;
mWebView.loadUrl(url);
}
private String readOAuthPin(final String html) {
try {
return OAuthPasswordAuthenticator.readOAuthPINFromHtml(new StringReader(html));
} catch (final XmlPullParserException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private String readOAuthPin(final String html) {
try {
return OAuthPasswordAuthenticator.readOAuthPINFromHtml(new StringReader(html));
} catch (final XmlPullParserException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private void setLoadProgressShown(final boolean shown) {
mProgressContainer.setVisibility(shown ? View.VISIBLE : View.GONE);
}
private void setLoadProgressShown(final boolean shown) {
mProgressContainer.setVisibility(shown ? View.VISIBLE : View.GONE);
}
private void setRequestToken(final RequestToken token) {
mRequestToken = token;
}
private void setRequestToken(final RequestToken token) {
mRequestToken = token;
}
static class AuthorizationWebViewClient extends WebViewClient {
private final BrowserSignInActivity mActivity;
static class AuthorizationWebViewClient extends WebViewClient {
private final BrowserSignInActivity mActivity;
AuthorizationWebViewClient(final BrowserSignInActivity activity) {
mActivity = activity;
}
AuthorizationWebViewClient(final BrowserSignInActivity activity) {
mActivity = activity;
}
@Override
public void onPageFinished(final WebView view, final String url) {
super.onPageFinished(view, url);
view.loadUrl(INJECT_CONTENT);
mActivity.setLoadProgressShown(false);
}
@Override
public void onPageFinished(final WebView view, final String url) {
super.onPageFinished(view, url);
view.loadUrl(INJECT_CONTENT);
mActivity.setLoadProgressShown(false);
}
@Override
public void onPageStarted(final WebView view, final String url, final Bitmap favicon) {
super.onPageStarted(view, url, favicon);
mActivity.setLoadProgressShown(true);
}
@Override
public void onPageStarted(final WebView view, final String url, final Bitmap favicon) {
super.onPageStarted(view, url, favicon);
mActivity.setLoadProgressShown(true);
}
@Override
public void onReceivedError(final WebView view, final int errorCode, final String description,
final String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
Toast.makeText(mActivity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
mActivity.finish();
}
@Override
public void onReceivedError(final WebView view, final int errorCode, final String description,
final String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
Toast.makeText(mActivity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
mActivity.finish();
}
@Override
public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
if (mActivity.mPreferences.getBoolean(KEY_IGNORE_SSL_ERROR, false)) {
handler.proceed();
} else {
handler.cancel();
}
}
@Override
public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
if (mActivity.mPreferences.getBoolean(KEY_IGNORE_SSL_ERROR, false)) {
handler.proceed();
} else {
handler.cancel();
}
}
@Override
public boolean shouldOverrideUrlLoading(final WebView view, final String url) {
final Uri uri = Uri.parse(url);
if (url.startsWith(OAUTH_CALLBACK_URL)) {
final String oauth_verifier = uri.getQueryParameter(EXTRA_OAUTH_VERIFIER);
final RequestToken request_token = mActivity.mRequestToken;
if (oauth_verifier != null && request_token != null) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_OAUTH_VERIFIER, oauth_verifier);
intent.putExtra(EXTRA_REQUEST_TOKEN, request_token.getToken());
intent.putExtra(EXTRA_REQUEST_TOKEN_SECRET, request_token.getTokenSecret());
mActivity.setResult(RESULT_OK, intent);
mActivity.finish();
}
return true;
}
return false;
}
@Override
public boolean shouldOverrideUrlLoading(final WebView view, final String url) {
final Uri uri = Uri.parse(url);
if (url.startsWith(OAUTH_CALLBACK_URL)) {
final String oauth_verifier = uri.getQueryParameter(EXTRA_OAUTH_VERIFIER);
final RequestToken request_token = mActivity.mRequestToken;
if (oauth_verifier != null && request_token != null) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_OAUTH_VERIFIER, oauth_verifier);
intent.putExtra(EXTRA_REQUEST_TOKEN, request_token.getToken());
intent.putExtra(EXTRA_REQUEST_TOKEN_SECRET, request_token.getTokenSecret());
mActivity.setResult(RESULT_OK, intent);
mActivity.finish();
}
return true;
}
return false;
}
}
}
static class GetRequestTokenTask extends AsyncTask<Void, Void, RequestToken> {
static class GetRequestTokenTask extends AsyncTask<Void, Void, RequestToken> {
private final String mConsumerKey, mConsumerSecret;
private final TwidereApplication mApplication;
private final SharedPreferences mPreferences;
private final BrowserSignInActivity mActivity;
private final String mConsumerKey, mConsumerSecret;
private final TwidereApplication mApplication;
private final SharedPreferences mPreferences;
private final BrowserSignInActivity mActivity;
public GetRequestTokenTask(final BrowserSignInActivity activity) {
mActivity = activity;
mApplication = TwidereApplication.getInstance(activity);
mPreferences = activity.getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
final Intent intent = activity.getIntent();
mConsumerKey = intent.getStringExtra(Accounts.CONSUMER_KEY);
mConsumerSecret = intent.getStringExtra(Accounts.CONSUMER_SECRET);
}
public GetRequestTokenTask(final BrowserSignInActivity activity) {
mActivity = activity;
mApplication = TwidereApplication.getInstance(activity);
mPreferences = activity.getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
final Intent intent = activity.getIntent();
mConsumerKey = intent.getStringExtra(Accounts.CONSUMER_KEY);
mConsumerSecret = intent.getStringExtra(Accounts.CONSUMER_SECRET);
}
@Override
protected RequestToken doInBackground(final Void... params) {
final ConfigurationBuilder cb = new ConfigurationBuilder();
final boolean enable_gzip_compressing = mPreferences.getBoolean(KEY_GZIP_COMPRESSING, false);
final boolean ignore_ssl_error = mPreferences.getBoolean(KEY_IGNORE_SSL_ERROR, false);
final boolean enable_proxy = mPreferences.getBoolean(KEY_ENABLE_PROXY, false);
final String consumer_key = getNonEmptyString(mPreferences, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY_3);
final String consumer_secret = getNonEmptyString(mPreferences, KEY_CONSUMER_SECRET,
@Override
protected RequestToken doInBackground(final Void... params) {
final ConfigurationBuilder cb = new ConfigurationBuilder();
final boolean enable_gzip_compressing = mPreferences.getBoolean(KEY_GZIP_COMPRESSING, false);
final boolean ignore_ssl_error = mPreferences.getBoolean(KEY_IGNORE_SSL_ERROR, false);
final boolean enable_proxy = mPreferences.getBoolean(KEY_ENABLE_PROXY, false);
final String consumerKey = getNonEmptyString(mPreferences, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY_3);
final String consumerSecret = getNonEmptyString(mPreferences, KEY_CONSUMER_SECRET,
TWITTER_CONSUMER_SECRET_3);
cb.setHostAddressResolverFactory(new TwidereHostResolverFactory(mApplication));
cb.setHttpClientFactory(new TwidereHttpClientFactory(mApplication));
setUserAgent(mActivity, cb);
cb.setRestBaseURL(DEFAULT_REST_BASE_URL);
cb.setOAuthBaseURL(DEFAULT_OAUTH_BASE_URL);
cb.setSigningRestBaseURL(DEFAULT_SIGNING_REST_BASE_URL);
cb.setSigningOAuthBaseURL(DEFAULT_SIGNING_OAUTH_BASE_URL);
if (!isEmpty(mConsumerKey) && !isEmpty(mConsumerSecret)) {
cb.setOAuthConsumerKey(mConsumerKey);
cb.setOAuthConsumerSecret(mConsumerSecret);
} else {
cb.setOAuthConsumerKey(consumer_key);
cb.setOAuthConsumerSecret(consumer_secret);
}
cb.setGZIPEnabled(enable_gzip_compressing);
cb.setIgnoreSSLError(ignore_ssl_error);
if (enable_proxy) {
final String proxy_host = mPreferences.getString(KEY_PROXY_HOST, null);
final int proxy_port = ParseUtils.parseInt(mPreferences.getString(KEY_PROXY_PORT, "-1"));
if (!isEmpty(proxy_host) && proxy_port > 0) {
cb.setHttpProxyHost(proxy_host);
cb.setHttpProxyPort(proxy_port);
}
}
try {
final Twitter twitter = new TwitterFactory(cb.build()).getInstance();
return twitter.getOAuthRequestToken(OAUTH_CALLBACK_OOB);
} catch (final TwitterException e) {
e.printStackTrace();
}
return null;
}
cb.setHostAddressResolverFactory(new TwidereHostResolverFactory(mApplication));
cb.setHttpClientFactory(new TwidereHttpClientFactory(mApplication));
if (Utils.isOfficialConsumerKeySecret(mActivity, consumerKey, consumerSecret)) {
Utils.setMockOfficialUserAgent(mActivity, cb);
} else {
Utils.setUserAgent(mActivity, cb);
}
cb.setRestBaseURL(DEFAULT_REST_BASE_URL);
cb.setOAuthBaseURL(DEFAULT_OAUTH_BASE_URL);
cb.setSigningRestBaseURL(DEFAULT_SIGNING_REST_BASE_URL);
cb.setSigningOAuthBaseURL(DEFAULT_SIGNING_OAUTH_BASE_URL);
if (!isEmpty(mConsumerKey) && !isEmpty(mConsumerSecret)) {
cb.setOAuthConsumerKey(mConsumerKey);
cb.setOAuthConsumerSecret(mConsumerSecret);
} else {
cb.setOAuthConsumerKey(consumerKey);
cb.setOAuthConsumerSecret(consumerSecret);
}
cb.setGZIPEnabled(enable_gzip_compressing);
cb.setIgnoreSSLError(ignore_ssl_error);
if (enable_proxy) {
final String proxy_host = mPreferences.getString(KEY_PROXY_HOST, null);
final int proxy_port = ParseUtils.parseInt(mPreferences.getString(KEY_PROXY_PORT, "-1"));
if (!isEmpty(proxy_host) && proxy_port > 0) {
cb.setHttpProxyHost(proxy_host);
cb.setHttpProxyPort(proxy_port);
}
}
try {
final Twitter twitter = new TwitterFactory(cb.build()).getInstance();
return twitter.getOAuthRequestToken(OAUTH_CALLBACK_OOB);
} catch (final TwitterException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(final RequestToken data) {
mActivity.setLoadProgressShown(false);
mActivity.setRequestToken(data);
if (data == null) {
Toast.makeText(mActivity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
mActivity.finish();
return;
}
mActivity.loadUrl(data.getAuthorizationURL());
}
@Override
protected void onPostExecute(final RequestToken data) {
mActivity.setLoadProgressShown(false);
mActivity.setRequestToken(data);
if (data == null) {
Toast.makeText(mActivity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
mActivity.finish();
return;
}
mActivity.loadUrl(data.getAuthorizationURL());
}
@Override
protected void onPreExecute() {
mActivity.setLoadProgressShown(true);
}
@Override
protected void onPreExecute() {
mActivity.setLoadProgressShown(true);
}
}
}
static class InjectorJavaScriptInterface {
static class InjectorJavaScriptInterface {
private final BrowserSignInActivity mActivity;
private final BrowserSignInActivity mActivity;
InjectorJavaScriptInterface(final BrowserSignInActivity activity) {
mActivity = activity;
}
InjectorJavaScriptInterface(final BrowserSignInActivity activity) {
mActivity = activity;
}
@JavascriptInterface
public void processHTML(final String html) {
final String oauth_verifier = mActivity.readOAuthPin(html);
final RequestToken request_token = mActivity.mRequestToken;
if (oauth_verifier != null && request_token != null) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_OAUTH_VERIFIER, oauth_verifier);
intent.putExtra(EXTRA_REQUEST_TOKEN, request_token.getToken());
intent.putExtra(EXTRA_REQUEST_TOKEN_SECRET, request_token.getTokenSecret());
mActivity.setResult(RESULT_OK, intent);
mActivity.finish();
}
}
}
@JavascriptInterface
public void processHTML(final String html) {
final String oauth_verifier = mActivity.readOAuthPin(html);
final RequestToken request_token = mActivity.mRequestToken;
if (oauth_verifier != null && request_token != null) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_OAUTH_VERIFIER, oauth_verifier);
intent.putExtra(EXTRA_REQUEST_TOKEN, request_token.getToken());
intent.putExtra(EXTRA_REQUEST_TOKEN_SECRET, request_token.getTokenSecret());
mActivity.setResult(RESULT_OK, intent);
mActivity.finish();
}
}
}
}

View File

@ -65,6 +65,7 @@ import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.StackView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
@ -77,7 +78,7 @@ import org.mariotaku.menucomponent.widget.MenuBar;
import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
import org.mariotaku.menucomponent.widget.PopupMenu;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ArrayRecyclerAdapter;
import org.mariotaku.twidere.adapter.BaseArrayAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.model.Account;
@ -177,9 +178,10 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
private IColorLabelView mColorIndicator;
private EditText mEditText;
private ProgressBar mProgress;
// private RecyclerView mAccountSelector;
private StackView mAccountStack;
private View mSendView, mBottomSendView;
private StatusTextCountView mSendTextCountView, mBottomSendTextCountView;
private View mSelectAccount;
private MediaPreviewAdapter mMediaPreviewAdapter;
private AccountSelectorAdapter mAccountSelectorAdapter;
@ -417,6 +419,10 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
}
break;
}
case R.id.select_account: {
Toast.makeText(this, "Select account", Toast.LENGTH_SHORT).show();
break;
}
}
}
@ -431,13 +437,14 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
mMediasPreviewGrid = (GridView) findViewById(R.id.medias_thumbnail_preview);
mMenuBar = (MenuBar) findViewById(R.id.menu_bar);
mProgress = (ProgressBar) findViewById(R.id.actionbar_progress_indeterminate);
// mAccountSelector = (RecyclerView) findViewById(R.id.account_selector);
mAccountStack = (StackView) findViewById(R.id.accounts_stack);
final View composeActionBar = findViewById(R.id.compose_actionbar);
final View composeBottomBar = findViewById(R.id.compose_bottombar);
mSendView = composeActionBar.findViewById(R.id.send);
mBottomSendView = composeBottomBar.findViewById(R.id.send);
mSendTextCountView = (StatusTextCountView) mSendView.findViewById(R.id.status_text_count);
mBottomSendTextCountView = (StatusTextCountView) mBottomSendView.findViewById(R.id.status_text_count);
mSelectAccount = composeActionBar.findViewById(R.id.select_account);
ViewAccessor.setBackground(findViewById(R.id.compose_content), getWindowContentOverlayForCompose(this));
ViewAccessor.setBackground(composeActionBar, getActionBarBackground(this, getCurrentThemeResourceId()));
}
@ -592,8 +599,9 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
mEditText.setOnEditorActionListener(mPreferences.getBoolean(KEY_QUICK_SEND, false) ? this : null);
mEditText.addTextChangedListener(this);
mAccountSelectorAdapter = new AccountSelectorAdapter(this);
// mAccountSelector.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
// mAccountSelector.setAdapter(mAccountSelectorAdapter);
mAccountStack.setAdapter(mAccountSelectorAdapter);
mAccountSelectorAdapter.addAll(Account.getAccountsList(this, false));
mSelectAccount.setOnClickListener(this);
// mAccountSelector.setOnItemClickListener(this);
// mAccountSelector.setOnItemLongClickListener(this);
@ -1291,16 +1299,13 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
}
private static class AccountSelectorAdapter extends ArrayRecyclerAdapter<Account, AccountAvatarHolder> {
private static class AccountSelectorAdapter extends BaseArrayAdapter<Account> {
private final LongSparseArray<Boolean> mAccountSelectStates = new LongSparseArray<>();
private final LayoutInflater mInflater;
private final ImageLoaderWrapper mImageLoader;
public AccountSelectorAdapter(final Context context) {
mInflater = LayoutInflater.from(context);
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
super(context, R.layout.adapter_item_compose_account);
}
public void clearAccountSelection() {
@ -1308,30 +1313,19 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
notifyDataSetChanged();
}
public long[] getSelectedAccountIds() {
final ArrayList<Long> list = new ArrayList<Long>();
for (int i = 0, j = getItemCount(); i < j; i++) {
final Account account = getItem(i);
if (mAccountSelectStates.get(account.account_id, false)) {
list.add(account.account_id);
}
}
return ArrayUtils.fromList(list);
}
public void setAccountSelected(final long accountId, final boolean selected) {
mAccountSelectStates.put(accountId, selected);
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(AccountAvatarHolder holder, int position, Account item) {
holder.setAccount(mImageLoader, item, mAccountSelectStates);
}
@Override
public AccountAvatarHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AccountAvatarHolder(mInflater.inflate(R.layout.gallery_item_compose_account, parent, false));
public View getView(int position, View convertView, ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
final Account account = getItem(position);
final ImageLoaderWrapper loader = getImageLoader();
loader.displayProfileImage(icon, account.profile_image_url);
return view;
}
@ -1348,8 +1342,6 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
}
public void setAccount(ImageLoaderWrapper loader, Account account, LongSparseArray<Boolean> states) {
loader.displayProfileImage(icon, account.profile_image_url);
states.get(account.account_id, false);
}
}

View File

@ -75,7 +75,6 @@ import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.model.SupportTabSpec;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
@ -252,8 +251,8 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_home, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_home, menu);
final MenuItem itemProgress = menu.findItem(MENU_PROGRESS);
mSmartBarProgress = (ProgressBar) itemProgress.getActionView().findViewById(android.R.id.progress);
updateActionsButton();
@ -452,7 +451,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
public void updateUnreadCount() {
if (mTabIndicator == null || mUpdateUnreadCountTask != null
&& mUpdateUnreadCountTask.getStatus() == AsyncTask.Status.RUNNING) return;
mUpdateUnreadCountTask = new UpdateUnreadCountTask(mTabIndicator, mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
mUpdateUnreadCountTask = new UpdateUnreadCountTask(mTabIndicator);
mUpdateUnreadCountTask.execute();
}
@ -535,6 +534,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mTabIndicator.setDisplayLabel(false);
mTabIndicator.setDisplayIcon(true);
}
mTabIndicator.setDisplayBadge(mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
mActionsButton.setOnClickListener(this);
mActionsButton.setOnLongClickListener(this);
setTabPosition(initialTabPosition);
@ -937,12 +937,10 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
private static class UpdateUnreadCountTask extends AsyncTask<Void, Void, int[]> {
private final Context mContext;
private final TabPagerIndicator mIndicator;
private final boolean mEnabled;
UpdateUnreadCountTask(final TabPagerIndicator indicator, final boolean enabled) {
UpdateUnreadCountTask(final TabPagerIndicator indicator) {
mIndicator = indicator;
mContext = indicator.getContext();
mEnabled = enabled;
}
@Override

View File

@ -8,6 +8,7 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
@ -18,7 +19,6 @@ import android.widget.ListView;
import org.mariotaku.menucomponent.internal.menu.MenuAdapter;
import org.mariotaku.menucomponent.internal.menu.MenuUtils;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.ThemeUtils;
public abstract class MenuDialogFragment extends BaseSupportDialogFragment implements OnItemClickListener {
@ -36,7 +36,7 @@ public abstract class MenuDialogFragment extends BaseSupportDialogFragment imple
listView.setOnItemClickListener(this);
builder.setView(listView);
final Menu menu = MenuUtils.createMenu(context);
onCreateMenu(new TwidereMenuInflater(context), menu);
onCreateMenu(new MenuInflater(context), menu);
final int itemColor = ThemeUtils.getThemeForegroundColor(context);
final int highlightColor = ThemeUtils.getUserAccentColor(context);
ThemeUtils.applyColorFilterToMenuIcon(menu, itemColor, highlightColor, Mode.SRC_ATOP);
@ -60,6 +60,6 @@ public abstract class MenuDialogFragment extends BaseSupportDialogFragment imple
}
}
protected abstract void onCreateMenu(TwidereMenuInflater inflater, Menu menu);
protected abstract void onCreateMenu(MenuInflater inflater, Menu menu);
}

View File

@ -47,7 +47,6 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.SettingsActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.task.AsyncTask;
import org.mariotaku.twidere.util.ColorAnalyser;
@ -86,7 +85,6 @@ import static org.mariotaku.twidere.util.ContentValuesCreator.makeAccountContent
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
import static org.mariotaku.twidere.util.Utils.getNonEmptyString;
import static org.mariotaku.twidere.util.Utils.isUserLoggedIn;
import static org.mariotaku.twidere.util.Utils.setUserAgent;
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
import static org.mariotaku.twidere.util.Utils.trim;
@ -223,8 +221,8 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_sign_in, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_sign_in, menu);
return true;
}
@ -396,7 +394,11 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
final boolean enable_proxy = mPreferences.getBoolean(KEY_ENABLE_PROXY, false);
cb.setHostAddressResolverFactory(new TwidereHostResolverFactory(mApplication));
cb.setHttpClientFactory(new TwidereHttpClientFactory(mApplication));
setUserAgent(this, cb);
if (Utils.isOfficialConsumerKeySecret(this, mConsumerKey, mConsumerSecret)) {
Utils.setMockOfficialUserAgent(this, cb);
} else {
Utils.setUserAgent(this, cb);
}
if (!isEmpty(mAPIUrlFormat)) {
final String versionSuffix = mNoVersionSuffix ? null : "/1.1/";
cb.setRestBaseURL(Utils.getApiUrl(mAPIUrlFormat, "api", versionSuffix));

View File

@ -47,7 +47,6 @@ import org.mariotaku.menucomponent.widget.PopupMenu;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.loader.support.ParcelableUserLoader;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
@ -263,8 +262,8 @@ public class UserProfileEditorActivity extends BaseSupportActivity implements On
}
@Override
public boolean onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
inflater.inflate(R.menu.menu_edit_user_profile, menu);
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_edit_user_profile, menu);
return true;
}

View File

@ -19,12 +19,9 @@
package org.mariotaku.twidere.adapter;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.widget.SimpleCursorAdapter;
@ -40,7 +37,6 @@ import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.provider.TweetStore.CachedHashtags;
import org.mariotaku.twidere.provider.TweetStore.CachedUsers;
@ -48,190 +44,181 @@ import org.mariotaku.twidere.provider.TweetStore.CachedValues;
import org.mariotaku.twidere.util.ArrayUtils;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
private static final String[] FROM = new String[0];
private static final int[] TO = new int[0];
private static final String[] CACHED_USERS_COLUMNS = new String[] { CachedUsers._ID, CachedUsers.USER_ID,
CachedUsers.NAME, CachedUsers.SCREEN_NAME, CachedUsers.PROFILE_IMAGE_URL };
private final Locale mLocale;
private static final String[] FROM = new String[0];
private static final int[] TO = new int[0];
private static final String[] CACHED_USERS_COLUMNS = new String[]{CachedUsers._ID, CachedUsers.USER_ID,
CachedUsers.NAME, CachedUsers.SCREEN_NAME, CachedUsers.PROFILE_IMAGE_URL};
private final Locale mLocale;
private final ContentResolver mResolver;
private final SQLiteDatabase mDatabase;
private final ImageLoaderWrapper mProfileImageLoader;
private final SharedPreferences mPreferences, mUserNicknamePreferences;
private final Resources mResources;
private final ContentResolver mResolver;
private final SQLiteDatabase mDatabase;
private final ImageLoaderWrapper mProfileImageLoader;
private final SharedPreferences mPreferences, mUserNicknamePreferences;
private final EditText mEditText;
private final EditText mEditText;
private final boolean mDisplayProfileImage, mNicknameOnly;
private final boolean mDisplayProfileImage, mNicknameOnly;
private int mProfileImageUrlIdx, mNameIdx, mScreenNameIdx, mUserIdIdx;
private char mToken = '@';
private int mProfileImageUrlIdx, mNameIdx, mScreenNameIdx, mUserIdIdx;
private char mToken = '@';
public UserHashtagAutoCompleteAdapter(final Context context) {
this(context, null);
}
public UserHashtagAutoCompleteAdapter(final Context context) {
this(context, null);
}
public UserHashtagAutoCompleteAdapter(final Context context, final EditText view) {
super(context, R.layout.list_item_two_line_small, null, FROM, TO, 0);
mEditText = view;
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mUserNicknamePreferences = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE);
mResolver = context.getContentResolver();
final TwidereApplication app = TwidereApplication.getInstance(context);
mProfileImageLoader = app != null ? app.getImageLoaderWrapper() : null;
mDatabase = app != null ? app.getSQLiteDatabase() : null;
mDisplayProfileImage = mPreferences != null && mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mNicknameOnly = mPreferences != null && mPreferences.getBoolean(KEY_NICKNAME_ONLY, false);
mLocale = context.getResources().getConfiguration().locale;
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = ThemeUtils.getThemeResource(context);
accentColor = ThemeUtils.getUserAccentColor(context);
}
mResources = ThemeUtils.getThemedResourcesForActionIcons(context, themeRes, accentColor);
}
public UserHashtagAutoCompleteAdapter(final Context context, final EditText view) {
super(context, R.layout.list_item_two_line_small, null, FROM, TO, 0);
mEditText = view;
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mUserNicknamePreferences = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE);
mResolver = context.getContentResolver();
final TwidereApplication app = TwidereApplication.getInstance(context);
mProfileImageLoader = app != null ? app.getImageLoaderWrapper() : null;
mDatabase = app != null ? app.getSQLiteDatabase() : null;
mDisplayProfileImage = mPreferences != null && mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mNicknameOnly = mPreferences != null && mPreferences.getBoolean(KEY_NICKNAME_ONLY, false);
mLocale = context.getResources().getConfiguration().locale;
}
public UserHashtagAutoCompleteAdapter(final EditText view) {
this(view.getContext(), view);
}
public UserHashtagAutoCompleteAdapter(final EditText view) {
this(view.getContext(), view);
}
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
if (isCursorClosed()) return;
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
if (isCursorClosed()) return;
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
// Clear images in prder to prevent images in recycled view shown.
icon.setImageDrawable(null);
// Clear images in prder to prevent images in recycled view shown.
icon.setImageDrawable(null);
if (mScreenNameIdx != -1 && mNameIdx != -1 && mUserIdIdx != -1) {
final String nick = getUserNickname(context, cursor.getLong(mUserIdIdx));
final String name = cursor.getString(mNameIdx);
if (TextUtils.isEmpty(nick)) {
text1.setText(name);
} else {
text1.setText(mNicknameOnly ? nick : context.getString(R.string.name_with_nickname, name, nick));
}
text2.setText("@" + cursor.getString(mScreenNameIdx));
} else {
text1.setText("#" + cursor.getString(mNameIdx));
text2.setText(R.string.hashtag);
}
icon.setVisibility(mDisplayProfileImage ? View.VISIBLE : View.GONE);
if (mProfileImageUrlIdx != -1) {
if (mDisplayProfileImage && mProfileImageLoader != null) {
final String profile_image_url_string = cursor.getString(mProfileImageUrlIdx);
mProfileImageLoader.displayProfileImage(icon, profile_image_url_string);
} else {
icon.setImageResource(R.drawable.ic_profile_image_default);
}
} else {
icon.setImageDrawable(mResources.getDrawable(R.drawable.ic_action_hashtag));
}
super.bindView(view, context, cursor);
}
if (mScreenNameIdx != -1 && mNameIdx != -1 && mUserIdIdx != -1) {
final String nick = getUserNickname(context, cursor.getLong(mUserIdIdx));
final String name = cursor.getString(mNameIdx);
if (TextUtils.isEmpty(nick)) {
text1.setText(name);
} else {
text1.setText(mNicknameOnly ? nick : context.getString(R.string.name_with_nickname, name, nick));
}
text2.setText("@" + cursor.getString(mScreenNameIdx));
} else {
text1.setText("#" + cursor.getString(mNameIdx));
text2.setText(R.string.hashtag);
}
icon.setVisibility(mDisplayProfileImage ? View.VISIBLE : View.GONE);
if (mProfileImageUrlIdx != -1) {
if (mDisplayProfileImage && mProfileImageLoader != null) {
final String profile_image_url_string = cursor.getString(mProfileImageUrlIdx);
mProfileImageLoader.displayProfileImage(icon, profile_image_url_string);
} else {
icon.setImageResource(R.drawable.ic_profile_image_default);
}
} else {
icon.setImageResource(R.drawable.ic_action_hashtag);
}
super.bindView(view, context, cursor);
}
public void closeCursor() {
final Cursor cursor = getCursor();
if (cursor == null) return;
if (!cursor.isClosed()) {
cursor.close();
}
}
public void closeCursor() {
final Cursor cursor = getCursor();
if (cursor == null) return;
if (!cursor.isClosed()) {
cursor.close();
}
}
@Override
public CharSequence convertToString(final Cursor cursor) {
if (isCursorClosed()) return null;
return cursor.getString(mScreenNameIdx != -1 ? mScreenNameIdx : mNameIdx);
}
@Override
public CharSequence convertToString(final Cursor cursor) {
if (isCursorClosed()) return null;
return cursor.getString(mScreenNameIdx != -1 ? mScreenNameIdx : mNameIdx);
}
public boolean isCursorClosed() {
final Cursor cursor = getCursor();
return cursor == null || cursor.isClosed();
}
public boolean isCursorClosed() {
final Cursor cursor = getCursor();
return cursor == null || cursor.isClosed();
}
@Override
public Cursor runQueryOnBackgroundThread(final CharSequence constraint) {
char token = mToken;
if (mEditText != null && constraint != null) {
final CharSequence text = mEditText.getText();
token = text.charAt(mEditText.getSelectionEnd() - constraint.length() - 1);
}
if (isAtSymbol(token) == isAtSymbol(mToken)) {
final FilterQueryProvider filter = getFilterQueryProvider();
if (filter != null) return filter.runQuery(constraint);
}
mToken = token;
final String constraint_escaped = constraint != null ? constraint.toString().replaceAll("_", "^_") : null;
if (isAtSymbol(token)) {
final StringBuilder builder = new StringBuilder();
builder.append(CachedUsers.SCREEN_NAME + " LIKE ?||'%' ESCAPE '^'");
builder.append(" OR ");
builder.append(CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'");
builder.append(" OR ");
builder.append(Where.in(new Column(CachedUsers.USER_ID),
new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL());
final String selection = constraint_escaped != null ? builder.toString() : null;
final String[] selectionArgs = constraint_escaped != null ? new String[] { constraint_escaped,
constraint_escaped } : null;
final String orderBy = CachedUsers.SCREEN_NAME + ", " + CachedUsers.NAME;
return mResolver.query(CachedUsers.CONTENT_URI, CACHED_USERS_COLUMNS, selection, selectionArgs, orderBy);
} else {
final String selection = constraint_escaped != null ? CachedHashtags.NAME + " LIKE ?||'%' ESCAPE '^'"
: null;
final String[] selectionArgs = constraint_escaped != null ? new String[] { constraint_escaped } : null;
return mDatabase.query(true, CachedHashtags.TABLE_NAME, CachedHashtags.COLUMNS, selection, selectionArgs,
null, null, CachedHashtags.NAME, null);
}
}
@Override
public Cursor runQueryOnBackgroundThread(final CharSequence constraint) {
char token = mToken;
if (mEditText != null && constraint != null) {
final CharSequence text = mEditText.getText();
token = text.charAt(mEditText.getSelectionEnd() - constraint.length() - 1);
}
if (isAtSymbol(token) == isAtSymbol(mToken)) {
final FilterQueryProvider filter = getFilterQueryProvider();
if (filter != null) return filter.runQuery(constraint);
}
mToken = token;
final String constraint_escaped = constraint != null ? constraint.toString().replaceAll("_", "^_") : null;
if (isAtSymbol(token)) {
final StringBuilder builder = new StringBuilder();
builder.append(CachedUsers.SCREEN_NAME + " LIKE ?||'%' ESCAPE '^'");
builder.append(" OR ");
builder.append(CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'");
builder.append(" OR ");
builder.append(Where.in(new Column(CachedUsers.USER_ID),
new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL());
final String selection = constraint_escaped != null ? builder.toString() : null;
final String[] selectionArgs = constraint_escaped != null ? new String[]{constraint_escaped,
constraint_escaped} : null;
final String orderBy = CachedUsers.SCREEN_NAME + ", " + CachedUsers.NAME;
return mResolver.query(CachedUsers.CONTENT_URI, CACHED_USERS_COLUMNS, selection, selectionArgs, orderBy);
} else {
final String selection = constraint_escaped != null ? CachedHashtags.NAME + " LIKE ?||'%' ESCAPE '^'"
: null;
final String[] selectionArgs = constraint_escaped != null ? new String[]{constraint_escaped} : null;
return mDatabase.query(true, CachedHashtags.TABLE_NAME, CachedHashtags.COLUMNS, selection, selectionArgs,
null, null, CachedHashtags.NAME, null);
}
}
@Override
public Cursor swapCursor(final Cursor cursor) {
if (cursor != null) {
mNameIdx = cursor.getColumnIndex(CachedValues.NAME);
mScreenNameIdx = cursor.getColumnIndex(CachedUsers.SCREEN_NAME);
mUserIdIdx = cursor.getColumnIndex(CachedUsers.USER_ID);
mProfileImageUrlIdx = cursor.getColumnIndex(CachedUsers.PROFILE_IMAGE_URL);
}
return super.swapCursor(cursor);
}
@Override
public Cursor swapCursor(final Cursor cursor) {
if (cursor != null) {
mNameIdx = cursor.getColumnIndex(CachedValues.NAME);
mScreenNameIdx = cursor.getColumnIndex(CachedUsers.SCREEN_NAME);
mUserIdIdx = cursor.getColumnIndex(CachedUsers.USER_ID);
mProfileImageUrlIdx = cursor.getColumnIndex(CachedUsers.PROFILE_IMAGE_URL);
}
return super.swapCursor(cursor);
}
private long[] getMatchedNicknameIds(final String str) {
if (TextUtils.isEmpty(str)) return new long[0];
final List<Long> list = new ArrayList<Long>();
for (final Entry<String, ?> entry : mUserNicknamePreferences.getAll().entrySet()) {
final String value = ParseUtils.parseString(entry.getValue());
final long key = ParseUtils.parseLong(entry.getKey(), -1);
if (key == -1 || TextUtils.isEmpty(value)) {
continue;
}
if (value.toLowerCase(mLocale).startsWith(str.toLowerCase(mLocale))) {
list.add(key);
}
}
return ArrayUtils.fromList(list);
}
private long[] getMatchedNicknameIds(final String str) {
if (TextUtils.isEmpty(str)) return new long[0];
final List<Long> list = new ArrayList<Long>();
for (final Entry<String, ?> entry : mUserNicknamePreferences.getAll().entrySet()) {
final String value = ParseUtils.parseString(entry.getValue());
final long key = ParseUtils.parseLong(entry.getKey(), -1);
if (key == -1 || TextUtils.isEmpty(value)) {
continue;
}
if (value.toLowerCase(mLocale).startsWith(str.toLowerCase(mLocale))) {
list.add(key);
}
}
return ArrayUtils.fromList(list);
}
private static boolean isAtSymbol(final char character) {
switch (character) {
case '\uff20':
case '@':
return true;
}
return false;
}
private static boolean isAtSymbol(final char character) {
switch (character) {
case '\uff20':
case '@':
return true;
}
return false;
}
}

View File

@ -1,62 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.content;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.view.ContextThemeWrapper;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
public class TwidereContextThemeWrapper extends ContextThemeWrapper implements ITwidereContextWrapper {
private final int mThemeResourceId;
private final int mAccentColor;
private Theme mTheme;
public TwidereContextThemeWrapper(final Context base, final int themeResource, final int accentColor) {
super(base, themeResource);
mThemeResourceId = themeResource;
mAccentColor = accentColor;
}
public int getAccentColor() {
return mAccentColor;
}
@Override
public Theme getTheme() {
if (mTheme == null) {
mTheme = getResources().newTheme();
mTheme.setTo(super.getTheme());
final int getThemeResourceId = getThemeResourceId();
if (getThemeResourceId != 0) {
mTheme.applyStyle(getThemeResourceId, true);
}
}
return mTheme;
}
@Override
public int getThemeResourceId() {
return mThemeResourceId;
}
}

View File

@ -1,80 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.content;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
import org.mariotaku.twidere.content.res.NoAccentResources;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.theme.TwidereResourceHelper;
public class TwidereContextWrapper extends ContextWrapper implements ITwidereContextWrapper {
private final Resources mResources;
private final int mThemeResourceId;
private Theme mTheme;
public TwidereContextWrapper(final Context base) {
this(base, null, getThemeResource(base));
}
public TwidereContextWrapper(final Context base, final int theme) {
this(base, null, theme);
}
public TwidereContextWrapper(final Context base, final Resources res) {
this(base, res, getThemeResource(base));
}
public TwidereContextWrapper(final Context base, final Resources res, final int theme) {
super(base);
mResources = res;
mThemeResourceId = theme;
}
@Override
public Theme getTheme() {
if (mTheme == null) {
mTheme = getResources().newTheme();
mTheme.setTo(super.getTheme());
final int getThemeResourceId = getThemeResourceId();
if (getThemeResourceId != 0) {
mTheme.applyStyle(getThemeResourceId, true);
}
}
return mTheme;
}
@Override
public int getThemeResourceId() {
return mThemeResourceId;
}
private static int getThemeResource(final Context base) {
if (base instanceof ITwidereContextWrapper)
return ((ITwidereContextWrapper) base).getThemeResourceId();
else
return 0;
}
}

View File

@ -1,6 +0,0 @@
package org.mariotaku.twidere.content.iface;
public interface ITwidereContextWrapper {
public int getThemeResourceId();
}

View File

@ -1,56 +0,0 @@
/*******************************************************************************
* Copyright 2013 NEGU Soft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.mariotaku.twidere.content.res;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Extends the default android Resources to replace and modify
* drawables at runtime and apply the accent color.
* <br/><br/>
* "openRawResource()" and "getDrawable()" are called when inflating
* XML drawable resources. By overriding them, we can replace the
* components that form the drawables at runtime.
* <br/><br/>
* For the OverScroll, the native android drawables are modified
* directly. We look up their id by name, and then we replace the
* drawable with a tinted version by applying a ColorFilter.
*/
public class NoAccentResources extends Resources {
public NoAccentResources(Context c, Resources resources) {
super(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
}
}

View File

@ -61,18 +61,18 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
private final Canvas mCanvas;
private final int mIconWidth, mIconHeight;
private final int mRectrangleSize, mNumRectanglesHorizontal, mNumRectanglesVertical;
private final int mRectangleSize, mNumRectanglesHorizontal, mNumRectanglesVertical;
public ColorPickerDialog(final Context context, final int initialColor, final boolean showAlphaSlider) {
super(context);
mColorsAdapter = new ColorsAdapter(context);
mColorsAdapter = new ColorsAdapter(this, context);
mResources = context.getResources();
final float density = mResources.getDisplayMetrics().density;
mIconWidth = (int) (32 * density);
mIconHeight = (int) (32 * density);
mRectrangleSize = (int) (density * 5);
mNumRectanglesHorizontal = (int) Math.ceil(mIconWidth / mRectrangleSize);
mNumRectanglesVertical = (int) Math.ceil(mIconHeight / mRectrangleSize);
mRectangleSize = (int) (density * 5);
mNumRectanglesHorizontal = (int) Math.ceil(mIconWidth / mRectangleSize);
mNumRectanglesVertical = (int) Math.ceil(mIconHeight / mRectangleSize);
mTempBitmap = Bitmap.createBitmap(mIconWidth, mIconHeight, Config.ARGB_8888);
mCanvas = new Canvas(mTempBitmap);
init(context, initialColor, showAlphaSlider);
@ -91,13 +91,6 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
setIcon(new BitmapDrawable(mResources, mTempBitmap));
}
// @Override
// public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
// final int color = mColorsAdapter.getItem(position);
// if (mColorPicker == null) return;
// mColorPicker.setColor(color, true);
// }
public final void setAlphaSliderVisible(final boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
}
@ -147,10 +140,10 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
boolean isWhite = verticalStartWhite;
for (int j = 0; j <= mNumRectanglesHorizontal; j++) {
r.top = i * mRectrangleSize;
r.left = j * mRectrangleSize;
r.bottom = r.top + mRectrangleSize;
r.right = r.left + mRectrangleSize;
r.top = i * mRectangleSize;
r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize;
final Paint paint = new Paint();
paint.setColor(isWhite ? Color.WHITE : Color.GRAY);
@ -172,12 +165,14 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
}
public static class ColorsAdapter extends ArrayRecyclerAdapter<Integer, ColorViewHolder> {
private static class ColorsAdapter extends ArrayRecyclerAdapter<Integer, ColorViewHolder> implements View.OnClickListener {
private final ColorPickerDialog mDialog;
private final LayoutInflater mInflater;
private int mCurrentColor;
public ColorsAdapter(final Context context) {
public ColorsAdapter(ColorPickerDialog dialog, final Context context) {
mDialog = dialog;
mInflater = LayoutInflater.from(context);
}
@ -188,12 +183,21 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
@Override
public void onBindViewHolder(ColorViewHolder holder, int position, Integer item) {
holder.setColor(item, mCurrentColor == item);
holder.setItem(position, item, mCurrentColor == item);
}
@Override
public ColorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ColorViewHolder(mInflater.inflate(R.layout.gallery_item_color_picker_preset, parent, false));
final View view = mInflater.inflate(R.layout.gallery_item_color_picker_preset, parent, false);
view.setOnClickListener(this);
return new ColorViewHolder(view);
}
@Override
public void onClick(View v) {
final Object tag = v.getTag();
if (!(tag instanceof Integer)) return;
mDialog.mColorPicker.setColor(getItem((Integer) tag), true);
}
}
@ -206,7 +210,8 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
colorView = (ForegroundColorView) itemView.findViewById(R.id.color);
}
public void setColor(int color, boolean activated) {
public void setItem(int position, int color, boolean activated) {
itemView.setTag(position);
colorView.setColor(color);
colorView.setActivated(activated);
}

View File

@ -25,33 +25,15 @@ import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
public class BaseFragment extends Fragment implements Constants {
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final Activity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
public TwidereApplication getApplication() {
final Activity activity = getActivity();
if (activity != null) return (TwidereApplication) activity.getApplication();

View File

@ -27,8 +27,6 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
@ -36,10 +34,8 @@ import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Utils;
@ -92,20 +88,6 @@ public class BaseListFragment extends ListFragment implements Constants, OnScrol
activity.invalidateOptionsMenu();
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final Activity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
public boolean isActivityFirstCreated() {
return mActivityFirstCreated;
}

View File

@ -19,15 +19,10 @@
package org.mariotaku.twidere.fragment;
import android.app.Activity;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
public class BasePreferenceFragment extends PreferenceFragment implements Constants {
@ -37,17 +32,4 @@ public class BasePreferenceFragment extends PreferenceFragment implements Consta
getPreferenceManager().setSharedPreferencesName(SHARED_PREFERENCES_NAME);
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final Activity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
}

View File

@ -36,6 +36,7 @@ import android.text.TextUtils;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
@ -53,9 +54,7 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.CustomTabEditorActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.CustomTabConfiguration;
import org.mariotaku.twidere.model.CustomTabConfiguration.CustomTabConfigurationComparator;
import org.mariotaku.twidere.model.Panes;
@ -116,13 +115,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
setHasOptionsMenu(true);
mResolver = getContentResolver();
final Activity activity = getActivity();
final int themeRes;
if (activity instanceof IThemedActivity) {
themeRes = ((IThemedActivity) activity).getThemeResourceId();
} else {
themeRes = ThemeUtils.getSettingsThemeResource(activity);
}
mAdapter = new CustomTabsAdapter(ThemeUtils.getThemedContextForActionIcons(activity, themeRes));
mAdapter = new CustomTabsAdapter(activity);
setListAdapter(mAdapter);
setEmptyText(getString(R.string.no_tab_hint));
mListView = (DragSortListView) getListView();
@ -166,7 +159,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
@Override
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
new TwidereMenuInflater(getActivity()).inflate(R.menu.action_multi_select_items, menu);
mode.getMenuInflater().inflate(R.menu.action_multi_select_items, menu);
return true;
}
@ -176,7 +169,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_custom_tabs, menu);
}
@ -281,6 +274,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
subItem.setIntent(intent);
}
}
ThemeUtils.applyColorFilterToMenuIcon(getActivity(), menu);
}
@Override

View File

@ -38,6 +38,7 @@ import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -52,7 +53,6 @@ import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ArrayAdapter;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.task.AsyncTask;
import org.mariotaku.twidere.util.HostsFileParser;
import org.mariotaku.twidere.util.ParseUtils;
@ -109,12 +109,12 @@ public class HostMappingsListFragment extends BaseListFragment implements MultiC
@Override
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
new TwidereMenuInflater(getActivity()).inflate(R.menu.action_multi_select_items, menu);
mode.getMenuInflater().inflate(R.menu.action_multi_select_items, menu);
return true;
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_host_mapping, menu);
}

View File

@ -31,6 +31,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -38,6 +39,7 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -63,7 +65,6 @@ import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.activity.support.UserProfileEditorActivity;
import org.mariotaku.twidere.adapter.ArrayAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.content.TwidereContextThemeWrapper;
import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.provider.TweetStore.DirectMessages;
@ -351,10 +352,9 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
if (mThemedContext != null) return mThemedContext;
final Context context = getActivity();
if (!ThemeUtils.isDarkDrawerEnabled(context))
return mThemedContext = ThemeUtils.getThemedContextForActionIcons(context);
return mThemedContext = context;
final int themeResource = ThemeUtils.getDrawerThemeResource(context);
final int accentColor = ThemeUtils.getUserAccentColor(context);
return mThemedContext = new TwidereContextThemeWrapper(context, themeResource, accentColor);
return mThemedContext = new ContextThemeWrapper(context, themeResource);
}
private void updateAccountOptionsSeparatorLabel() {
@ -487,7 +487,7 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
private OnAccountActivateStateChangeListener mOnAccountActivateStateChangeListener;
public DrawerAccountsAdapter(final Context context) {
super(context, R.layout.list_item_drawer_accounts, null, new String[0], new int[0], 0);
super(context, R.layout.list_item_drawer_account, null, new String[0], new int[0], 0);
final TwidereApplication app = TwidereApplication.getInstance(context);
mImageLoader = app.getImageLoaderWrapper();
mActivatedColor = ThemeUtils.getUserAccentColor(context);
@ -622,11 +622,11 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
private static abstract class OptionItemsAdapter extends ArrayAdapter<OptionItem> {
private final int mMenuIconColor;
private final int mActionIconColor;
public OptionItemsAdapter(final Context context) {
super(context, R.layout.list_item_menu);
mMenuIconColor = ThemeUtils.getThemeForegroundColor(context);
mActionIconColor = ThemeUtils.getThemeForegroundColor(context);
}
@Override
@ -637,7 +637,7 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
text1.setText(option.name);
icon.setImageDrawable(icon.getResources().getDrawable(option.icon));
icon.setColorFilter(mMenuIconColor);
icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
return view;
}

View File

@ -10,6 +10,7 @@ import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -21,7 +22,6 @@ import com.mobeta.android.dslv.DragSortListView.DropListener;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.SignInActivity;
import org.mariotaku.twidere.adapter.AccountsAdapter;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.util.Utils;
@ -46,7 +46,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements
}
@Override
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_accounts_manager, menu);
}

View File

@ -25,14 +25,9 @@ import android.content.ContentResolver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
public class BaseSupportDialogFragment extends DialogFragment implements Constants {
@ -41,20 +36,6 @@ public class BaseSupportDialogFragment extends DialogFragment implements Constan
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final FragmentActivity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
public TwidereApplication getApplication() {
final Activity activity = getActivity();
if (activity != null) return (TwidereApplication) activity.getApplication();

View File

@ -24,44 +24,20 @@ import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.ThemeUtils;
public class BaseSupportFragment extends Fragment implements Constants {
private LayoutInflater mLayoutInflater;
public BaseSupportFragment() {
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final FragmentActivity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
public TwidereApplication getApplication() {
final Activity activity = getActivity();
if (activity != null) return (TwidereApplication) activity.getApplication();
@ -74,12 +50,6 @@ public class BaseSupportFragment extends Fragment implements Constants {
return null;
}
@Override
public LayoutInflater getLayoutInflater(final Bundle savedInstanceState) {
if (mLayoutInflater != null) return mLayoutInflater;
return mLayoutInflater = ThemeUtils.getThemedLayoutInflaterForActionIcons(getActivity());
}
public MultiSelectManager getMultiSelectManager() {
return getApplication() != null ? getApplication().getMultiSelectManager() : null;
}

View File

@ -32,8 +32,6 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
@ -49,13 +47,11 @@ import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ListScrollDistanceCalculator;
import org.mariotaku.twidere.util.ListScrollDistanceCalculator.ScrollDistanceListener;
@ -78,25 +74,9 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
private boolean mReachedTop, mNotReachedTopBefore;
private LayoutInflater mLayoutInflater;
private boolean mStoppedPreviously;
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final FragmentActivity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
public final TwidereApplication getApplication() {
return TwidereApplication.getInstance(getActivity());
}
@ -117,12 +97,6 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
return extras;
}
@Override
public LayoutInflater getLayoutInflater(final Bundle savedInstanceState) {
if (mLayoutInflater != null) return mLayoutInflater;
return mLayoutInflater = ThemeUtils.getThemedLayoutInflaterForActionIcons(getActivity());
}
public final MultiSelectManager getMultiSelectManager() {
return getApplication() != null ? getApplication().getMultiSelectManager() : null;
}

View File

@ -27,10 +27,7 @@ import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
@ -39,13 +36,11 @@ import android.widget.AbsListView.OnScrollListener;
import com.etsy.android.grid.StaggeredGridView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Utils;
@ -81,20 +76,6 @@ public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment impl
return null;
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final FragmentActivity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
@Override
public Bundle getExtraConfiguration() {
final Bundle args = getArguments();

View File

@ -21,15 +21,10 @@ package org.mariotaku.twidere.fragment.support;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.webkit.WebSettings;
import android.webkit.WebView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.util.accessor.WebSettingsAccessor;
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient;
@ -47,17 +42,4 @@ public class BaseSupportWebViewFragment extends SupportWebViewFragment implement
WebSettingsAccessor.setAllowUniversalAccessFromFileURLs(settings, true);
}
@Override
public final void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final FragmentActivity activity = getActivity();
if (activity instanceof IThemedActivity) {
onCreateOptionsMenu(menu, ((IThemedActivity) activity).getTwidereMenuInflater());
} else {
super.onCreateOptionsMenu(menu, inflater);
}
}
public void onCreateOptionsMenu(Menu menu, TwidereMenuInflater inflater) {
}
}

View File

@ -19,14 +19,6 @@
package org.mariotaku.twidere.fragment.support;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.getOldestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.showOkMessage;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -65,7 +57,6 @@ import android.widget.TextView.OnEditorActionListener;
import org.mariotaku.menucomponent.widget.PopupMenu;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.ImagePickerActivity;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
@ -91,445 +82,449 @@ import org.mariotaku.twidere.view.StatusTextCountView;
import java.util.List;
import java.util.Locale;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.getOldestMessageIdsFromDatabase;
import static org.mariotaku.twidere.util.Utils.showOkMessage;
public class DirectMessagesConversationFragment extends BasePullToRefreshListFragment implements
LoaderCallbacks<Cursor>, OnMenuItemClickListener, TextWatcher, OnClickListener, Panes.Right,
OnItemSelectedListener, OnEditorActionListener, MenuButtonClickListener {
LoaderCallbacks<Cursor>, OnMenuItemClickListener, TextWatcher, OnClickListener, Panes.Right,
OnItemSelectedListener, OnEditorActionListener, MenuButtonClickListener {
private TwidereValidator mValidator;
private AsyncTwitterWrapper mTwitterWrapper;
private SharedPreferences mPreferences;
private TwidereValidator mValidator;
private AsyncTwitterWrapper mTwitterWrapper;
private SharedPreferences mPreferences;
private ListView mListView;
private EditText mEditText;
private StatusTextCountView mTextCountView;
private View mSendButton;
private ImageView mAddImageButton;
private View mConversationContainer, mRecipientSelectorContainer, mRecipientSelector;
private Spinner mAccountSpinner;
private ListView mListView;
private EditText mEditText;
private StatusTextCountView mTextCountView;
private View mSendButton;
private ImageView mAddImageButton;
private View mConversationContainer, mRecipientSelectorContainer, mRecipientSelector;
private Spinner mAccountSpinner;
private PopupMenu mPopupMenu;
private PopupMenu mPopupMenu;
private ParcelableDirectMessage mSelectedDirectMessage;
private long mAccountId, mRecipientId;
private boolean mLoaderInitialized;
private boolean mLoadMoreAutomatically;
private String mImageUri;
private ParcelableDirectMessage mSelectedDirectMessage;
private long mAccountId, mRecipientId;
private boolean mLoaderInitialized;
private boolean mLoadMoreAutomatically;
private String mImageUri;
private Locale mLocale;
private Locale mLocale;
private DirectMessagesConversationAdapter mAdapter;
private DirectMessagesConversationAdapter mAdapter;
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (getActivity() == null || !isAdded() || isDetached()) return;
final String action = intent.getAction();
if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
updateRefreshState();
}
}
};
@Override
public void onReceive(final Context context, final Intent intent) {
if (getActivity() == null || !isAdded() || isDetached()) return;
final String action = intent.getAction();
if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
updateRefreshState();
}
}
};
@Override
public void afterTextChanged(final Editable s) {
@Override
public void afterTextChanged(final Editable s) {
}
}
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
}
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTwitterWrapper = getTwitterWrapper();
mValidator = new TwidereValidator(getActivity());
mLocale = getResources().getConfiguration().locale;
mAdapter = new DirectMessagesConversationAdapter(getActivity());
setListAdapter(mAdapter);
mAdapter.setMenuButtonClickListener(this);
mListView = getListView();
mListView.setDivider(null);
mListView.setSelector(android.R.color.transparent);
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
mListView.setStackFromBottom(true);
setListShownNoAnimation(false);
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTwitterWrapper = getTwitterWrapper();
mValidator = new TwidereValidator(getActivity());
mLocale = getResources().getConfiguration().locale;
mAdapter = new DirectMessagesConversationAdapter(getActivity());
setListAdapter(mAdapter);
mAdapter.setMenuButtonClickListener(this);
mListView = getListView();
mListView.setDivider(null);
mListView.setSelector(android.R.color.transparent);
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
mListView.setStackFromBottom(true);
setListShownNoAnimation(false);
if (mPreferences.getBoolean(KEY_QUICK_SEND, false)) {
mEditText.setOnEditorActionListener(this);
}
mEditText.addTextChangedListener(this);
if (mPreferences.getBoolean(KEY_QUICK_SEND, false)) {
mEditText.setOnEditorActionListener(this);
}
mEditText.addTextChangedListener(this);
final List<Account> accounts = Account.getAccountsList(getActivity(), false);
mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts));
mAccountSpinner.setOnItemSelectedListener(this);
final List<Account> accounts = Account.getAccountsList(getActivity(), false);
mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts));
mAccountSpinner.setOnItemSelectedListener(this);
mSendButton.setOnClickListener(this);
mAddImageButton.setOnClickListener(this);
mSendButton.setEnabled(false);
mRecipientSelector.setOnClickListener(this);
if (savedInstanceState != null) {
final long accountId = savedInstanceState.getLong(EXTRA_ACCOUNT_ID, -1);
final long recipientId = savedInstanceState.getLong(EXTRA_RECIPIENT_ID, -1);
showConversation(accountId, recipientId);
mEditText.setText(savedInstanceState.getString(EXTRA_TEXT));
mImageUri = savedInstanceState.getString(EXTRA_IMAGE_URI);
} else {
final Bundle args = getArguments();
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long recipientId = args != null ? args.getLong(EXTRA_RECIPIENT_ID, -1) : -1;
showConversation(accountId, recipientId);
}
final boolean isValid = mAccountId > 0 && mRecipientId > 0;
mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE);
mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE);
}
mSendButton.setOnClickListener(this);
mAddImageButton.setOnClickListener(this);
mSendButton.setEnabled(false);
mRecipientSelector.setOnClickListener(this);
if (savedInstanceState != null) {
final long accountId = savedInstanceState.getLong(EXTRA_ACCOUNT_ID, -1);
final long recipientId = savedInstanceState.getLong(EXTRA_RECIPIENT_ID, -1);
showConversation(accountId, recipientId);
mEditText.setText(savedInstanceState.getString(EXTRA_TEXT));
mImageUri = savedInstanceState.getString(EXTRA_IMAGE_URI);
} else {
final Bundle args = getArguments();
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long recipientId = args != null ? args.getLong(EXTRA_RECIPIENT_ID, -1) : -1;
showConversation(accountId, recipientId);
}
final boolean isValid = mAccountId > 0 && mRecipientId > 0;
mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE);
mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE);
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_SELECT_USER: {
if (resultCode != Activity.RESULT_OK || !data.hasExtra(EXTRA_USER)) {
break;
}
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
if (user != null && mAccountId > 0) {
mRecipientId = user.id;
showConversation(mAccountId, mRecipientId);
}
break;
}
case REQUEST_PICK_IMAGE: {
if (resultCode != Activity.RESULT_OK || data.getDataString() == null) {
break;
}
mImageUri = data.getDataString();
updateAddImageButton();
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_SELECT_USER: {
if (resultCode != Activity.RESULT_OK || !data.hasExtra(EXTRA_USER)) {
break;
}
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
if (user != null && mAccountId > 0) {
mRecipientId = user.id;
showConversation(mAccountId, mRecipientId);
}
break;
}
case REQUEST_PICK_IMAGE: {
if (resultCode != Activity.RESULT_OK || data.getDataString() == null) {
break;
}
mImageUri = data.getDataString();
updateAddImageButton();
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.send: {
sendDirectMessage();
break;
}
case R.id.recipient_selector: {
if (mAccountId <= 0) return;
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(getActivity(), UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, mAccountId);
startActivityForResult(intent, REQUEST_SELECT_USER);
break;
}
case R.id.add_image: {
final Intent intent = new Intent(getActivity(), ImagePickerActivity.class);
startActivityForResult(intent, REQUEST_PICK_IMAGE);
break;
}
}
}
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.send: {
sendDirectMessage();
break;
}
case R.id.recipient_selector: {
if (mAccountId <= 0) return;
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(getActivity(), UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, mAccountId);
startActivityForResult(intent, REQUEST_SELECT_USER);
break;
}
case R.id.add_image: {
final Intent intent = new Intent(getActivity(), ImagePickerActivity.class);
startActivityForResult(intent, REQUEST_PICK_IMAGE);
break;
}
}
}
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long recipientId = args != null ? args.getLong(EXTRA_RECIPIENT_ID, -1) : -1;
final String[] cols = DirectMessages.COLUMNS;
final boolean isValid = accountId > 0 && recipientId > 0;
mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE);
mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE);
if (!isValid) return new CursorLoader(getActivity(), TweetStore.CONTENT_URI_NULL, cols, null, null, null);
final Uri uri = buildDirectMessageConversationUri(accountId, recipientId, null);
return new CursorLoader(getActivity(), uri, cols, null, null, Conversation.DEFAULT_SORT_ORDER);
}
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long recipientId = args != null ? args.getLong(EXTRA_RECIPIENT_ID, -1) : -1;
final String[] cols = DirectMessages.COLUMNS;
final boolean isValid = accountId > 0 && recipientId > 0;
mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE);
mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE);
if (!isValid)
return new CursorLoader(getActivity(), TweetStore.CONTENT_URI_NULL, cols, null, null, null);
final Uri uri = buildDirectMessageConversationUri(accountId, recipientId, null);
return new CursorLoader(getActivity(), uri, cols, null, null, Conversation.DEFAULT_SORT_ORDER);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_messages_conversation, null);
final FrameLayout listContainer = (FrameLayout) view.findViewById(R.id.list_container);
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
listContainer.addView(super.onCreateView(inflater, container, savedInstanceState), lp);
final ViewGroup inputSendContainer = (ViewGroup) view.findViewById(R.id.input_send_container);
final FragmentActivity activity = getActivity();
final int themeRes;
if (activity instanceof IThemedActivity) {
themeRes = ((IThemedActivity) activity).getThemeResourceId();
} else {
themeRes = ThemeUtils.getThemeResource(activity);
}
ViewAccessor.setBackground(inputSendContainer, ThemeUtils.getActionBarSplitBackground(activity, themeRes));
final Context actionBarContext = ThemeUtils.getActionBarContext(activity);
View.inflate(actionBarContext, R.layout.fragment_messages_conversation_input_send, inputSendContainer);
return view;
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_messages_conversation, null);
final FrameLayout listContainer = (FrameLayout) view.findViewById(R.id.list_container);
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
listContainer.addView(super.onCreateView(inflater, container, savedInstanceState), lp);
final ViewGroup inputSendContainer = (ViewGroup) view.findViewById(R.id.input_send_container);
final FragmentActivity activity = getActivity();
final int themeRes = ThemeUtils.getThemeResource(activity);
ViewAccessor.setBackground(inputSendContainer, ThemeUtils.getActionBarSplitBackground(activity, themeRes));
final Context actionBarContext = ThemeUtils.getActionBarContext(activity);
View.inflate(actionBarContext, R.layout.fragment_messages_conversation_input_send, inputSendContainer);
return view;
}
@Override
public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_ENTER: {
sendDirectMessage();
return true;
}
}
return false;
}
@Override
public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_ENTER: {
sendDirectMessage();
return true;
}
}
return false;
}
@Override
public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) {
final Account account = (Account) mAccountSpinner.getSelectedItem();
if (account != null) {
mAccountId = account.account_id;
}
}
@Override
public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) {
final Account account = (Account) mAccountSpinner.getSelectedItem();
if (account != null) {
mAccountId = account.account_id;
}
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
mAdapter.swapCursor(cursor);
setListShown(true);
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
mAdapter.swapCursor(cursor);
setListShown(true);
}
@Override
public void onMenuButtonClick(final View button, final int position, final long id) {
mSelectedDirectMessage = mAdapter.findItem(id);
showMenu(button, mSelectedDirectMessage);
}
@Override
public void onMenuButtonClick(final View button, final int position, final long id) {
mSelectedDirectMessage = mAdapter.findItem(id);
showMenu(button, mSelectedDirectMessage);
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
if (mSelectedDirectMessage != null) {
final long message_id = mSelectedDirectMessage.id;
final long account_id = mSelectedDirectMessage.account_id;
switch (item.getItemId()) {
case MENU_DELETE: {
mTwitterWrapper.destroyDirectMessageAsync(account_id, message_id);
break;
}
case MENU_COPY: {
if (ClipboardUtils.setText(getActivity(), mSelectedDirectMessage.text_plain)) {
showOkMessage(getActivity(), R.string.text_copied, false);
}
break;
}
default:
return false;
}
}
return true;
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
if (mSelectedDirectMessage != null) {
final long message_id = mSelectedDirectMessage.id;
final long account_id = mSelectedDirectMessage.account_id;
switch (item.getItemId()) {
case MENU_DELETE: {
mTwitterWrapper.destroyDirectMessageAsync(account_id, message_id);
break;
}
case MENU_COPY: {
if (ClipboardUtils.setText(getActivity(), mSelectedDirectMessage.text_plain)) {
showOkMessage(getActivity(), R.string.text_copied, false);
}
break;
}
default:
return false;
}
}
return true;
}
@Override
public void onNothingSelected(final AdapterView<?> view) {
@Override
public void onNothingSelected(final AdapterView<?> view) {
}
}
@Override
public void onRefreshFromEnd() {
new AsyncTask<Void, Void, long[][]>() {
@Override
public void onRefreshFromEnd() {
new AsyncTask<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 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);
}
@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);
}
}.execute();
}
}.execute();
}
@Override
public void onRefreshFromStart() {
loadMoreMessages();
}
@Override
public void onRefreshFromStart() {
loadMoreMessages();
}
@Override
public void onResume() {
super.onResume();
configBaseCardAdapter(getActivity(), mAdapter);
final boolean displayImagePreview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
final String previewScaleType = Utils.getNonEmptyString(mPreferences, KEY_IMAGE_PREVIEW_SCALE_TYPE,
ScaleType.CENTER_CROP.name());
mAdapter.setDisplayImagePreview(displayImagePreview);
mAdapter.setImagePreviewScaleType(previewScaleType);
mAdapter.notifyDataSetChanged();
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
updateAddImageButton();
}
@Override
public void onResume() {
super.onResume();
configBaseCardAdapter(getActivity(), mAdapter);
final boolean displayImagePreview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
final String previewScaleType = Utils.getNonEmptyString(mPreferences, KEY_IMAGE_PREVIEW_SCALE_TYPE,
ScaleType.CENTER_CROP.name());
mAdapter.setDisplayImagePreview(displayImagePreview);
mAdapter.setImagePreviewScaleType(previewScaleType);
mAdapter.notifyDataSetChanged();
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
updateAddImageButton();
}
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
if (mEditText != null) {
outState.putCharSequence(EXTRA_TEXT, mEditText.getText());
}
outState.putLong(EXTRA_ACCOUNT_ID, mAccountId);
outState.putLong(EXTRA_RECIPIENT_ID, mRecipientId);
outState.putString(EXTRA_IMAGE_URI, mImageUri);
}
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
if (mEditText != null) {
outState.putCharSequence(EXTRA_TEXT, mEditText.getText());
}
outState.putLong(EXTRA_ACCOUNT_ID, mAccountId);
outState.putLong(EXTRA_RECIPIENT_ID, mRecipientId);
outState.putString(EXTRA_IMAGE_URI, mImageUri);
}
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_TASK_STATE_CHANGED);
registerReceiver(mStatusReceiver, filter);
updateTextCount();
}
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_TASK_STATE_CHANGED);
registerReceiver(mStatusReceiver, filter);
updateTextCount();
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
if (mPopupMenu != null) {
mPopupMenu.dismiss();
}
super.onStop();
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
if (mPopupMenu != null) {
mPopupMenu.dismiss();
}
super.onStop();
}
@Override
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
updateTextCount();
if (mSendButton == null || s == null) return;
mSendButton.setEnabled(mValidator.isValidTweet(s.toString()));
}
@Override
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
updateTextCount();
if (mSendButton == null || s == null) return;
mSendButton.setEnabled(mValidator.isValidTweet(s.toString()));
}
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final View inputSendContainer = view.findViewById(R.id.input_send_container);
mConversationContainer = view.findViewById(R.id.conversation_container);
mRecipientSelectorContainer = view.findViewById(R.id.recipient_selector_container);
mRecipientSelector = view.findViewById(R.id.recipient_selector);
mAccountSpinner = (Spinner) view.findViewById(R.id.account_selector);
mEditText = (EditText) inputSendContainer.findViewById(R.id.edit_text);
mTextCountView = (StatusTextCountView) inputSendContainer.findViewById(R.id.text_count);
mSendButton = inputSendContainer.findViewById(R.id.send);
mAddImageButton = (ImageView) inputSendContainer.findViewById(R.id.add_image);
mRecipientSelector = view.findViewById(R.id.recipient_selector);
}
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final View inputSendContainer = view.findViewById(R.id.input_send_container);
mConversationContainer = view.findViewById(R.id.conversation_container);
mRecipientSelectorContainer = view.findViewById(R.id.recipient_selector_container);
mRecipientSelector = view.findViewById(R.id.recipient_selector);
mAccountSpinner = (Spinner) view.findViewById(R.id.account_selector);
mEditText = (EditText) inputSendContainer.findViewById(R.id.edit_text);
mTextCountView = (StatusTextCountView) inputSendContainer.findViewById(R.id.text_count);
mSendButton = inputSendContainer.findViewById(R.id.send);
mAddImageButton = (ImageView) inputSendContainer.findViewById(R.id.add_image);
mRecipientSelector = view.findViewById(R.id.recipient_selector);
}
@Override
public boolean scrollToStart() {
if (mAdapter == null || mAdapter.isEmpty()) return false;
setSelection(mAdapter.getCount() - 1);
return true;
}
@Override
public boolean scrollToStart() {
if (mAdapter == null || mAdapter.isEmpty()) return false;
setSelection(mAdapter.getCount() - 1);
return true;
}
public void showConversation(final long accountId, final long recipientId) {
mAccountId = accountId;
mRecipientId = recipientId;
final LoaderManager lm = getLoaderManager();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, accountId);
args.putLong(EXTRA_RECIPIENT_ID, recipientId);
if (mLoaderInitialized) {
lm.restartLoader(0, args, this);
} else {
mLoaderInitialized = true;
lm.initLoader(0, args, this);
}
}
public void showConversation(final long accountId, final long recipientId) {
mAccountId = accountId;
mRecipientId = recipientId;
final LoaderManager lm = getLoaderManager();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, accountId);
args.putLong(EXTRA_RECIPIENT_ID, recipientId);
if (mLoaderInitialized) {
lm.restartLoader(0, args, this);
} else {
mLoaderInitialized = true;
lm.initLoader(0, args, this);
}
}
@Override
protected void onReachedTop() {
if (!mLoadMoreAutomatically) return;
loadMoreMessages();
}
@Override
protected void onReachedTop() {
if (!mLoadMoreAutomatically) return;
loadMoreMessages();
}
protected void updateRefreshState() {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null || !getUserVisibleHint()) return;
final boolean refreshing = twitter.isReceivedDirectMessagesRefreshing()
|| twitter.isSentDirectMessagesRefreshing();
setProgressBarIndeterminateVisibility(refreshing);
setRefreshing(refreshing);
}
protected void updateRefreshState() {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null || !getUserVisibleHint()) return;
final boolean refreshing = twitter.isReceivedDirectMessagesRefreshing()
|| twitter.isSentDirectMessagesRefreshing();
setProgressBarIndeterminateVisibility(refreshing);
setRefreshing(refreshing);
}
private void loadMoreMessages() {
if (isRefreshing()) return;
new AsyncTask<Void, Void, long[][]>() {
private void loadMoreMessages() {
if (isRefreshing()) return;
new AsyncTask<Void, Void, long[][]>() {
@Override
protected long[][] doInBackground(final Void... params) {
final long[][] result = new long[3][];
result[0] = getActivatedAccountIds(getActivity());
result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
return result;
}
@Override
protected long[][] doInBackground(final Void... params) {
final long[][] result = new long[3][];
result[0] = getActivatedAccountIds(getActivity());
result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
return result;
}
@Override
protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
twitter.getSentDirectMessagesAsync(result[0], result[2], null);
}
@Override
protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
if (twitter == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
twitter.getSentDirectMessagesAsync(result[0], result[2], null);
}
}.execute();
}
}.execute();
}
private void sendDirectMessage() {
final Editable text = mEditText.getText();
if (isEmpty(text) || mAccountId <= 0 || mRecipientId <= 0) return;
final String message = text.toString();
if (mValidator.isValidTweet(message)) {
mTwitterWrapper.sendDirectMessageAsync(mAccountId, mRecipientId, message, mImageUri);
text.clear();
mImageUri = null;
updateAddImageButton();
}
}
private void sendDirectMessage() {
final Editable text = mEditText.getText();
if (isEmpty(text) || mAccountId <= 0 || mRecipientId <= 0) return;
final String message = text.toString();
if (mValidator.isValidTweet(message)) {
mTwitterWrapper.sendDirectMessageAsync(mAccountId, mRecipientId, message, mImageUri);
text.clear();
mImageUri = null;
updateAddImageButton();
}
}
private void showMenu(final View view, final ParcelableDirectMessage dm) {
if (mPopupMenu != null && mPopupMenu.isShowing()) {
mPopupMenu.dismiss();
}
final Context context = ThemeUtils.getThemedContextForActionIcons(getActivity());
mPopupMenu = PopupMenu.getInstance(context, view);
mPopupMenu.inflate(R.menu.action_direct_message);
final Menu menu = mPopupMenu.getMenu();
final MenuItem view_profile_item = menu.findItem(MENU_VIEW_PROFILE);
if (view_profile_item != null && dm != null) {
view_profile_item.setVisible(dm.account_id != dm.sender_id);
}
mPopupMenu.setOnMenuItemClickListener(this);
mPopupMenu.show();
}
private void showMenu(final View view, final ParcelableDirectMessage dm) {
if (mPopupMenu != null && mPopupMenu.isShowing()) {
mPopupMenu.dismiss();
}
final Context context = getActivity();
mPopupMenu = PopupMenu.getInstance(context, view);
mPopupMenu.inflate(R.menu.action_direct_message);
final Menu menu = mPopupMenu.getMenu();
final MenuItem view_profile_item = menu.findItem(MENU_VIEW_PROFILE);
if (view_profile_item != null && dm != null) {
view_profile_item.setVisible(dm.account_id != dm.sender_id);
}
mPopupMenu.setOnMenuItemClickListener(this);
mPopupMenu.show();
}
private void updateAddImageButton() {
final int color = ThemeUtils.getThemeColor(getActivity());
if (mImageUri != null) {
mAddImageButton.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
} else {
mAddImageButton.clearColorFilter();
}
}
private void updateAddImageButton() {
final int color = ThemeUtils.getThemeColor(getActivity());
if (mImageUri != null) {
mAddImageButton.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
} else {
mAddImageButton.clearColorFilter();
}
}
private void updateTextCount() {
if (mTextCountView == null || mEditText == null) return;
final int count = mValidator.getTweetLength(ParseUtils.parseString(mEditText.getText()));
mTextCountView.setTextCount(count);
}
private void updateTextCount() {
if (mTextCountView == null || mEditText == null) return;
final int count = mValidator.getTweetLength(ParseUtils.parseString(mEditText.getText()));
mTextCountView.setTextCount(count);
}
}

View File

@ -2,9 +2,9 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.model.Account.AccountWithCredentials;
import org.mariotaku.twidere.model.ParcelableUser;
@ -16,7 +16,7 @@ public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragmen
final Context context = getThemedContext();
final AccountWithCredentials account = Account.getAccountWithCredentials(context, user.account_id);
if (AccountWithCredentials.isOfficialCredentials(context, account)) {
final TwidereMenuInflater inflater = new TwidereMenuInflater(context);
final MenuInflater inflater = new MenuInflater(context);
inflater.inflate(R.menu.action_incoming_friendship, menu);
}
}

View File

@ -8,6 +8,7 @@ import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -18,7 +19,6 @@ import com.commonsware.cwac.merge.MergeAdapter;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.content.TwidereContextThemeWrapper;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment.TrendsAdapter;
import org.mariotaku.twidere.provider.TweetStore.CachedTrends;
import org.mariotaku.twidere.util.ThemeUtils;
@ -112,8 +112,8 @@ public class QuickMenuFragment extends BaseSupportFragment {
} else {
themeResource = ThemeUtils.getDrawerThemeResource(currentThemeResource);
}
final int accentColor = ThemeUtils.getUserAccentColor(context);
return mThemedContext = new TwidereContextThemeWrapper(context, themeResource, accentColor);
// final int accentColor = ThemeUtils.getUserAccentColor(context);
return mThemedContext = new ContextThemeWrapper(context, themeResource);
}
}

View File

@ -27,6 +27,7 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -36,7 +37,6 @@ import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.Panes;
import org.mariotaku.twidere.provider.RecentSearchProvider;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
@ -92,7 +92,7 @@ public class SearchFragment extends BaseSupportFragment implements Panes.Left, O
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_search, menu);
}

View File

@ -50,6 +50,7 @@ import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
@ -73,7 +74,6 @@ import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.model.Account.AccountWithCredentials;
import org.mariotaku.twidere.model.Panes;
@ -567,7 +567,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
if (!shouldUseNativeMenu()) return;
inflater.inflate(R.menu.menu_status, menu);
}

View File

@ -4,10 +4,10 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.MenuDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.Utils;
@ -16,7 +16,7 @@ import static org.mariotaku.twidere.util.Utils.setMenuForStatus;
public class StatusMenuDialogFragment extends MenuDialogFragment {
@Override
protected void onCreateMenu(final TwidereMenuInflater inflater, final Menu menu) {
protected void onCreateMenu(final MenuInflater inflater, final Menu menu) {
inflater.inflate(R.menu.action_status, menu);
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final Bundle args = getArguments();

View File

@ -5,10 +5,10 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.MenuDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.Utils;
@ -17,7 +17,7 @@ import static org.mariotaku.twidere.util.Utils.addIntentToMenu;
public class UserListMenuDialogFragment extends MenuDialogFragment {
@Override
protected void onCreateMenu(final TwidereMenuInflater inflater, final Menu menu) {
protected void onCreateMenu(final MenuInflater inflater, final Menu menu) {
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final Bundle args = getArguments();
final ParcelableUserList user = args.getParcelable(EXTRA_USER_LIST);

View File

@ -27,12 +27,12 @@ import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ParcelableUserListsAdapter;
import org.mariotaku.twidere.loader.support.UserListsLoader;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
@ -69,7 +69,7 @@ public class UserListsListFragment extends BaseUserListsListFragment {
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_user_list_created, menu);
}

View File

@ -5,9 +5,9 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import org.mariotaku.twidere.activity.support.MenuDialogFragment;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.Utils;
@ -16,7 +16,7 @@ import static org.mariotaku.twidere.util.Utils.addIntentToMenu;
public class UserMenuDialogFragment extends MenuDialogFragment {
@Override
protected void onCreateMenu(final TwidereMenuInflater inflater, final Menu menu) {
protected void onCreateMenu(final MenuInflater inflater, final Menu menu) {
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final Bundle args = getArguments();
final ParcelableUser user = args.getParcelable(EXTRA_USER);

View File

@ -46,6 +46,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
@ -72,7 +73,6 @@ import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.activity.support.UserProfileEditorActivity;
import org.mariotaku.twidere.adapter.ListActionAdapter;
import org.mariotaku.twidere.loader.support.ParcelableUserLoader;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.ListAction;
import org.mariotaku.twidere.model.Panes;
import org.mariotaku.twidere.model.ParcelableUser;
@ -567,7 +567,7 @@ public class UserProfileFragment extends BaseSupportListFragment implements OnCl
}
@Override
public void onCreateOptionsMenu(final Menu menu, final TwidereMenuInflater inflater) {
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
if (!shouldUseNativeMenu()) return;
inflater.inflate(R.menu.menu_user_profile, menu);
}
@ -633,8 +633,9 @@ public class UserProfileFragment extends BaseSupportListFragment implements OnCl
break;
}
case TwidereLinkify.LINK_TYPE_LIST: {
final String[] mention_list = link.split("\\/");
if (mention_list == null || mention_list.length != 2) {
if (link == null) break;
final String[] mentionList = link.split("/");
if (mentionList.length != 2) {
break;
}
break;

View File

@ -19,9 +19,6 @@
package org.mariotaku.twidere.loader.support;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
import static org.mariotaku.twidere.util.Utils.truncateStatuses;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
@ -33,11 +30,6 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.task.CacheUsersStatusesTask;
import org.mariotaku.twidere.util.TwitterWrapper.StatusListResponse;
import twitter4j.Paging;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@ -45,120 +37,128 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import twitter4j.Paging;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
import static org.mariotaku.twidere.util.Utils.truncateStatuses;
public abstract class Twitter4JStatusesLoader extends ParcelableStatusesLoader {
private final Context mContext;
private final long mAccountId;
private final long mMaxId, mSinceId;
private final SQLiteDatabase mDatabase;
private final Handler mHandler;
private final Object[] mSavedStatusesFileArgs;
private final Context mContext;
private final long mAccountId;
private final long mMaxId, mSinceId;
private final SQLiteDatabase mDatabase;
private final Handler mHandler;
private final Object[] mSavedStatusesFileArgs;
public Twitter4JStatusesLoader(final Context context, final long account_id, final long max_id,
final long since_id, final List<ParcelableStatus> data, final String[] saved_statuses_args,
final int tab_position) {
super(context, data, tab_position);
mContext = context;
mAccountId = account_id;
mMaxId = max_id;
mSinceId = since_id;
mDatabase = TwidereApplication.getInstance(context).getSQLiteDatabase();
mHandler = new Handler();
mSavedStatusesFileArgs = saved_statuses_args;
}
public Twitter4JStatusesLoader(final Context context, final long account_id, final long max_id,
final long since_id, final List<ParcelableStatus> data, final String[] saved_statuses_args,
final int tab_position) {
super(context, data, tab_position);
mContext = context;
mAccountId = account_id;
mMaxId = max_id;
mSinceId = since_id;
mDatabase = TwidereApplication.getInstance(context).getSQLiteDatabase();
mHandler = new Handler();
mSavedStatusesFileArgs = saved_statuses_args;
}
@SuppressWarnings("unchecked")
@Override
public final List<ParcelableStatus> loadInBackground() {
final File serializationFile = getSerializationFile();
final List<ParcelableStatus> data = getData();
if (isFirstLoad() && getTabPosition() >= 0 && serializationFile != null) {
final List<ParcelableStatus> cached = getCachedData(serializationFile);
if (cached != null) {
data.addAll(cached);
Collections.sort(data);
return new CopyOnWriteArrayList<ParcelableStatus>(data);
}
}
final List<Status> statuses;
final boolean truncated;
final Context context = getContext();
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int loadItemLimit = prefs.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
try {
final Paging paging = new Paging();
paging.setCount(loadItemLimit);
if (mMaxId > 0) {
paging.setMaxId(mMaxId);
}
if (mSinceId > 0) {
paging.setSinceId(mSinceId - 1);
}
statuses = new ArrayList<Status>();
truncated = truncateStatuses(getStatuses(getTwitter(), paging), statuses, mSinceId);
} catch (final TwitterException e) {
// mHandler.post(new ShowErrorRunnable(e));
e.printStackTrace();
return new CopyOnWriteArrayList<ParcelableStatus>(data);
}
final long minStatusId = statuses.isEmpty() ? -1 : Collections.min(statuses).getId();
final boolean insertGap = minStatusId > 0 && statuses.size() > 1 && !data.isEmpty() && !truncated;
mHandler.post(CacheUsersStatusesTask.getRunnable(context, new StatusListResponse(mAccountId, statuses)));
for (final Status status : statuses) {
final long id = status.getId();
final boolean deleted = deleteStatus(data, id);
data.add(new ParcelableStatus(status, mAccountId, minStatusId == id && insertGap && !deleted));
}
Collections.sort(data);
final ParcelableStatus[] array = data.toArray(new ParcelableStatus[data.size()]);
for (int i = 0, size = array.length; i < size; i++) {
final ParcelableStatus status = array[i];
if (shouldFilterStatus(mDatabase, status) && !status.is_gap && i != size - 1) {
deleteStatus(data, status.id);
}
}
saveCachedData(serializationFile, data);
return new CopyOnWriteArrayList<ParcelableStatus>(data);
}
@SuppressWarnings("unchecked")
@Override
public final List<ParcelableStatus> loadInBackground() {
final File serializationFile = getSerializationFile();
final List<ParcelableStatus> data = getData();
if (isFirstLoad() && getTabPosition() >= 0 && serializationFile != null) {
final List<ParcelableStatus> cached = getCachedData(serializationFile);
if (cached != null) {
data.addAll(cached);
Collections.sort(data);
return new CopyOnWriteArrayList<>(data);
}
}
final List<Status> statuses;
final boolean truncated;
final Context context = getContext();
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int loadItemLimit = prefs.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
try {
final Paging paging = new Paging();
paging.setCount(loadItemLimit);
if (mMaxId > 0) {
paging.setMaxId(mMaxId);
}
if (mSinceId > 0) {
paging.setSinceId(mSinceId - 1);
}
statuses = new ArrayList<>();
truncated = truncateStatuses(getStatuses(getTwitter(), paging), statuses, mSinceId);
} catch (final TwitterException e) {
// mHandler.post(new ShowErrorRunnable(e));
e.printStackTrace();
return new CopyOnWriteArrayList<>(data);
}
final long minStatusId = statuses.isEmpty() ? -1 : Collections.min(statuses).getId();
final boolean insertGap = minStatusId > 0 && statuses.size() > 1 && !data.isEmpty() && !truncated;
mHandler.post(CacheUsersStatusesTask.getRunnable(context, new StatusListResponse(mAccountId, statuses)));
for (final Status status : statuses) {
final long id = status.getId();
final boolean deleted = deleteStatus(data, id);
data.add(new ParcelableStatus(status, mAccountId, minStatusId == id && insertGap && !deleted));
}
Collections.sort(data);
final ParcelableStatus[] array = data.toArray(new ParcelableStatus[data.size()]);
for (int i = 0, size = array.length; i < size; i++) {
final ParcelableStatus status = array[i];
if (shouldFilterStatus(mDatabase, status) && !status.is_gap && i != size - 1) {
deleteStatus(data, status.id);
}
}
saveCachedData(serializationFile, data);
return new CopyOnWriteArrayList<ParcelableStatus>(data);
}
protected abstract List<Status> getStatuses(Twitter twitter, Paging paging) throws TwitterException;
protected abstract List<Status> getStatuses(Twitter twitter, Paging paging) throws TwitterException;
protected final Twitter getTwitter() {
return getTwitterInstance(mContext, mAccountId, true, true);
}
protected final Twitter getTwitter() {
return getTwitterInstance(mContext, mAccountId, true, true);
}
protected abstract boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status);
protected abstract boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status);
private List<ParcelableStatus> getCachedData(final File file) {
if (file == null) return null;
try {
return JSONFileIO.readArrayList(file);
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private List<ParcelableStatus> getCachedData(final File file) {
if (file == null) return null;
try {
return JSONFileIO.readArrayList(file);
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private File getSerializationFile() {
if (mSavedStatusesFileArgs == null) return null;
try {
return JSONFileIO.getSerializationFile(mContext, mSavedStatusesFileArgs);
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private File getSerializationFile() {
if (mSavedStatusesFileArgs == null) return null;
try {
return JSONFileIO.getSerializationFile(mContext, mSavedStatusesFileArgs);
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
private void saveCachedData(final File file, final List<ParcelableStatus> data) {
if (file == null || data == null) return;
final SharedPreferences prefs = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int databaseItemLimit = prefs.getInt(KEY_DATABASE_ITEM_LIMIT, DEFAULT_DATABASE_ITEM_LIMIT);
try {
final List<ParcelableStatus> activities = data.subList(0, Math.min(databaseItemLimit, data.size()));
JSONFileIO.writeArray(file, activities.toArray(new ParcelableStatus[activities.size()]));
} catch (final IOException e) {
e.printStackTrace();
}
}
private void saveCachedData(final File file, final List<ParcelableStatus> data) {
if (file == null || data == null) return;
final SharedPreferences prefs = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int databaseItemLimit = prefs.getInt(KEY_DATABASE_ITEM_LIMIT, DEFAULT_DATABASE_ITEM_LIMIT);
try {
final List<ParcelableStatus> activities = data.subList(0, Math.min(databaseItemLimit, data.size()));
JSONFileIO.writeArray(file, activities.toArray(new ParcelableStatus[activities.size()]));
} catch (final IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,554 +0,0 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mariotaku.twidere.menu;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import android.view.ActionProvider;
import android.view.InflateException;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import org.mariotaku.twidere.util.ThemeUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* This class is used to instantiate menu XML files into Menu objects.
* <p/>
* For performance reasons, menu inflation relies heavily on pre-processing of
* XML files that is done at build time. Therefore, it is not currently possible
* to use MenuInflater with an XmlPullParser over a plain XML file at runtime;
* it only works with an XmlPullParser returned from a compiled resource (R.
* <em>something</em> file.)
*/
public class TwidereMenuInflater extends MenuInflater {
private static final String LOG_TAG = "MenuInflater";
/**
* Menu tag name in XML.
*/
private static final String XML_MENU = "menu";
/**
* Group tag name in XML.
*/
private static final String XML_GROUP = "group";
/**
* Item tag name in XML.
*/
private static final String XML_ITEM = "item";
private static final int NO_ID = 0;
private static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[]{Context.class};
private static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE;
private final Object[] mActionViewConstructorArguments;
private final Object[] mActionProviderConstructorArguments;
private final Context mContext;
private final Resources mResources;
private final Object mRealOwner;
/**
* Constructs a menu inflater.
*
* @see Activity#getMenuInflater()
*/
public TwidereMenuInflater(Context context) {
this(context, context);
}
/**
* Constructs a menu inflater.
*
* @hide
* @see Activity#getMenuInflater()
*/
public TwidereMenuInflater(Context context, Object realOwner) {
super(context);
mContext = context;
mResources = context.getResources();
mRealOwner = realOwner;
mActionViewConstructorArguments = new Object[]{context};
mActionProviderConstructorArguments = mActionViewConstructorArguments;
}
/**
* Inflate a menu hierarchy from the specified XML resource. Throws
* {@link InflateException} if there is an error.
*
* @param menuRes Resource ID for an XML layout resource to load (e.g.,
* <code>R.menu.main_activity</code>)
* @param menu The Menu to inflate into. The items and submenus will be
* added to this Menu.
*/
@Override
public void inflate(int menuRes, Menu menu) {
XmlResourceParser parser = null;
try {
parser = mContext.getResources().getLayout(menuRes);
AttributeSet attrs = Xml.asAttributeSet(parser);
parseMenu(parser, attrs, menu);
} catch (XmlPullParserException e) {
throw new InflateException("Error inflating menu XML", e);
} catch (IOException e) {
throw new InflateException("Error inflating menu XML", e);
} finally {
if (parser != null) parser.close();
}
}
/**
* Called internally to fill the given menu. If a sub menu is seen, it will
* call this recursively.
*/
private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu)
throws XmlPullParserException, IOException {
MenuState menuState = new MenuState(menu);
int eventType = parser.getEventType();
String tagName;
boolean lookingForEndOfUnknownTag = false;
String unknownTagName = null;
// This loop will skip to the menu start tag
do {
if (eventType == XmlPullParser.START_TAG) {
tagName = parser.getName();
if (tagName.equals(XML_MENU)) {
// Go to next tag
eventType = parser.next();
break;
}
throw new RuntimeException("Expecting menu, got " + tagName);
}
eventType = parser.next();
} while (eventType != XmlPullParser.END_DOCUMENT);
boolean reachedEndOfMenu = false;
while (!reachedEndOfMenu) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (lookingForEndOfUnknownTag) {
break;
}
tagName = parser.getName();
if (tagName.equals(XML_GROUP)) {
menuState.readGroup(attrs);
} else if (tagName.equals(XML_ITEM)) {
menuState.readItem(attrs);
} else if (tagName.equals(XML_MENU)) {
// A menu start tag denotes a submenu for an item
SubMenu subMenu = menuState.addSubMenuItem();
// Parse the submenu into returned SubMenu
parseMenu(parser, attrs, subMenu);
} else {
lookingForEndOfUnknownTag = true;
unknownTagName = tagName;
}
break;
case XmlPullParser.END_TAG:
tagName = parser.getName();
if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) {
lookingForEndOfUnknownTag = false;
unknownTagName = null;
} else if (tagName.equals(XML_GROUP)) {
menuState.resetGroup();
} else if (tagName.equals(XML_ITEM)) {
// Add the item if it hasn't been added (if the item was
// a submenu, it would have been added already)
if (!menuState.hasAddedItem()) {
if (menuState.itemActionProvider != null &&
menuState.itemActionProvider.hasSubMenu()) {
menuState.addSubMenuItem();
} else {
menuState.addItem();
}
}
} else if (tagName.equals(XML_MENU)) {
reachedEndOfMenu = true;
}
break;
case XmlPullParser.END_DOCUMENT:
throw new RuntimeException("Unexpected end of document");
}
eventType = parser.next();
}
}
private static class InflatedOnMenuItemClickListener
implements MenuItem.OnMenuItemClickListener {
private static final Class<?>[] PARAM_TYPES = new Class[]{MenuItem.class};
private Object mRealOwner;
private Method mMethod;
public InflatedOnMenuItemClickListener(Object realOwner, String methodName) {
mRealOwner = realOwner;
Class<?> c = realOwner.getClass();
try {
mMethod = c.getMethod(methodName, PARAM_TYPES);
} catch (Exception e) {
InflateException ex = new InflateException(
"Couldn't resolve menu item onClick handler " + methodName +
" in class " + c.getName()
);
ex.initCause(e);
throw ex;
}
}
public boolean onMenuItemClick(MenuItem item) {
try {
if (mMethod.getReturnType() == Boolean.TYPE) {
return (Boolean) mMethod.invoke(mRealOwner, item);
} else {
mMethod.invoke(mRealOwner, item);
return true;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static class Styleable {
public static final int[] MenuGroup = {android.R.attr.id, android.R.attr.menuCategory,
android.R.attr.orderInCategory, android.R.attr.checkableBehavior,
android.R.attr.visible, android.R.attr.enabled};
public static final int MenuGroup_id = 0;
public static final int MenuGroup_menuCategory = 1;
public static final int MenuGroup_orderInCategory = 2;
public static final int MenuGroup_checkableBehavior = 3;
public static final int MenuGroup_visible = 4;
public static final int MenuGroup_enabled = 5;
public static final int[] MenuItem = {android.R.attr.id, android.R.attr.menuCategory,
android.R.attr.orderInCategory, android.R.attr.title, android.R.attr.titleCondensed,
android.R.attr.icon, android.R.attr.alphabeticShortcut, android.R.attr.numericShortcut,
android.R.attr.checkable, android.R.attr.checked, android.R.attr.visible,
android.R.attr.enabled, android.R.attr.showAsAction, android.R.attr.onClick,
android.R.attr.actionLayout, android.R.attr.actionViewClass,
android.R.attr.actionProviderClass};
public static final int MenuItem_id = 0;
public static final int MenuItem_menuCategory = 1;
public static final int MenuItem_orderInCategory = 2;
public static final int MenuItem_title = 3;
public static final int MenuItem_titleCondensed = 4;
public static final int MenuItem_icon = 5;
public static final int MenuItem_alphabeticShortcut = 6;
public static final int MenuItem_numericShortcut = 7;
public static final int MenuItem_checkable = 8;
public static final int MenuItem_checked = 9;
public static final int MenuItem_visible = 10;
public static final int MenuItem_enabled = 11;
public static final int MenuItem_showAsAction = 12;
public static final int MenuItem_onClick = 13;
public static final int MenuItem_actionLayout = 14;
public static final int MenuItem_actionViewClass = 15;
public static final int MenuItem_actionProviderClass = 16;
}
/**
* State for the current menu.
* <p/>
* Groups can not be nested unless there is another menu (which will have
* its state class).
*/
private class MenuState {
/**
* This is the part of an order integer that the user can provide.
*
* @hide
*/
static final int USER_MASK = 0x0000ffff;
/**
* Bit shift of the user portion of the order integer.
*
* @hide
*/
static final int USER_SHIFT = 0;
/**
* This is the part of an order integer that supplies the category of the
* item.
*
* @hide
*/
static final int CATEGORY_MASK = 0xffff0000;
private Menu menu;
/*
* Group state is set on items as they are added, allowing an item to
* override its group state. (As opposed to set on items at the group end tag.)
*/
private int groupId;
private int groupCategory;
private int groupOrder;
private int groupCheckable;
private boolean groupVisible;
private boolean groupEnabled;
private boolean itemAdded;
private int itemId;
private int itemCategoryOrder;
private CharSequence itemTitle;
private CharSequence itemTitleCondensed;
private int itemIconResId;
private char itemAlphabeticShortcut;
private char itemNumericShortcut;
/**
* Sync to attrs.xml enum:
* - 0: none
* - 1: all
* - 2: exclusive
*/
private int itemCheckable;
private boolean itemChecked;
private boolean itemVisible;
private boolean itemEnabled;
/**
* Sync to attrs.xml enum, values in MenuItem:
* - 0: never
* - 1: ifRoom
* - 2: always
* - -1: Safe sentinel for "no value".
*/
private int itemShowAsAction;
private int itemActionViewLayout;
private String itemActionViewClassName;
private String itemActionProviderClassName;
private String itemListenerMethodName;
private ActionProvider itemActionProvider;
private static final int defaultGroupId = NO_ID;
private static final int defaultItemId = NO_ID;
private static final int defaultItemCategory = 0;
private static final int defaultItemOrder = 0;
private static final int defaultItemCheckable = 0;
private static final boolean defaultItemChecked = false;
private static final boolean defaultItemVisible = true;
private static final boolean defaultItemEnabled = true;
public MenuState(final Menu menu) {
this.menu = menu;
resetGroup();
}
public void resetGroup() {
groupId = defaultGroupId;
groupCategory = defaultItemCategory;
groupOrder = defaultItemOrder;
groupCheckable = defaultItemCheckable;
groupVisible = defaultItemVisible;
groupEnabled = defaultItemEnabled;
}
/**
* Called when the parser is pointing to a group tag.
*/
public void readGroup(AttributeSet attrs) {
TypedArray a = mContext.obtainStyledAttributes(attrs,
Styleable.MenuGroup);
groupId = a.getResourceId(Styleable.MenuGroup_id, defaultGroupId);
groupCategory = a.getInt(Styleable.MenuGroup_menuCategory, defaultItemCategory);
groupOrder = a.getInt(Styleable.MenuGroup_orderInCategory, defaultItemOrder);
groupCheckable = a.getInt(Styleable.MenuGroup_checkableBehavior, defaultItemCheckable);
groupVisible = a.getBoolean(Styleable.MenuGroup_visible, defaultItemVisible);
groupEnabled = a.getBoolean(Styleable.MenuGroup_enabled, defaultItemEnabled);
a.recycle();
}
/**
* Called when the parser is pointing to an item tag.
*/
public void readItem(AttributeSet attrs) {
TypedArray a = mContext.obtainStyledAttributes(attrs,
Styleable.MenuItem);
// Inherit attributes from the group as default value
itemId = a.getResourceId(Styleable.MenuItem_id, defaultItemId);
final int category = a.getInt(Styleable.MenuItem_menuCategory, groupCategory);
final int order = a.getInt(Styleable.MenuItem_orderInCategory, groupOrder);
itemCategoryOrder = (category & CATEGORY_MASK) | (order & USER_MASK);
itemTitle = a.getText(Styleable.MenuItem_title);
itemTitleCondensed = a.getText(Styleable.MenuItem_titleCondensed);
itemIconResId = ThemeUtils.findAttributeResourceValue(attrs, "icon", 0);
itemAlphabeticShortcut =
getShortcut(a.getString(Styleable.MenuItem_alphabeticShortcut));
itemNumericShortcut =
getShortcut(a.getString(Styleable.MenuItem_numericShortcut));
if (a.hasValue(Styleable.MenuItem_checkable)) {
// Item has attribute checkable, use it
itemCheckable = a.getBoolean(Styleable.MenuItem_checkable, false) ? 1 : 0;
} else {
// Item does not have attribute, use the group's (group can have one more state
// for checkable that represents the exclusive checkable)
itemCheckable = groupCheckable;
}
itemChecked = a.getBoolean(Styleable.MenuItem_checked, defaultItemChecked);
itemVisible = a.getBoolean(Styleable.MenuItem_visible, groupVisible);
itemEnabled = a.getBoolean(Styleable.MenuItem_enabled, groupEnabled);
itemShowAsAction = a.getInt(Styleable.MenuItem_showAsAction, -1);
itemListenerMethodName = a.getString(Styleable.MenuItem_onClick);
itemActionViewLayout = a.getResourceId(Styleable.MenuItem_actionLayout, 0);
itemActionViewClassName = a.getString(Styleable.MenuItem_actionViewClass);
itemActionProviderClassName = a.getString(Styleable.MenuItem_actionProviderClass);
final boolean hasActionProvider = itemActionProviderClassName != null;
if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) {
itemActionProvider = newInstance(itemActionProviderClassName,
ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE,
mActionProviderConstructorArguments);
} else {
if (hasActionProvider) {
Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'."
+ " Action view already specified.");
}
itemActionProvider = null;
}
a.recycle();
itemAdded = false;
}
private char getShortcut(String shortcutString) {
if (shortcutString == null) {
return 0;
} else {
return shortcutString.charAt(0);
}
}
private void setItem(MenuItem item) {
item.setChecked(itemChecked)
.setVisible(itemVisible)
.setEnabled(itemEnabled)
.setCheckable(itemCheckable >= 1)
.setTitleCondensed(itemTitleCondensed)
.setIcon(itemIconResId > 0 ? mResources.getDrawable(itemIconResId) : null)
.setAlphabeticShortcut(itemAlphabeticShortcut)
.setNumericShortcut(itemNumericShortcut);
if (itemShowAsAction >= 0) {
item.setShowAsAction(itemShowAsAction);
}
if (itemListenerMethodName != null) {
if (mContext.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
item.setOnMenuItemClickListener(
new InflatedOnMenuItemClickListener(mRealOwner, itemListenerMethodName));
}
// if (item instanceof MenuItemImpl) {
// MenuItemImpl impl = (MenuItemImpl) item;
// if (itemCheckable >= 2) {
// impl.setExclusiveCheckable(true);
// }
// }
boolean actionViewSpecified = false;
if (itemActionViewClassName != null) {
View actionView = (View) newInstance(itemActionViewClassName,
ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments);
item.setActionView(actionView);
actionViewSpecified = true;
}
if (itemActionViewLayout > 0) {
if (!actionViewSpecified) {
item.setActionView(itemActionViewLayout);
actionViewSpecified = true;
} else {
Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'."
+ " Action view already specified.");
}
}
if (itemActionProvider != null) {
item.setActionProvider(itemActionProvider);
}
}
public void addItem() {
itemAdded = true;
setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle));
}
public SubMenu addSubMenuItem() {
itemAdded = true;
SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle);
setItem(subMenu.getItem());
return subMenu;
}
public boolean hasAddedItem() {
return itemAdded;
}
@SuppressWarnings("unchecked")
private <T> T newInstance(String className, Class<?>[] constructorSignature,
Object[] arguments) {
try {
Class<?> clazz = mContext.getClassLoader().loadClass(className);
Constructor<?> constructor = clazz.getConstructor(constructorSignature);
return (T) constructor.newInstance(arguments);
} catch (Exception e) {
Log.w(LOG_TAG, "Cannot instantiate class: " + className, e);
}
return null;
}
}
}

View File

@ -42,7 +42,7 @@ public enum CustomTabConfiguration2 implements Constants {
HOME_TIMELINE(HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false),
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_mention,
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false),
DIRECT_MESSAGES(DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,

View File

@ -12,136 +12,144 @@ import org.mariotaku.jsonserializer.JSONSerializer;
import org.mariotaku.twidere.util.MediaPreviewUtils;
import org.mariotaku.twidere.util.ParseUtils;
import twitter4j.EntitySupport;
import twitter4j.MediaEntity;
import twitter4j.URLEntity;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import twitter4j.EntitySupport;
import twitter4j.ExtendedEntitySupport;
import twitter4j.MediaEntity;
import twitter4j.URLEntity;
public class ParcelableMedia implements Parcelable, JSONParcelable {
public static final int TYPE_IMAGE = 1;
public static final int TYPE_IMAGE = 1;
public static final Parcelable.Creator<ParcelableMedia> CREATOR = new Parcelable.Creator<ParcelableMedia>() {
@Override
public ParcelableMedia createFromParcel(final Parcel in) {
return new ParcelableMedia(in);
}
public static final Parcelable.Creator<ParcelableMedia> CREATOR = new Parcelable.Creator<ParcelableMedia>() {
@Override
public ParcelableMedia createFromParcel(final Parcel in) {
return new ParcelableMedia(in);
}
@Override
public ParcelableMedia[] newArray(final int size) {
return new ParcelableMedia[size];
}
};
@Override
public ParcelableMedia[] newArray(final int size) {
return new ParcelableMedia[size];
}
};
public static final JSONParcelable.Creator<ParcelableMedia> JSON_CREATOR = new JSONParcelable.Creator<ParcelableMedia>() {
@Override
public ParcelableMedia createFromParcel(final JSONParcel in) {
return new ParcelableMedia(in);
}
public static final JSONParcelable.Creator<ParcelableMedia> JSON_CREATOR = new JSONParcelable.Creator<ParcelableMedia>() {
@Override
public ParcelableMedia createFromParcel(final JSONParcel in) {
return new ParcelableMedia(in);
}
@Override
public ParcelableMedia[] newArray(final int size) {
return new ParcelableMedia[size];
}
};
@Override
public ParcelableMedia[] newArray(final int size) {
return new ParcelableMedia[size];
}
};
public final String url, media_url;
public final int start, end, type;
public final String url, media_url;
public final int start, end, type;
public ParcelableMedia(final JSONParcel in) {
url = in.readString("url");
media_url = in.readString("media_url");
start = in.readInt("start");
end = in.readInt("end");
type = in.readInt("type");
}
public ParcelableMedia(final JSONParcel in) {
url = in.readString("url");
media_url = in.readString("media_url");
start = in.readInt("start");
end = in.readInt("end");
type = in.readInt("type");
}
public ParcelableMedia(final MediaEntity entity) {
url = ParseUtils.parseString(entity.getMediaURL());
media_url = ParseUtils.parseString(entity.getMediaURL());
start = entity.getStart();
end = entity.getEnd();
type = TYPE_IMAGE;
}
public ParcelableMedia(final MediaEntity entity) {
url = ParseUtils.parseString(entity.getMediaURL());
media_url = ParseUtils.parseString(entity.getMediaURL());
start = entity.getStart();
end = entity.getEnd();
type = TYPE_IMAGE;
}
public ParcelableMedia(final Parcel in) {
url = in.readString();
media_url = in.readString();
start = in.readInt();
end = in.readInt();
type = in.readInt();
}
public ParcelableMedia(final Parcel in) {
url = in.readString();
media_url = in.readString();
start = in.readInt();
end = in.readInt();
type = in.readInt();
}
private ParcelableMedia(final String url, final String media_url, final int start, final int end, final int type) {
this.url = url;
this.media_url = media_url;
this.start = start;
this.end = end;
this.type = type;
}
private ParcelableMedia(final String url, final String media_url, final int start, final int end, final int type) {
this.url = url;
this.media_url = media_url;
this.start = start;
this.end = end;
this.type = type;
}
@Override
public int describeContents() {
return 0;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final JSONParcel out) {
out.writeString("url", url);
out.writeString("media_url", media_url);
out.writeInt("start", start);
out.writeInt("end", end);
out.writeInt("type", type);
}
@Override
public void writeToParcel(final JSONParcel out) {
out.writeString("url", url);
out.writeString("media_url", media_url);
out.writeInt("start", start);
out.writeInt("end", end);
out.writeInt("type", type);
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(url);
dest.writeString(media_url);
dest.writeInt(start);
dest.writeInt(end);
dest.writeInt(type);
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(url);
dest.writeString(media_url);
dest.writeInt(start);
dest.writeInt(end);
dest.writeInt(type);
}
public static ParcelableMedia[] fromEntities(final EntitySupport entities) {
final List<ParcelableMedia> list = new ArrayList<ParcelableMedia>();
final MediaEntity[] medias = entities.getMediaEntities();
if (medias != null) {
for (final MediaEntity media : medias) {
final URL media_url = media.getMediaURL();
if (media_url != null) {
list.add(new ParcelableMedia(media));
}
}
}
final URLEntity[] urls = entities.getURLEntities();
if (urls != null) {
for (final URLEntity url : urls) {
final String expanded = ParseUtils.parseString(url.getExpandedURL());
final String media_url = MediaPreviewUtils.getSupportedLink(expanded);
if (expanded != null && media_url != null) {
list.add(new ParcelableMedia(expanded, media_url, url.getStart(), url.getEnd(), TYPE_IMAGE));
}
}
}
if (list.isEmpty()) return null;
return list.toArray(new ParcelableMedia[list.size()]);
}
public static ParcelableMedia[] fromEntities(final EntitySupport entities) {
final List<ParcelableMedia> list = new ArrayList<>();
final MediaEntity[] medias;
if (entities instanceof ExtendedEntitySupport) {
final ExtendedEntitySupport extendedEntities = (ExtendedEntitySupport) entities;
final MediaEntity[] extendedMedias = extendedEntities.getExtendedMediaEntities();
medias = extendedMedias != null ? extendedMedias : entities.getMediaEntities();
} else {
medias = entities.getMediaEntities();
}
if (medias != null) {
for (final MediaEntity media : medias) {
final URL media_url = media.getMediaURL();
if (media_url != null) {
list.add(new ParcelableMedia(media));
}
}
}
final URLEntity[] urls = entities.getURLEntities();
if (urls != null) {
for (final URLEntity url : urls) {
final String expanded = ParseUtils.parseString(url.getExpandedURL());
final String media_url = MediaPreviewUtils.getSupportedLink(expanded);
if (expanded != null && media_url != null) {
list.add(new ParcelableMedia(expanded, media_url, url.getStart(), url.getEnd(), TYPE_IMAGE));
}
}
}
if (list.isEmpty()) return null;
return list.toArray(new ParcelableMedia[list.size()]);
}
public static ParcelableMedia[] fromJSONString(final String json) {
if (TextUtils.isEmpty(json)) return null;
try {
return JSONSerializer.createArray(JSON_CREATOR, new JSONArray(json));
} catch (final JSONException e) {
return null;
}
}
public static ParcelableMedia[] fromJSONString(final String json) {
if (TextUtils.isEmpty(json)) return null;
try {
return JSONSerializer.createArray(JSON_CREATOR, new JSONArray(json));
} catch (final JSONException e) {
return null;
}
}
public static ParcelableMedia newImage(final String media_url, final String url) {
return new ParcelableMedia(url, media_url, 0, 0, TYPE_IMAGE);
}
public static ParcelableMedia newImage(final String media_url, final String url) {
return new ParcelableMedia(url, media_url, 0, 0, TYPE_IMAGE);
}
}

View File

@ -19,6 +19,24 @@
package org.mariotaku.twidere.model;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import org.mariotaku.jsonserializer.JSONParcel;
import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.twidere.provider.TweetStore.Statuses;
import org.mariotaku.twidere.util.ParseUtils;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import twitter4j.Status;
import twitter4j.User;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.Utils.formatStatusText;
import static org.mariotaku.twidere.util.Utils.getInReplyToName;
@ -26,473 +44,453 @@ import static org.mariotaku.twidere.util.content.ContentValuesUtils.getAsBoolean
import static org.mariotaku.twidere.util.content.ContentValuesUtils.getAsInteger;
import static org.mariotaku.twidere.util.content.ContentValuesUtils.getAsLong;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import org.mariotaku.jsonserializer.JSONParcel;
import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.twidere.provider.TweetStore.Statuses;
import org.mariotaku.twidere.util.ParseUtils;
import twitter4j.Status;
import twitter4j.User;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
public class ParcelableStatus implements TwidereParcelable, Comparable<ParcelableStatus> {
public static final Parcelable.Creator<ParcelableStatus> CREATOR = new Parcelable.Creator<ParcelableStatus>() {
@Override
public ParcelableStatus createFromParcel(final Parcel in) {
return new ParcelableStatus(in);
}
public static final Parcelable.Creator<ParcelableStatus> CREATOR = new Parcelable.Creator<ParcelableStatus>() {
@Override
public ParcelableStatus createFromParcel(final Parcel in) {
return new ParcelableStatus(in);
}
@Override
public ParcelableStatus[] newArray(final int size) {
return new ParcelableStatus[size];
}
};
@Override
public ParcelableStatus[] newArray(final int size) {
return new ParcelableStatus[size];
}
};
public static final JSONParcelable.Creator<ParcelableStatus> JSON_CREATOR = new JSONParcelable.Creator<ParcelableStatus>() {
@Override
public ParcelableStatus createFromParcel(final JSONParcel in) {
return new ParcelableStatus(in);
}
public static final JSONParcelable.Creator<ParcelableStatus> JSON_CREATOR = new JSONParcelable.Creator<ParcelableStatus>() {
@Override
public ParcelableStatus createFromParcel(final JSONParcel in) {
return new ParcelableStatus(in);
}
@Override
public ParcelableStatus[] newArray(final int size) {
return new ParcelableStatus[size];
}
};
@Override
public ParcelableStatus[] newArray(final int size) {
return new ParcelableStatus[size];
}
};
public static final Comparator<ParcelableStatus> TIMESTAMP_COMPARATOR = new Comparator<ParcelableStatus>() {
public static final Comparator<ParcelableStatus> TIMESTAMP_COMPARATOR = new Comparator<ParcelableStatus>() {
@Override
public int compare(final ParcelableStatus object1, final ParcelableStatus object2) {
final long diff = object2.timestamp - object1.timestamp;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
};
@Override
public int compare(final ParcelableStatus object1, final ParcelableStatus object2) {
final long diff = object2.timestamp - object1.timestamp;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
};
public static final Comparator<ParcelableStatus> REVERSE_ID_COMPARATOR = new Comparator<ParcelableStatus>() {
public static final Comparator<ParcelableStatus> REVERSE_ID_COMPARATOR = new Comparator<ParcelableStatus>() {
@Override
public int compare(final ParcelableStatus object1, final ParcelableStatus object2) {
final long diff = object1.id - object2.id;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
};
@Override
public int compare(final ParcelableStatus object1, final ParcelableStatus object2) {
final long diff = object1.id - object2.id;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
};
public final long id, account_id, timestamp, user_id, retweet_id, retweeted_by_id, retweet_timestamp,
retweet_count, favorite_count, in_reply_to_status_id, in_reply_to_user_id, my_retweet_id;
public final long id, account_id, timestamp, user_id, retweet_id, retweeted_by_id, retweet_timestamp,
retweet_count, favorite_count, in_reply_to_status_id, in_reply_to_user_id, my_retweet_id;
public final boolean is_gap, is_retweet, is_favorite, is_possibly_sensitive, user_is_following, user_is_protected,
user_is_verified;
public final boolean is_gap, is_retweet, is_favorite, is_possibly_sensitive, user_is_following, user_is_protected,
user_is_verified;
public final String retweeted_by_name, retweeted_by_screen_name, text_html, text_plain, user_name,
user_screen_name, in_reply_to_name, in_reply_to_screen_name, source, user_profile_image_url,
text_unescaped, first_media;
public final String retweeted_by_name, retweeted_by_screen_name, text_html, text_plain, user_name,
user_screen_name, in_reply_to_name, in_reply_to_screen_name, source, user_profile_image_url,
text_unescaped, first_media;
public final ParcelableLocation location;
public final ParcelableLocation location;
public final ParcelableUserMention[] mentions;
public final ParcelableUserMention[] mentions;
public final ParcelableMedia[] medias;
public final ParcelableMedia[] medias;
public ParcelableStatus(final ContentValues values) {
id = getAsLong(values, Statuses.STATUS_ID, -1);
account_id = getAsLong(values, Statuses.ACCOUNT_ID, -1);
timestamp = getAsLong(values, Statuses.STATUS_TIMESTAMP, -1);
user_id = getAsLong(values, Statuses.USER_ID, -1);
retweet_id = getAsLong(values, Statuses.RETWEET_ID, -1);
retweet_timestamp = getAsLong(values, Statuses.RETWEET_TIMESTAMP, -1);
retweeted_by_id = getAsLong(values, Statuses.RETWEETED_BY_USER_ID, -1);
user_name = values.getAsString(Statuses.USER_NAME);
user_screen_name = values.getAsString(Statuses.USER_SCREEN_NAME);
text_html = values.getAsString(Statuses.TEXT_HTML);
text_plain = values.getAsString(Statuses.TEXT_PLAIN);
user_profile_image_url = values.getAsString(Statuses.USER_PROFILE_IMAGE_URL);
is_favorite = getAsBoolean(values, Statuses.IS_FAVORITE, false);
is_retweet = getAsBoolean(values, Statuses.IS_RETWEET, false);
is_gap = getAsBoolean(values, Statuses.IS_GAP, false);
location = ParcelableLocation.fromString(values.getAsString(Statuses.LOCATION));
user_is_protected = getAsBoolean(values, Statuses.IS_PROTECTED, false);
user_is_verified = getAsBoolean(values, Statuses.IS_VERIFIED, false);
in_reply_to_status_id = getAsLong(values, Statuses.IN_REPLY_TO_STATUS_ID, -1);
in_reply_to_user_id = getAsLong(values, Statuses.IN_REPLY_TO_USER_ID, -1);
in_reply_to_name = values.getAsString(Statuses.IN_REPLY_TO_USER_NAME);
in_reply_to_screen_name = values.getAsString(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
my_retweet_id = getAsLong(values, Statuses.MY_RETWEET_ID, -1);
retweeted_by_name = values.getAsString(Statuses.RETWEETED_BY_USER_NAME);
retweeted_by_screen_name = values.getAsString(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
source = values.getAsString(Statuses.SOURCE);
retweet_count = getAsInteger(values, Statuses.RETWEET_COUNT, 0);
favorite_count = getAsInteger(values, Statuses.FAVORITE_COUNT, 0);
text_unescaped = values.getAsString(Statuses.TEXT_UNESCAPED);
medias = ParcelableMedia.fromJSONString(values.getAsString(Statuses.MEDIAS));
is_possibly_sensitive = getAsBoolean(values, Statuses.IS_POSSIBLY_SENSITIVE, false);
user_is_following = getAsBoolean(values, Statuses.IS_FOLLOWING, false);
mentions = ParcelableUserMention.fromJSONString(values.getAsString(Statuses.MENTIONS));
first_media = values.getAsString(Statuses.FIRST_MEDIA);
}
public ParcelableStatus(final ContentValues values) {
id = getAsLong(values, Statuses.STATUS_ID, -1);
account_id = getAsLong(values, Statuses.ACCOUNT_ID, -1);
timestamp = getAsLong(values, Statuses.STATUS_TIMESTAMP, -1);
user_id = getAsLong(values, Statuses.USER_ID, -1);
retweet_id = getAsLong(values, Statuses.RETWEET_ID, -1);
retweet_timestamp = getAsLong(values, Statuses.RETWEET_TIMESTAMP, -1);
retweeted_by_id = getAsLong(values, Statuses.RETWEETED_BY_USER_ID, -1);
user_name = values.getAsString(Statuses.USER_NAME);
user_screen_name = values.getAsString(Statuses.USER_SCREEN_NAME);
text_html = values.getAsString(Statuses.TEXT_HTML);
text_plain = values.getAsString(Statuses.TEXT_PLAIN);
user_profile_image_url = values.getAsString(Statuses.USER_PROFILE_IMAGE_URL);
is_favorite = getAsBoolean(values, Statuses.IS_FAVORITE, false);
is_retweet = getAsBoolean(values, Statuses.IS_RETWEET, false);
is_gap = getAsBoolean(values, Statuses.IS_GAP, false);
location = ParcelableLocation.fromString(values.getAsString(Statuses.LOCATION));
user_is_protected = getAsBoolean(values, Statuses.IS_PROTECTED, false);
user_is_verified = getAsBoolean(values, Statuses.IS_VERIFIED, false);
in_reply_to_status_id = getAsLong(values, Statuses.IN_REPLY_TO_STATUS_ID, -1);
in_reply_to_user_id = getAsLong(values, Statuses.IN_REPLY_TO_USER_ID, -1);
in_reply_to_name = values.getAsString(Statuses.IN_REPLY_TO_USER_NAME);
in_reply_to_screen_name = values.getAsString(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
my_retweet_id = getAsLong(values, Statuses.MY_RETWEET_ID, -1);
retweeted_by_name = values.getAsString(Statuses.RETWEETED_BY_USER_NAME);
retweeted_by_screen_name = values.getAsString(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
source = values.getAsString(Statuses.SOURCE);
retweet_count = getAsInteger(values, Statuses.RETWEET_COUNT, 0);
favorite_count = getAsInteger(values, Statuses.FAVORITE_COUNT, 0);
text_unescaped = values.getAsString(Statuses.TEXT_UNESCAPED);
medias = ParcelableMedia.fromJSONString(values.getAsString(Statuses.MEDIAS));
is_possibly_sensitive = getAsBoolean(values, Statuses.IS_POSSIBLY_SENSITIVE, false);
user_is_following = getAsBoolean(values, Statuses.IS_FOLLOWING, false);
mentions = ParcelableUserMention.fromJSONString(values.getAsString(Statuses.MENTIONS));
first_media = values.getAsString(Statuses.FIRST_MEDIA);
}
public ParcelableStatus(final Cursor c, final CursorIndices idx) {
id = idx.status_id != -1 ? c.getLong(idx.status_id) : -1;
account_id = idx.account_id != -1 ? c.getLong(idx.account_id) : -1;
timestamp = idx.status_timestamp != -1 ? c.getLong(idx.status_timestamp) : 0;
user_id = idx.user_id != -1 ? c.getLong(idx.user_id) : -1;
retweet_id = idx.retweet_id != -1 ? c.getLong(idx.retweet_id) : -1;
retweet_timestamp = idx.retweet_timestamp != -1 ? c.getLong(idx.retweet_timestamp) : -1;
retweeted_by_id = idx.retweeted_by_user_id != -1 ? c.getLong(idx.retweeted_by_user_id) : -1;
retweet_count = idx.retweet_count != -1 ? c.getLong(idx.retweet_count) : -1;
favorite_count = idx.favorite_count != -1 ? c.getLong(idx.favorite_count) : -1;
in_reply_to_status_id = idx.in_reply_to_status_id != -1 ? c.getLong(idx.in_reply_to_status_id) : -1;
in_reply_to_user_id = idx.in_reply_to_user_id != -1 ? c.getLong(idx.in_reply_to_user_id) : -1;
is_gap = idx.is_gap != -1 ? c.getInt(idx.is_gap) == 1 : false;
is_retweet = idx.is_retweet != -1 ? c.getInt(idx.is_retweet) == 1 : false;
is_favorite = idx.is_favorite != -1 ? c.getInt(idx.is_favorite) == 1 : false;
user_is_protected = idx.is_protected != -1 ? c.getInt(idx.is_protected) == 1 : false;
user_is_verified = idx.is_verified != -1 ? c.getInt(idx.is_verified) == 1 : false;
retweeted_by_name = idx.retweeted_by_user_name != -1 ? c.getString(idx.retweeted_by_user_name) : null;
retweeted_by_screen_name = idx.retweeted_by_user_screen_name != -1 ? c
.getString(idx.retweeted_by_user_screen_name) : null;
text_html = idx.text_html != -1 ? c.getString(idx.text_html) : null;
medias = ParcelableMedia.fromJSONString(idx.medias != -1 ? c.getString(idx.medias) : null);
text_plain = idx.text_plain != -1 ? c.getString(idx.text_plain) : null;
user_name = idx.user_name != -1 ? c.getString(idx.user_name) : null;
user_screen_name = idx.user_screen_name != -1 ? c.getString(idx.user_screen_name) : null;
in_reply_to_name = idx.in_reply_to_user_name != -1 ? c.getString(idx.in_reply_to_user_name) : null;
in_reply_to_screen_name = idx.in_reply_to_user_screen_name != -1 ? c
.getString(idx.in_reply_to_user_screen_name) : null;
source = idx.source != -1 ? c.getString(idx.source) : null;
location = idx.location != -1 ? new ParcelableLocation(c.getString(idx.location)) : null;
user_profile_image_url = idx.user_profile_image_url != -1 ? c.getString(idx.user_profile_image_url) : null;
text_unescaped = idx.text_unescaped != -1 ? c.getString(idx.text_unescaped) : null;
my_retweet_id = idx.my_retweet_id != -1 ? c.getLong(idx.my_retweet_id) : -1;
is_possibly_sensitive = idx.is_possibly_sensitive != -1 ? c.getInt(idx.is_possibly_sensitive) == 1 : false;
user_is_following = idx.is_following != -1 ? c.getInt(idx.is_following) == 1 : false;
mentions = idx.mentions != -1 ? ParcelableUserMention.fromJSONString(c.getString(idx.mentions)) : null;
first_media = idx.first_media != -1 ? c.getString(idx.first_media) : null;
}
public ParcelableStatus(final Cursor c, final CursorIndices idx) {
id = idx.status_id != -1 ? c.getLong(idx.status_id) : -1;
account_id = idx.account_id != -1 ? c.getLong(idx.account_id) : -1;
timestamp = idx.status_timestamp != -1 ? c.getLong(idx.status_timestamp) : 0;
user_id = idx.user_id != -1 ? c.getLong(idx.user_id) : -1;
retweet_id = idx.retweet_id != -1 ? c.getLong(idx.retweet_id) : -1;
retweet_timestamp = idx.retweet_timestamp != -1 ? c.getLong(idx.retweet_timestamp) : -1;
retweeted_by_id = idx.retweeted_by_user_id != -1 ? c.getLong(idx.retweeted_by_user_id) : -1;
retweet_count = idx.retweet_count != -1 ? c.getLong(idx.retweet_count) : -1;
favorite_count = idx.favorite_count != -1 ? c.getLong(idx.favorite_count) : -1;
in_reply_to_status_id = idx.in_reply_to_status_id != -1 ? c.getLong(idx.in_reply_to_status_id) : -1;
in_reply_to_user_id = idx.in_reply_to_user_id != -1 ? c.getLong(idx.in_reply_to_user_id) : -1;
is_gap = idx.is_gap != -1 && c.getInt(idx.is_gap) == 1;
is_retweet = idx.is_retweet != -1 && c.getInt(idx.is_retweet) == 1;
is_favorite = idx.is_favorite != -1 && c.getInt(idx.is_favorite) == 1;
user_is_protected = idx.is_protected != -1 && c.getInt(idx.is_protected) == 1;
user_is_verified = idx.is_verified != -1 && c.getInt(idx.is_verified) == 1;
retweeted_by_name = idx.retweeted_by_user_name != -1 ? c.getString(idx.retweeted_by_user_name) : null;
retweeted_by_screen_name = idx.retweeted_by_user_screen_name != -1 ? c
.getString(idx.retweeted_by_user_screen_name) : null;
text_html = idx.text_html != -1 ? c.getString(idx.text_html) : null;
medias = ParcelableMedia.fromJSONString(idx.medias != -1 ? c.getString(idx.medias) : null);
text_plain = idx.text_plain != -1 ? c.getString(idx.text_plain) : null;
user_name = idx.user_name != -1 ? c.getString(idx.user_name) : null;
user_screen_name = idx.user_screen_name != -1 ? c.getString(idx.user_screen_name) : null;
in_reply_to_name = idx.in_reply_to_user_name != -1 ? c.getString(idx.in_reply_to_user_name) : null;
in_reply_to_screen_name = idx.in_reply_to_user_screen_name != -1 ? c
.getString(idx.in_reply_to_user_screen_name) : null;
source = idx.source != -1 ? c.getString(idx.source) : null;
location = idx.location != -1 ? new ParcelableLocation(c.getString(idx.location)) : null;
user_profile_image_url = idx.user_profile_image_url != -1 ? c.getString(idx.user_profile_image_url) : null;
text_unescaped = idx.text_unescaped != -1 ? c.getString(idx.text_unescaped) : null;
my_retweet_id = idx.my_retweet_id != -1 ? c.getLong(idx.my_retweet_id) : -1;
is_possibly_sensitive = idx.is_possibly_sensitive != -1 && c.getInt(idx.is_possibly_sensitive) == 1;
user_is_following = idx.is_following != -1 && c.getInt(idx.is_following) == 1;
mentions = idx.mentions != -1 ? ParcelableUserMention.fromJSONString(c.getString(idx.mentions)) : null;
first_media = idx.first_media != -1 ? c.getString(idx.first_media) : null;
}
public ParcelableStatus(final JSONParcel in) {
id = in.readLong("status_id");
account_id = in.readLong("account_id");
timestamp = in.readLong("status_timestamp");
user_id = in.readLong("user_id");
retweet_id = in.readLong("retweet_id");
retweet_timestamp = in.readLong("retweet_timestamp");
retweeted_by_id = in.readLong("retweeted_by_id");
retweet_count = in.readLong("retweet_count");
favorite_count = in.readLong("favorite_count");
in_reply_to_status_id = in.readLong("in_reply_to_status_id");
in_reply_to_user_id = in.readLong("in_reply_to_user_id");
is_gap = in.readBoolean("is_gap");
is_retweet = in.readBoolean("is_retweet");
is_favorite = in.readBoolean("is_favorite");
user_is_protected = in.readBoolean("is_protected");
user_is_verified = in.readBoolean("is_verified");
retweeted_by_name = in.readString("retweeted_by_name");
retweeted_by_screen_name = in.readString("retweeted_by_screen_name");
text_html = in.readString("text_html");
text_plain = in.readString("text_plain");
user_name = in.readString("name");
user_screen_name = in.readString("screen_name");
in_reply_to_name = in.readString("in_reply_to_name");
in_reply_to_screen_name = in.readString("in_reply_to_screen_name");
source = in.readString("source");
user_profile_image_url = in.readString("profile_image_url");
medias = in.readParcelableArray("medias", ParcelableMedia.JSON_CREATOR);
location = in.readParcelable("location", ParcelableLocation.JSON_CREATOR);
my_retweet_id = in.readLong("my_retweet_id");
is_possibly_sensitive = in.readBoolean("is_possibly_sensitive");
text_unescaped = in.readString("text_unescaped");
user_is_following = in.readBoolean("is_following");
mentions = in.readParcelableArray("mentions", ParcelableUserMention.JSON_CREATOR);
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
public ParcelableStatus(final JSONParcel in) {
id = in.readLong("status_id");
account_id = in.readLong("account_id");
timestamp = in.readLong("status_timestamp");
user_id = in.readLong("user_id");
retweet_id = in.readLong("retweet_id");
retweet_timestamp = in.readLong("retweet_timestamp");
retweeted_by_id = in.readLong("retweeted_by_id");
retweet_count = in.readLong("retweet_count");
favorite_count = in.readLong("favorite_count");
in_reply_to_status_id = in.readLong("in_reply_to_status_id");
in_reply_to_user_id = in.readLong("in_reply_to_user_id");
is_gap = in.readBoolean("is_gap");
is_retweet = in.readBoolean("is_retweet");
is_favorite = in.readBoolean("is_favorite");
user_is_protected = in.readBoolean("is_protected");
user_is_verified = in.readBoolean("is_verified");
retweeted_by_name = in.readString("retweeted_by_name");
retweeted_by_screen_name = in.readString("retweeted_by_screen_name");
text_html = in.readString("text_html");
text_plain = in.readString("text_plain");
user_name = in.readString("name");
user_screen_name = in.readString("screen_name");
in_reply_to_name = in.readString("in_reply_to_name");
in_reply_to_screen_name = in.readString("in_reply_to_screen_name");
source = in.readString("source");
user_profile_image_url = in.readString("profile_image_url");
medias = in.readParcelableArray("medias", ParcelableMedia.JSON_CREATOR);
location = in.readParcelable("location", ParcelableLocation.JSON_CREATOR);
my_retweet_id = in.readLong("my_retweet_id");
is_possibly_sensitive = in.readBoolean("is_possibly_sensitive");
text_unescaped = in.readString("text_unescaped");
user_is_following = in.readBoolean("is_following");
mentions = in.readParcelableArray("mentions", ParcelableUserMention.JSON_CREATOR);
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
public ParcelableStatus(final Parcel in) {
id = in.readLong();
account_id = in.readLong();
timestamp = in.readLong();
user_id = in.readLong();
retweet_id = in.readLong();
retweet_timestamp = in.readLong();
retweeted_by_id = in.readLong();
retweet_count = in.readLong();
favorite_count = in.readLong();
in_reply_to_status_id = in.readLong();
is_gap = in.readInt() == 1;
is_retweet = in.readInt() == 1;
is_favorite = in.readInt() == 1;
user_is_protected = in.readInt() == 1;
user_is_verified = in.readInt() == 1;
retweeted_by_name = in.readString();
retweeted_by_screen_name = in.readString();
text_html = in.readString();
text_plain = in.readString();
user_name = in.readString();
user_screen_name = in.readString();
in_reply_to_screen_name = in.readString();
source = in.readString();
user_profile_image_url = in.readString();
medias = in.createTypedArray(ParcelableMedia.CREATOR);
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
my_retweet_id = in.readLong();
is_possibly_sensitive = in.readInt() == 1;
user_is_following = in.readInt() == 1;
text_unescaped = in.readString();
in_reply_to_user_id = in.readLong();
in_reply_to_name = in.readString();
mentions = in.createTypedArray(ParcelableUserMention.CREATOR);
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
public ParcelableStatus(final Parcel in) {
id = in.readLong();
account_id = in.readLong();
timestamp = in.readLong();
user_id = in.readLong();
retweet_id = in.readLong();
retweet_timestamp = in.readLong();
retweeted_by_id = in.readLong();
retweet_count = in.readLong();
favorite_count = in.readLong();
in_reply_to_status_id = in.readLong();
is_gap = in.readInt() == 1;
is_retweet = in.readInt() == 1;
is_favorite = in.readInt() == 1;
user_is_protected = in.readInt() == 1;
user_is_verified = in.readInt() == 1;
retweeted_by_name = in.readString();
retweeted_by_screen_name = in.readString();
text_html = in.readString();
text_plain = in.readString();
user_name = in.readString();
user_screen_name = in.readString();
in_reply_to_screen_name = in.readString();
source = in.readString();
user_profile_image_url = in.readString();
medias = in.createTypedArray(ParcelableMedia.CREATOR);
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
my_retweet_id = in.readLong();
is_possibly_sensitive = in.readInt() == 1;
user_is_following = in.readInt() == 1;
text_unescaped = in.readString();
in_reply_to_user_id = in.readLong();
in_reply_to_name = in.readString();
mentions = in.createTypedArray(ParcelableUserMention.CREATOR);
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
public ParcelableStatus(final Status orig, final long account_id, final boolean is_gap) {
this.is_gap = is_gap;
this.account_id = account_id;
id = orig.getId();
timestamp = getTime(orig.getCreatedAt());
is_retweet = orig.isRetweet();
final Status retweeted_status = orig.getRetweetedStatus();
final User retweet_user = retweeted_status != null ? orig.getUser() : null;
retweet_id = retweeted_status != null ? retweeted_status.getId() : -1;
retweet_timestamp = retweeted_status != null ? getTime(orig.getCreatedAt()) : -1;
retweeted_by_id = retweet_user != null ? retweet_user.getId() : -1;
retweeted_by_name = retweet_user != null ? retweet_user.getName() : null;
retweeted_by_screen_name = retweet_user != null ? retweet_user.getScreenName() : null;
final Status status = retweeted_status != null ? retweeted_status : orig;
final User user = status.getUser();
user_id = user.getId();
user_name = user.getName();
user_screen_name = user.getScreenName();
user_profile_image_url = ParseUtils.parseString(user.getProfileImageUrlHttps());
user_is_protected = user.isProtected();
user_is_verified = user.isVerified();
user_is_following = user.isFollowing();
text_html = formatStatusText(status);
medias = ParcelableMedia.fromEntities(status);
text_plain = status.getText();
retweet_count = status.getRetweetCount();
favorite_count = status.getFavoriteCount();
in_reply_to_name = getInReplyToName(status);
in_reply_to_screen_name = status.getInReplyToScreenName();
in_reply_to_status_id = status.getInReplyToStatusId();
in_reply_to_user_id = status.getInReplyToUserId();
source = status.getSource();
location = new ParcelableLocation(status.getGeoLocation());
is_favorite = status.isFavorited();
text_unescaped = toPlainText(text_html);
my_retweet_id = retweeted_by_id == account_id ? id : -1;
is_possibly_sensitive = status.isPossiblySensitive();
mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities());
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
public ParcelableStatus(final Status orig, final long account_id, final boolean is_gap) {
this.is_gap = is_gap;
this.account_id = account_id;
id = orig.getId();
timestamp = getTime(orig.getCreatedAt());
is_retweet = orig.isRetweet();
final Status retweeted_status = orig.getRetweetedStatus();
final User retweet_user = retweeted_status != null ? orig.getUser() : null;
retweet_id = retweeted_status != null ? retweeted_status.getId() : -1;
retweet_timestamp = retweeted_status != null ? getTime(orig.getCreatedAt()) : -1;
retweeted_by_id = retweet_user != null ? retweet_user.getId() : -1;
retweeted_by_name = retweet_user != null ? retweet_user.getName() : null;
retweeted_by_screen_name = retweet_user != null ? retweet_user.getScreenName() : null;
final Status status = retweeted_status != null ? retweeted_status : orig;
final User user = status.getUser();
user_id = user.getId();
user_name = user.getName();
user_screen_name = user.getScreenName();
user_profile_image_url = ParseUtils.parseString(user.getProfileImageUrlHttps());
user_is_protected = user.isProtected();
user_is_verified = user.isVerified();
user_is_following = user.isFollowing();
text_html = formatStatusText(status);
medias = ParcelableMedia.fromEntities(status);
text_plain = status.getText();
retweet_count = status.getRetweetCount();
favorite_count = status.getFavoriteCount();
in_reply_to_name = getInReplyToName(status);
in_reply_to_screen_name = status.getInReplyToScreenName();
in_reply_to_status_id = status.getInReplyToStatusId();
in_reply_to_user_id = status.getInReplyToUserId();
source = status.getSource();
location = new ParcelableLocation(status.getGeoLocation());
is_favorite = status.isFavorited();
text_unescaped = toPlainText(text_html);
my_retweet_id = retweeted_by_id == account_id ? id : -1;
is_possibly_sensitive = status.isPossiblySensitive();
mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities());
first_media = medias != null && medias.length > 0 ? medias[0].url : null;
}
@Override
public int compareTo(final ParcelableStatus another) {
if (another == null) return 0;
final long diff = another.id - id;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
@Override
public int compareTo(@NonNull final ParcelableStatus another) {
final long diff = another.id - id;
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) diff;
}
@Override
public int describeContents() {
return 0;
}
@Override
public int describeContents() {
return 0;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof ParcelableStatus)) return false;
final ParcelableStatus other = (ParcelableStatus) obj;
if (account_id != other.account_id) return false;
if (id != other.id) return false;
return true;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof ParcelableStatus)) return false;
final ParcelableStatus other = (ParcelableStatus) obj;
return account_id == other.account_id && id == other.id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (account_id ^ account_id >>> 32);
result = prime * result + (int) (id ^ id >>> 32);
return result;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (account_id ^ account_id >>> 32);
result = prime * result + (int) (id ^ id >>> 32);
return result;
}
@Override
public String toString() {
return "ParcelableStatus{retweet_id=" + retweet_id + ", retweeted_by_id=" + retweeted_by_id + ", id=" + id
+ ", account_id=" + account_id + ", user_id=" + user_id + ", timestamp=" + timestamp
+ ", retweet_count=" + retweet_count + ", favorite_count=" + favorite_count
+ ", in_reply_to_status_id=" + in_reply_to_status_id + ", in_reply_to_user_id=" + in_reply_to_user_id
+ ", my_retweet_id=" + my_retweet_id + ", is_gap=" + is_gap + ", is_retweet=" + is_retweet
+ ", is_favorite=" + is_favorite + ", is_possibly_sensitive=" + is_possibly_sensitive
+ ", user_is_following=" + user_is_following + ", user_is_protected=" + user_is_protected
+ ", user_is_verified=" + user_is_verified + ", retweeted_by_name=" + retweeted_by_name
+ ", retweeted_by_screen_name=" + retweeted_by_screen_name + ", text_html=" + text_html
+ ", text_plain=" + text_plain + ", user_name=" + user_name + ", user_screen_name=" + user_screen_name
+ ", in_reply_to_name=" + in_reply_to_name + ", in_reply_to_screen_name=" + in_reply_to_screen_name
+ ", source=" + source + ", user_profile_image_url=" + user_profile_image_url + ", text_unescaped="
+ text_unescaped + ", first_media=" + first_media + ", location=" + location + ", mentions="
+ Arrays.toString(mentions) + ", medias=" + Arrays.toString(medias) + "}";
}
@Override
public String toString() {
return "ParcelableStatus{retweet_id=" + retweet_id + ", retweeted_by_id=" + retweeted_by_id + ", id=" + id
+ ", account_id=" + account_id + ", user_id=" + user_id + ", timestamp=" + timestamp
+ ", retweet_count=" + retweet_count + ", favorite_count=" + favorite_count
+ ", in_reply_to_status_id=" + in_reply_to_status_id + ", in_reply_to_user_id=" + in_reply_to_user_id
+ ", my_retweet_id=" + my_retweet_id + ", is_gap=" + is_gap + ", is_retweet=" + is_retweet
+ ", is_favorite=" + is_favorite + ", is_possibly_sensitive=" + is_possibly_sensitive
+ ", user_is_following=" + user_is_following + ", user_is_protected=" + user_is_protected
+ ", user_is_verified=" + user_is_verified + ", retweeted_by_name=" + retweeted_by_name
+ ", retweeted_by_screen_name=" + retweeted_by_screen_name + ", text_html=" + text_html
+ ", text_plain=" + text_plain + ", user_name=" + user_name + ", user_screen_name=" + user_screen_name
+ ", in_reply_to_name=" + in_reply_to_name + ", in_reply_to_screen_name=" + in_reply_to_screen_name
+ ", source=" + source + ", user_profile_image_url=" + user_profile_image_url + ", text_unescaped="
+ text_unescaped + ", first_media=" + first_media + ", location=" + location + ", mentions="
+ Arrays.toString(mentions) + ", medias=" + Arrays.toString(medias) + "}";
}
@Override
public void writeToParcel(final JSONParcel out) {
out.writeLong("status_id", id);
out.writeLong("account_id", account_id);
out.writeLong("status_timestamp", timestamp);
out.writeLong("user_id", user_id);
out.writeLong("retweet_id", retweet_id);
out.writeLong("retweet_timestamp", retweet_timestamp);
out.writeLong("retweeted_by_id", retweeted_by_id);
out.writeLong("retweet_count", retweet_count);
out.writeLong("favorite_count", favorite_count);
out.writeLong("in_reply_to_status_id", in_reply_to_status_id);
out.writeLong("in_reply_to_user_id", in_reply_to_user_id);
out.writeBoolean("is_gap", is_gap);
out.writeBoolean("is_retweet", is_retweet);
out.writeBoolean("is_favorite", is_favorite);
out.writeBoolean("is_protected", user_is_protected);
out.writeBoolean("is_verified", user_is_verified);
out.writeString("retweeted_by_name", retweeted_by_name);
out.writeString("retweeted_by_screen_name", retweeted_by_screen_name);
out.writeString("text_html", text_html);
out.writeString("text_plain", text_plain);
out.writeString("text_unescaped", text_unescaped);
out.writeString("name", user_name);
out.writeString("screen_name", user_screen_name);
out.writeString("in_reply_to_name", in_reply_to_name);
out.writeString("in_reply_to_screen_name", in_reply_to_screen_name);
out.writeString("source", source);
out.writeString("profile_image_url", user_profile_image_url);
out.writeParcelableArray("medias", medias);
out.writeParcelable("location", location);
out.writeLong("my_retweet_id", my_retweet_id);
out.writeBoolean("is_possibly_sensitive", is_possibly_sensitive);
out.writeBoolean("is_following", user_is_following);
out.writeParcelableArray("mentions", mentions);
}
@Override
public void writeToParcel(final JSONParcel out) {
out.writeLong("status_id", id);
out.writeLong("account_id", account_id);
out.writeLong("status_timestamp", timestamp);
out.writeLong("user_id", user_id);
out.writeLong("retweet_id", retweet_id);
out.writeLong("retweet_timestamp", retweet_timestamp);
out.writeLong("retweeted_by_id", retweeted_by_id);
out.writeLong("retweet_count", retweet_count);
out.writeLong("favorite_count", favorite_count);
out.writeLong("in_reply_to_status_id", in_reply_to_status_id);
out.writeLong("in_reply_to_user_id", in_reply_to_user_id);
out.writeBoolean("is_gap", is_gap);
out.writeBoolean("is_retweet", is_retweet);
out.writeBoolean("is_favorite", is_favorite);
out.writeBoolean("is_protected", user_is_protected);
out.writeBoolean("is_verified", user_is_verified);
out.writeString("retweeted_by_name", retweeted_by_name);
out.writeString("retweeted_by_screen_name", retweeted_by_screen_name);
out.writeString("text_html", text_html);
out.writeString("text_plain", text_plain);
out.writeString("text_unescaped", text_unescaped);
out.writeString("name", user_name);
out.writeString("screen_name", user_screen_name);
out.writeString("in_reply_to_name", in_reply_to_name);
out.writeString("in_reply_to_screen_name", in_reply_to_screen_name);
out.writeString("source", source);
out.writeString("profile_image_url", user_profile_image_url);
out.writeParcelableArray("medias", medias);
out.writeParcelable("location", location);
out.writeLong("my_retweet_id", my_retweet_id);
out.writeBoolean("is_possibly_sensitive", is_possibly_sensitive);
out.writeBoolean("is_following", user_is_following);
out.writeParcelableArray("mentions", mentions);
}
@Override
public void writeToParcel(final Parcel out, final int flags) {
out.writeLong(id);
out.writeLong(account_id);
out.writeLong(timestamp);
out.writeLong(user_id);
out.writeLong(retweet_id);
out.writeLong(retweet_timestamp);
out.writeLong(retweeted_by_id);
out.writeLong(retweet_count);
out.writeLong(favorite_count);
out.writeLong(in_reply_to_status_id);
out.writeInt(is_gap ? 1 : 0);
out.writeInt(is_retweet ? 1 : 0);
out.writeInt(is_favorite ? 1 : 0);
out.writeInt(user_is_protected ? 1 : 0);
out.writeInt(user_is_verified ? 1 : 0);
out.writeString(retweeted_by_name);
out.writeString(retweeted_by_screen_name);
out.writeString(text_html);
out.writeString(text_plain);
out.writeString(user_name);
out.writeString(user_screen_name);
out.writeString(in_reply_to_screen_name);
out.writeString(source);
out.writeString(user_profile_image_url);
out.writeTypedArray(medias, flags);
out.writeParcelable(location, flags);
out.writeLong(my_retweet_id);
out.writeInt(is_possibly_sensitive ? 1 : 0);
out.writeInt(user_is_following ? 1 : 0);
out.writeString(text_unescaped);
out.writeLong(in_reply_to_user_id);
out.writeString(in_reply_to_name);
out.writeTypedArray(mentions, flags);
}
@Override
public void writeToParcel(final Parcel out, final int flags) {
out.writeLong(id);
out.writeLong(account_id);
out.writeLong(timestamp);
out.writeLong(user_id);
out.writeLong(retweet_id);
out.writeLong(retweet_timestamp);
out.writeLong(retweeted_by_id);
out.writeLong(retweet_count);
out.writeLong(favorite_count);
out.writeLong(in_reply_to_status_id);
out.writeInt(is_gap ? 1 : 0);
out.writeInt(is_retweet ? 1 : 0);
out.writeInt(is_favorite ? 1 : 0);
out.writeInt(user_is_protected ? 1 : 0);
out.writeInt(user_is_verified ? 1 : 0);
out.writeString(retweeted_by_name);
out.writeString(retweeted_by_screen_name);
out.writeString(text_html);
out.writeString(text_plain);
out.writeString(user_name);
out.writeString(user_screen_name);
out.writeString(in_reply_to_screen_name);
out.writeString(source);
out.writeString(user_profile_image_url);
out.writeTypedArray(medias, flags);
out.writeParcelable(location, flags);
out.writeLong(my_retweet_id);
out.writeInt(is_possibly_sensitive ? 1 : 0);
out.writeInt(user_is_following ? 1 : 0);
out.writeString(text_unescaped);
out.writeLong(in_reply_to_user_id);
out.writeString(in_reply_to_name);
out.writeTypedArray(mentions, flags);
}
private static long getTime(final Date date) {
return date != null ? date.getTime() : 0;
}
private static long getTime(final Date date) {
return date != null ? date.getTime() : 0;
}
public static final class CursorIndices {
public static final class CursorIndices {
public final int _id, account_id, status_id, status_timestamp, user_name, user_screen_name, text_html,
text_plain, text_unescaped, user_profile_image_url, is_favorite, is_retweet, is_gap, location,
is_protected, is_verified, in_reply_to_status_id, in_reply_to_user_id, in_reply_to_user_name,
in_reply_to_user_screen_name, my_retweet_id, retweeted_by_user_name, retweeted_by_user_screen_name,
retweet_id, retweet_timestamp, retweeted_by_user_id, user_id, source, retweet_count, favorite_count,
is_possibly_sensitive, is_following, medias, first_media, mentions;
public final int _id, account_id, status_id, status_timestamp, user_name, user_screen_name, text_html,
text_plain, text_unescaped, user_profile_image_url, is_favorite, is_retweet, is_gap, location,
is_protected, is_verified, in_reply_to_status_id, in_reply_to_user_id, in_reply_to_user_name,
in_reply_to_user_screen_name, my_retweet_id, retweeted_by_user_name, retweeted_by_user_screen_name,
retweet_id, retweet_timestamp, retweeted_by_user_id, user_id, source, retweet_count, favorite_count,
is_possibly_sensitive, is_following, medias, first_media, mentions;
public CursorIndices(final Cursor cursor) {
_id = cursor.getColumnIndex(Statuses._ID);
account_id = cursor.getColumnIndex(Statuses.ACCOUNT_ID);
status_id = cursor.getColumnIndex(Statuses.STATUS_ID);
status_timestamp = cursor.getColumnIndex(Statuses.STATUS_TIMESTAMP);
user_name = cursor.getColumnIndex(Statuses.USER_NAME);
user_screen_name = cursor.getColumnIndex(Statuses.USER_SCREEN_NAME);
text_html = cursor.getColumnIndex(Statuses.TEXT_HTML);
text_plain = cursor.getColumnIndex(Statuses.TEXT_PLAIN);
text_unescaped = cursor.getColumnIndex(Statuses.TEXT_UNESCAPED);
user_profile_image_url = cursor.getColumnIndex(Statuses.USER_PROFILE_IMAGE_URL);
is_favorite = cursor.getColumnIndex(Statuses.IS_FAVORITE);
is_retweet = cursor.getColumnIndex(Statuses.IS_RETWEET);
is_gap = cursor.getColumnIndex(Statuses.IS_GAP);
location = cursor.getColumnIndex(Statuses.LOCATION);
is_protected = cursor.getColumnIndex(Statuses.IS_PROTECTED);
is_verified = cursor.getColumnIndex(Statuses.IS_VERIFIED);
in_reply_to_status_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_STATUS_ID);
in_reply_to_user_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_ID);
in_reply_to_user_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_NAME);
in_reply_to_user_screen_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
my_retweet_id = cursor.getColumnIndex(Statuses.MY_RETWEET_ID);
retweet_id = cursor.getColumnIndex(Statuses.RETWEET_ID);
retweet_timestamp = cursor.getColumnIndex(Statuses.RETWEET_TIMESTAMP);
retweeted_by_user_id = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_ID);
retweeted_by_user_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_NAME);
retweeted_by_user_screen_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
user_id = cursor.getColumnIndex(Statuses.USER_ID);
source = cursor.getColumnIndex(Statuses.SOURCE);
retweet_count = cursor.getColumnIndex(Statuses.RETWEET_COUNT);
favorite_count = cursor.getColumnIndex(Statuses.FAVORITE_COUNT);
is_possibly_sensitive = cursor.getColumnIndex(Statuses.IS_POSSIBLY_SENSITIVE);
is_following = cursor.getColumnIndex(Statuses.IS_FOLLOWING);
medias = cursor.getColumnIndex(Statuses.MEDIAS);
first_media = cursor.getColumnIndex(Statuses.FIRST_MEDIA);
mentions = cursor.getColumnIndex(Statuses.MENTIONS);
}
public CursorIndices(final Cursor cursor) {
_id = cursor.getColumnIndex(Statuses._ID);
account_id = cursor.getColumnIndex(Statuses.ACCOUNT_ID);
status_id = cursor.getColumnIndex(Statuses.STATUS_ID);
status_timestamp = cursor.getColumnIndex(Statuses.STATUS_TIMESTAMP);
user_name = cursor.getColumnIndex(Statuses.USER_NAME);
user_screen_name = cursor.getColumnIndex(Statuses.USER_SCREEN_NAME);
text_html = cursor.getColumnIndex(Statuses.TEXT_HTML);
text_plain = cursor.getColumnIndex(Statuses.TEXT_PLAIN);
text_unescaped = cursor.getColumnIndex(Statuses.TEXT_UNESCAPED);
user_profile_image_url = cursor.getColumnIndex(Statuses.USER_PROFILE_IMAGE_URL);
is_favorite = cursor.getColumnIndex(Statuses.IS_FAVORITE);
is_retweet = cursor.getColumnIndex(Statuses.IS_RETWEET);
is_gap = cursor.getColumnIndex(Statuses.IS_GAP);
location = cursor.getColumnIndex(Statuses.LOCATION);
is_protected = cursor.getColumnIndex(Statuses.IS_PROTECTED);
is_verified = cursor.getColumnIndex(Statuses.IS_VERIFIED);
in_reply_to_status_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_STATUS_ID);
in_reply_to_user_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_ID);
in_reply_to_user_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_NAME);
in_reply_to_user_screen_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
my_retweet_id = cursor.getColumnIndex(Statuses.MY_RETWEET_ID);
retweet_id = cursor.getColumnIndex(Statuses.RETWEET_ID);
retweet_timestamp = cursor.getColumnIndex(Statuses.RETWEET_TIMESTAMP);
retweeted_by_user_id = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_ID);
retweeted_by_user_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_NAME);
retweeted_by_user_screen_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
user_id = cursor.getColumnIndex(Statuses.USER_ID);
source = cursor.getColumnIndex(Statuses.SOURCE);
retweet_count = cursor.getColumnIndex(Statuses.RETWEET_COUNT);
favorite_count = cursor.getColumnIndex(Statuses.FAVORITE_COUNT);
is_possibly_sensitive = cursor.getColumnIndex(Statuses.IS_POSSIBLY_SENSITIVE);
is_following = cursor.getColumnIndex(Statuses.IS_FOLLOWING);
medias = cursor.getColumnIndex(Statuses.MEDIAS);
first_media = cursor.getColumnIndex(Statuses.FIRST_MEDIA);
mentions = cursor.getColumnIndex(Statuses.MENTIONS);
}
@Override
public String toString() {
return "CursorIndices{_id=" + _id + ", account_id=" + account_id + ", status_id=" + status_id
+ ", status_timestamp=" + status_timestamp + ", user_name=" + user_name + ", user_screen_name="
+ user_screen_name + ", text_html=" + text_html + ", text_plain=" + text_plain
+ ", text_unescaped=" + text_unescaped + ", user_profile_image_url=" + user_profile_image_url
+ ", is_favorite=" + is_favorite + ", is_retweet=" + is_retweet + ", is_gap=" + is_gap
+ ", location=" + location + ", is_protected=" + is_protected + ", is_verified=" + is_verified
+ ", in_reply_to_status_id=" + in_reply_to_status_id + ", in_reply_to_user_id="
+ in_reply_to_user_id + ", in_reply_to_user_name=" + in_reply_to_user_name
+ ", in_reply_to_user_screen_name=" + in_reply_to_user_screen_name + ", my_retweet_id="
+ my_retweet_id + ", retweeted_by_user_name=" + retweeted_by_user_name
+ ", retweeted_by_user_screen_name=" + retweeted_by_user_screen_name + ", retweet_id=" + retweet_id
+ ", retweet_timestamp=" + retweet_timestamp + ", retweeted_by_user_id=" + retweeted_by_user_id
+ ", user_id=" + user_id + ", source=" + source + ", retweet_count=" + retweet_count
+ ", favorite_count=" + favorite_count + ", is_possibly_sensitive=" + is_possibly_sensitive
+ ", is_following=" + is_following + ", medias=" + medias + ", first_media=" + first_media
+ ", mentions=" + mentions + "}";
}
}
@Override
public String toString() {
return "CursorIndices{_id=" + _id + ", account_id=" + account_id + ", status_id=" + status_id
+ ", status_timestamp=" + status_timestamp + ", user_name=" + user_name + ", user_screen_name="
+ user_screen_name + ", text_html=" + text_html + ", text_plain=" + text_plain
+ ", text_unescaped=" + text_unescaped + ", user_profile_image_url=" + user_profile_image_url
+ ", is_favorite=" + is_favorite + ", is_retweet=" + is_retweet + ", is_gap=" + is_gap
+ ", location=" + location + ", is_protected=" + is_protected + ", is_verified=" + is_verified
+ ", in_reply_to_status_id=" + in_reply_to_status_id + ", in_reply_to_user_id="
+ in_reply_to_user_id + ", in_reply_to_user_name=" + in_reply_to_user_name
+ ", in_reply_to_user_screen_name=" + in_reply_to_user_screen_name + ", my_retweet_id="
+ my_retweet_id + ", retweeted_by_user_name=" + retweeted_by_user_name
+ ", retweeted_by_user_screen_name=" + retweeted_by_user_screen_name + ", retweet_id=" + retweet_id
+ ", retweet_timestamp=" + retweet_timestamp + ", retweeted_by_user_id=" + retweeted_by_user_id
+ ", user_id=" + user_id + ", source=" + source + ", retweet_count=" + retweet_count
+ ", favorite_count=" + favorite_count + ", is_possibly_sensitive=" + is_possibly_sensitive
+ ", is_following=" + is_following + ", medias=" + medias + ", first_media=" + first_media
+ ", mentions=" + mentions + "}";
}
}
}

View File

@ -19,15 +19,12 @@
package org.mariotaku.twidere.preference;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@ -38,127 +35,129 @@ import android.widget.TextView;
import org.mariotaku.menucomponent.widget.MenuBar;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.content.TwidereContextThemeWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.view.iface.ICardItemView;
import org.mariotaku.twidere.view.iface.IExtendedView;
import org.mariotaku.twidere.view.iface.IExtendedView.TouchInterceptor;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
public class ThemePreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener {
public ThemePreviewPreference(final Context context) {
this(context, null);
}
public ThemePreviewPreference(final Context context) {
this(context, null);
}
public ThemePreviewPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemePreviewPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public ThemePreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
prefs.registerOnSharedPreferenceChangeListener(this);
}
public ThemePreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
if (KEY_THEME.equals(key) || KEY_THEME_BACKGROUND.equals(key) || KEY_THEME_COLOR.equals(key)) {
notifyChanged();
}
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
if (KEY_THEME.equals(key) || KEY_THEME_BACKGROUND.equals(key) || KEY_THEME_COLOR.equals(key)) {
notifyChanged();
}
}
@Override
protected View onCreateView(final ViewGroup parent) {
final Context context = getContext();
final int themeResource = ThemeUtils.getThemeResource(context);
final int accentColor = ThemeUtils.getUserAccentColor(context);
final Context theme = new TwidereContextThemeWrapper(context, themeResource, accentColor);
final LayoutInflater inflater = LayoutInflater.from(theme);
final View view = inflater.inflate(R.layout.theme_preview, parent, false);
setPreviewView(theme, view.findViewById(R.id.theme_preview_content), themeResource);
return view;
}
@Override
protected View onCreateView(final ViewGroup parent) {
final Context context = getContext();
final int themeResource = ThemeUtils.getThemeResource(context);
final Context theme = new ContextThemeWrapper(context, themeResource);
final LayoutInflater inflater = LayoutInflater.from(theme);
final View view = inflater.inflate(R.layout.theme_preview, parent, false);
setPreviewView(theme, view.findViewById(R.id.theme_preview_content), themeResource);
return view;
}
private static void setPreviewView(final Context context, final View view, final int themeRes) {
if (view instanceof IExtendedView) {
((IExtendedView) view).setTouchInterceptor(new DummyTouchInterceptor());
}
final View windowBackgroundView = view.findViewById(R.id.theme_preview_window_background);
final View windowContentOverlayView = view.findViewById(R.id.theme_preview_window_content_overlay);
final View actionBarView = view.findViewById(R.id.actionbar);
final TextView actionBarTitleView = (TextView) view.findViewById(R.id.actionbar_title);
final MenuBar actionBarSplitView = (MenuBar) view.findViewById(R.id.actionbar_split);
final View statusContentView = view.findViewById(R.id.theme_preview_status_content);
private static void setPreviewView(final Context context, final View view, final int themeRes) {
if (view instanceof IExtendedView) {
((IExtendedView) view).setTouchInterceptor(new DummyTouchInterceptor());
}
final View windowBackgroundView = view.findViewById(R.id.theme_preview_window_background);
final View windowContentOverlayView = view.findViewById(R.id.theme_preview_window_content_overlay);
final View actionBarView = view.findViewById(R.id.actionbar);
final TextView actionBarTitleView = (TextView) view.findViewById(R.id.actionbar_title);
final MenuBar actionBarSplitView = (MenuBar) view.findViewById(R.id.actionbar_split);
final View statusContentView = view.findViewById(R.id.theme_preview_status_content);
final int defaultTextSize = getDefaultTextSize(context);
final int titleTextAppearance = ThemeUtils.getTitleTextAppearance(context);
final int defaultTextSize = getDefaultTextSize(context);
final int titleTextAppearance = ThemeUtils.getTitleTextAppearance(context);
ViewAccessor.setBackground(windowBackgroundView, ThemeUtils.getWindowBackground(context));
ViewAccessor.setBackground(windowContentOverlayView, ThemeUtils.getWindowContentOverlay(context));
ViewAccessor.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes));
ViewAccessor.setBackground(actionBarSplitView, ThemeUtils.getActionBarSplitBackground(context, themeRes));
ViewAccessor.setBackground(windowBackgroundView, ThemeUtils.getWindowBackground(context));
ViewAccessor.setBackground(windowContentOverlayView, ThemeUtils.getWindowContentOverlay(context));
ViewAccessor.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes));
ViewAccessor.setBackground(actionBarSplitView, ThemeUtils.getActionBarSplitBackground(context, themeRes));
actionBarTitleView.setTextAppearance(context, titleTextAppearance);
actionBarSplitView.setEnabled(false);
actionBarSplitView.inflate(R.menu.menu_status);
actionBarSplitView.setIsBottomBar(true);
actionBarSplitView.show();
if (statusContentView != null) {
ViewAccessor.setBackground(statusContentView, ThemeUtils.getWindowBackground(context));
actionBarTitleView.setTextAppearance(context, titleTextAppearance);
actionBarSplitView.setEnabled(false);
actionBarSplitView.inflate(R.menu.menu_status);
actionBarSplitView.setIsBottomBar(true);
actionBarSplitView.show();
if (statusContentView != null) {
ViewAccessor.setBackground(statusContentView, ThemeUtils.getWindowBackground(context));
final ICardItemView cardView = (ICardItemView) statusContentView.findViewById(R.id.card);
final View profileView = statusContentView.findViewById(R.id.profile);
final ImageView profileImageView = (ImageView) statusContentView.findViewById(R.id.profile_image);
final TextView nameView = (TextView) statusContentView.findViewById(R.id.name);
final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name);
final TextView textView = (TextView) statusContentView.findViewById(R.id.text);
final TextView timeSourceView = (TextView) statusContentView.findViewById(R.id.time_source);
// final TextView retweetView = (TextView)
// statusContentView.findViewById(R.id.retweet_view);
final TextView repliesView = (TextView) statusContentView.findViewById(R.id.replies_view);
final ICardItemView cardView = (ICardItemView) statusContentView.findViewById(R.id.card);
final View profileView = statusContentView.findViewById(R.id.profile);
final ImageView profileImageView = (ImageView) statusContentView.findViewById(R.id.profile_image);
final TextView nameView = (TextView) statusContentView.findViewById(R.id.name);
final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name);
final TextView textView = (TextView) statusContentView.findViewById(R.id.text);
final TextView timeSourceView = (TextView) statusContentView.findViewById(R.id.time_source);
// final TextView retweetView = (TextView)
// statusContentView.findViewById(R.id.retweet_view);
final TextView repliesView = (TextView) statusContentView.findViewById(R.id.replies_view);
cardView.setItemSelector(null);
cardView.setItemSelector(null);
nameView.setTextSize(defaultTextSize * 1.25f);
textView.setTextSize(defaultTextSize * 1.25f);
screenNameView.setTextSize(defaultTextSize * 0.85f);
timeSourceView.setTextSize(defaultTextSize * 0.85f);
// retweetView.setTextSize(defaultTextSize * 0.85f);
repliesView.setTextSize(defaultTextSize * 0.85f);
nameView.setTextSize(defaultTextSize * 1.25f);
textView.setTextSize(defaultTextSize * 1.25f);
screenNameView.setTextSize(defaultTextSize * 0.85f);
timeSourceView.setTextSize(defaultTextSize * 0.85f);
// retweetView.setTextSize(defaultTextSize * 0.85f);
repliesView.setTextSize(defaultTextSize * 0.85f);
profileView.setBackgroundResource(0);
// retweetView.setBackgroundResource(0);
repliesView.setBackgroundResource(0);
textView.setTextIsSelectable(false);
profileView.setBackgroundResource(0);
// retweetView.setBackgroundResource(0);
repliesView.setBackgroundResource(0);
textView.setTextIsSelectable(false);
profileImageView.setImageResource(R.drawable.ic_launcher);
nameView.setText(TWIDERE_PREVIEW_NAME);
screenNameView.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
profileImageView.setImageResource(R.drawable.ic_launcher);
nameView.setText(TWIDERE_PREVIEW_NAME);
screenNameView.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
final String time = formatToLongTimeString(context, System.currentTimeMillis());
timeSourceView.setText(toPlainText(context.getString(R.string.time_source, time, TWIDERE_PREVIEW_SOURCE)));
}
}
final String time = formatToLongTimeString(context, System.currentTimeMillis());
timeSourceView.setText(toPlainText(context.getString(R.string.time_source, time, TWIDERE_PREVIEW_SOURCE)));
}
}
private static class DummyTouchInterceptor implements TouchInterceptor {
private static class DummyTouchInterceptor implements TouchInterceptor {
@Override
public boolean dispatchTouchEvent(final View view, final MotionEvent event) {
return false;
}
@Override
public boolean dispatchTouchEvent(final View view, final MotionEvent event) {
return false;
}
@Override
public boolean onInterceptTouchEvent(final View view, final MotionEvent event) {
return true;
}
@Override
public boolean onInterceptTouchEvent(final View view, final MotionEvent event) {
return true;
}
@Override
public boolean onTouchEvent(final View view, final MotionEvent event) {
return false;
}
@Override
public boolean onTouchEvent(final View view, final MotionEvent event) {
return false;
}
}
}
}

View File

@ -68,7 +68,7 @@ public class CustomTabUtils implements Constants {
HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false));
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_MENTIONS_TIMELINE, new CustomTabConfiguration(
MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_mention,
MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false,
ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.my_following_only, false)));
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_DIRECT_MESSAGES, new CustomTabConfiguration(
@ -112,7 +112,7 @@ public class CustomTabUtils implements Constants {
CUSTOM_TABS_ICON_NAME_MAP.put("heart", R.drawable.ic_action_heart);
CUSTOM_TABS_ICON_NAME_MAP.put("home", R.drawable.ic_action_home);
CUSTOM_TABS_ICON_NAME_MAP.put("list", R.drawable.ic_action_list);
CUSTOM_TABS_ICON_NAME_MAP.put("mention", R.drawable.ic_action_mention);
CUSTOM_TABS_ICON_NAME_MAP.put("mention", R.drawable.ic_action_at);
CUSTOM_TABS_ICON_NAME_MAP.put("message", R.drawable.ic_action_message);
CUSTOM_TABS_ICON_NAME_MAP.put("quote", R.drawable.ic_action_quote);
CUSTOM_TABS_ICON_NAME_MAP.put("search", R.drawable.ic_action_search);

View File

@ -35,7 +35,6 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.menu.AccountActionProvider;
import org.mariotaku.twidere.menu.TwidereMenuInflater;
import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
@ -194,7 +193,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
@Override
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
new TwidereMenuInflater(mActivity).inflate(R.menu.action_multi_select_contents, menu);
mode.getMenuInflater().inflate(R.menu.action_multi_select_contents, menu);
mAccountActionProvider = (AccountActionProvider) menu.findItem(MENU_SELECT_ACCOUNT).getActionProvider();
mAccountActionProvider.setAccountId(mMultiSelectManager.getFirstSelectAccountId());
return true;

View File

@ -38,21 +38,18 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import org.mariotaku.menucomponent.internal.Utils;
import org.mariotaku.menucomponent.widget.MenuBar.MenuBarMenuInfo;
import org.mariotaku.refreshnow.widget.RefreshNowConfig;
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator.IndicatorConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.content.TwidereContextThemeWrapper;
import org.mariotaku.twidere.content.TwidereContextWrapper;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
import org.mariotaku.twidere.util.menu.StatusMenuInfo;
import java.lang.reflect.Constructor;
@ -121,6 +118,16 @@ public class ThemeUtils implements Constants {
d.setAlpha(getUserThemeBackgroundAlpha(context));
}
public static void applyColorFilterToMenuIcon(Activity activity, Menu menu) {
final ActionBar actionBar = activity.getActionBar();
final Context context = actionBar != null ? actionBar.getThemedContext() : activity;
final int color = getThemeForegroundColor(context);
final int popupTheme = Utils.getActionBarPopupThemeRes(context);
final int popupColor = ThemeUtils.getThemeForegroundColor(context, popupTheme);
final int highlightColor = ThemeUtils.getUserAccentColor(activity);
ThemeUtils.applyColorFilterToMenuIcon(menu, color, popupColor, highlightColor, Mode.SRC_ATOP);
}
public static void applyColorFilterToMenuIcon(final Menu menu, final int color,
final int highlightColor, final Mode mode,
final int... excludedGroups) {
@ -154,7 +161,8 @@ public class ThemeUtils implements Constants {
}
}
if (item.hasSubMenu()) {
applyColorFilterToMenuIcon(item.getSubMenu(), color, popupColor, highlightColor, mode, excludedGroups);
// SubMenu item is always in popup
applyColorFilterToMenuIcon(item.getSubMenu(), popupColor, popupColor, highlightColor, mode, excludedGroups);
}
}
}
@ -221,8 +229,8 @@ public class ThemeUtils implements Constants {
} finally {
a.recycle();
}
if (resId == 0) return new TwidereContextWrapper(context);
return new TwidereContextThemeWrapper(context, resId, getUserAccentColor(context));
if (resId == 0) return context;
return new ContextThemeWrapper(context, resId);
}
@Deprecated
@ -320,7 +328,7 @@ public class ThemeUtils implements Constants {
}
public static Context getDialogThemedContext(final Context context) {
return new TwidereContextThemeWrapper(context, getDialogThemeResource(context), getThemeColor(context));
return new ContextThemeWrapper(context, getDialogThemeResource(context));
}
public static int getDialogThemeResource(final Context context) {
@ -493,45 +501,11 @@ public class ThemeUtils implements Constants {
}
public static Context getThemedContext(final Context context) {
return new TwidereContextWrapper(context, getResources(context));
return context;
}
public static Context getThemedContext(final Context context, final Resources res) {
return new TwidereContextWrapper(context, res);
}
public static Context getThemedContextForActionIcons(final Context context) {
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = getSettingsThemeResource(context);
accentColor = getUserAccentColor(context, themeRes);
}
return new TwidereContextThemeWrapper(context, getThemeResActionIcons(themeRes), accentColor);
}
public static Context getThemedContextForActionIcons(final Context baseContext, final int baseThemeRes) {
return new TwidereContextWrapper(baseContext, getThemeResActionIcons(baseThemeRes));
}
public static Context getThemedContextForActionIcons(final Context baseContext, final int baseThemeRes,
final int accentColor) {
return new TwidereContextThemeWrapper(baseContext, getThemeResActionIcons(baseThemeRes), accentColor);
}
public static LayoutInflater getThemedLayoutInflaterForActionIcons(final Context context) {
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = getSettingsThemeResource(context);
accentColor = getUserAccentColor(context);
}
final Context theme = getThemedContextForActionIcons(context, themeRes, accentColor);
return LayoutInflater.from(theme);
return context;
}
public static String getThemeFontFamily(final Context context) {
@ -554,16 +528,20 @@ public class ThemeUtils implements Constants {
}
public static int getThemeForegroundColor(final Context context) {
final Resources res = getResources(context);
final Context wrapped = getThemedContext(context, res);
return getThemeForegroundColor(context, 0);
}
public static int getThemeForegroundColor(final Context context, int theme) {
final Context wrapped = theme != 0 ? new ContextThemeWrapper(context, theme) : context;
final TypedArray a = wrapped.obtainStyledAttributes(new int[]{android.R.attr.colorForeground});
try {
return a.getColor(0, Color.GRAY);
return a.getColor(0, 0);
} finally {
a.recycle();
}
}
@NonNull
private static SharedPreferencesWrapper getSharedPreferencesWrapper(Context context) {
final Context appContext = context.getApplicationContext();
@ -577,15 +555,6 @@ public class ThemeUtils implements Constants {
return pref.getString(KEY_THEME, VALUE_THEME_NAME_TWIDERE);
}
public static int getThemeResActionIcons(final int baseThemeRes) {
switch (baseThemeRes) {
case R.style.Theme_Twidere_Settings_Light_DarkActionBar: {
return R.style.Theme_Twidere_Settings_Light_DarkActionBar_DarkIcon;
}
}
return baseThemeRes;
}
public static int getThemeResource(final Context context) {
return getThemeResource(getThemeNameOption(context), getThemeBackgroundOption(context),
getDarkActionBarOption(context));
@ -636,6 +605,7 @@ public class ThemeUtils implements Constants {
return Color.HSVToColor(hsv);
}
public static int getUserThemeBackgroundAlpha(final Context context) {
if (context == null) return DEFAULT_THEME_BACKGROUND_ALPHA;
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
@ -713,8 +683,6 @@ public class ThemeUtils implements Constants {
}
public static boolean isDarkTheme(final Context context) {
if (context instanceof ITwidereContextWrapper)
return isDarkTheme(((ITwidereContextWrapper) context).getThemeResourceId());
return isDarkTheme(getThemeResource(context));
}
@ -860,10 +828,6 @@ public class ThemeUtils implements Constants {
return defaultValue;
}
public static Resources getThemedResourcesForActionIcons(Context context, int themeRes, int accentColor) {
return getThemedContextForActionIcons(context, themeRes, accentColor).getResources();
}
public static int getThemeColor(Context context, int themeResourceId) {
final Context appContext = context.getApplicationContext();
final Resources res = appContext.getResources();

View File

@ -41,7 +41,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
@ -115,7 +115,6 @@ import org.mariotaku.twidere.activity.CameraCropActivity;
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.support.DirectMessagesConversationFragment;
import org.mariotaku.twidere.fragment.support.IncomingFriendshipsFragment;
@ -396,16 +395,10 @@ public final class Utils implements Constants, TwitterConstants {
final MenuItem item = menu.add(groupId, Menu.NONE, Menu.NONE, info.loadLabel(pm));
item.setIntent(intent);
final Drawable metaDataDrawable = getMetadataDrawable(pm, info.activityInfo, METADATA_KEY_EXTENSION_ICON);
int actionIconColor;
if (context instanceof ITwidereContextWrapper) {
final int themeResId = ((ITwidereContextWrapper) context).getThemeResourceId();
actionIconColor = ThemeUtils.getActionIconColor(themeResId);
} else {
actionIconColor = ThemeUtils.getActionIconColor(context);
}
final int actionIconColor = ThemeUtils.getThemeForegroundColor(context);
if (metaDataDrawable != null) {
metaDataDrawable.mutate();
metaDataDrawable.setColorFilter(actionIconColor, PorterDuff.Mode.MULTIPLY);
metaDataDrawable.setColorFilter(actionIconColor, Mode.SRC_ATOP);
item.setIcon(metaDataDrawable);
} else {
final Drawable icon = info.loadIcon(pm);
@ -2428,7 +2421,6 @@ public final class Utils implements Constants, TwitterConstants {
cb.setHttpClientFactory(new TwidereHttpClientFactory(app));
}
cb.setHttpConnectionTimeout(connection_timeout);
setUserAgent(context, cb);
cb.setGZIPEnabled(enableGzip);
cb.setIgnoreSSLError(ignoreSslError);
if (enableProxy) {
@ -2455,6 +2447,12 @@ public final class Utils implements Constants, TwitterConstants {
cb.setSigningUploadBaseURL(DEFAULT_SIGNING_UPLOAD_BASE_URL);
}
}
if (isOfficialConsumerKeySecret(context, consumerKey, consumerSecret)) {
setMockOfficialUserAgent(context, cb);
} else {
setUserAgent(context, cb);
}
cb.setIncludeEntitiesEnabled(includeEntities);
cb.setIncludeRTsEnabled(includeRetweets);
switch (c.getInt(c.getColumnIndexOrThrow(Accounts.AUTH_TYPE))) {
@ -3492,7 +3490,7 @@ public final class Utils implements Constants, TwitterConstants {
public static void setUserAgent(final Context context, final ConfigurationBuilder cb) {
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final boolean gzip_compressing = prefs.getBoolean(KEY_GZIP_COMPRESSING, true);
final boolean gzipCompressing = prefs.getBoolean(KEY_GZIP_COMPRESSING, true);
final PackageManager pm = context.getPackageManager();
try {
final PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
@ -3501,12 +3499,30 @@ public final class Utils implements Constants, TwitterConstants {
cb.setClientName(APP_NAME);
cb.setClientURL(APP_PROJECT_URL);
cb.setHttpUserAgent(APP_NAME + " " + APP_PROJECT_URL + " / " + version_name
+ (gzip_compressing ? " (gzip)" : ""));
+ (gzipCompressing ? " (gzip)" : ""));
} catch (final PackageManager.NameNotFoundException e) {
}
}
/**
* User-Agent format of official client:
* TwitterAndroid/[versionName] ([versionCode]-[buildName]-[r|d)]-[buildNumber]) [deviceInfo]
*
* @param context
* @param cb
*/
public static void setMockOfficialUserAgent(final Context context, final ConfigurationBuilder cb) {
cb.setClientVersion("5.32.0");
cb.setClientName("TwitterAndroid");
cb.setClientURL(null);
final String deviceInfo = String.format(Locale.ROOT, "%s/%s (%s;%s;%s;%s;)",
Build.MODEL, Build.VERSION.RELEASE, Build.MANUFACTURER, Build.MODEL, Build.BRAND,
Build.PRODUCT);
cb.setHttpUserAgent(String.format(Locale.ROOT, "TwitterAndroid/%s (%d-%c-%d) %s",
"5.32.0", 3030745, 'r', 692, deviceInfo));
}
public static boolean shouldEnableFiltersForRTs(final Context context) {
if (context == null) return false;
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
@ -3765,10 +3781,10 @@ public final class Utils implements Constants, TwitterConstants {
}
public static boolean truncateStatuses(final List<twitter4j.Status> in, final List<twitter4j.Status> out,
final long since_id) {
final long sinceId) {
if (in == null) return false;
for (final twitter4j.Status status : in) {
if (since_id > 0 && status.getId() <= since_id) {
if (sinceId > 0 && status.getId() <= sinceId) {
continue;
}
out.add(status);

View File

@ -1,60 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util.theme;
import android.content.Context;
import android.content.res.Resources;
import org.mariotaku.twidere.content.res.NoAccentResources;
public class TwidereResourceHelper {
private final int mOverrideThemeRes;
private NoAccentResources mResources;
private OnInitListener mInitListener;
public TwidereResourceHelper(final int overrideThemeRes, OnInitListener listener) {
mOverrideThemeRes = overrideThemeRes;
mInitListener = listener;
}
public Resources getResources(final Context c, final Resources resources) {
if (mResources != null) return mResources;
mResources = new NoAccentResources(c, resources);
if (mInitListener != null)
mInitListener.onInitResources(mResources);
return mResources;
}
/**
* Set a listener to be notified when the instance of AccentResources is created.
*
* @param listener The actual listener or null to disable any event reporting.
*/
public void setOnInitListener(OnInitListener listener) {
mInitListener = listener;
}
public interface OnInitListener {
public void onInitResources(NoAccentResources resources);
}
}

View File

@ -26,39 +26,34 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import org.mariotaku.twidere.content.iface.ITwidereContextWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
public class ActionBarSplitThemedContainer extends FrameLayout {
public ActionBarSplitThemedContainer(final Context context) {
this(context, null);
}
public ActionBarSplitThemedContainer(final Context context) {
this(context, null);
}
public ActionBarSplitThemedContainer(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionBarSplitThemedContainer(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionBarSplitThemedContainer(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.layout });
final int resId = a.getResourceId(0, 0);
a.recycle();
if (resId == 0) throw new IllegalArgumentException("You must specify a layout resource in layout XML file.");
final View view = LayoutInflater.from(getThemedContext(context)).inflate(resId, this, false);
final int themeResId;
if (context instanceof ITwidereContextWrapper) {
themeResId = ((ITwidereContextWrapper) context).getThemeResourceId();
} else {
themeResId = ThemeUtils.getThemeResource(context);
}
ViewAccessor.setBackground(view, ThemeUtils.getActionBarSplitBackground(context, themeResId));
addView(view);
}
public ActionBarSplitThemedContainer(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.layout});
final int resId = a.getResourceId(0, 0);
a.recycle();
if (resId == 0)
throw new IllegalArgumentException("You must specify a layout resource in layout XML file.");
final View view = LayoutInflater.from(getThemedContext(context)).inflate(resId, this, false);
final int themeResId = ThemeUtils.getThemeResource(context);
ViewAccessor.setBackground(view, ThemeUtils.getActionBarSplitBackground(context, themeResId));
addView(view);
}
private static Context getThemedContext(final Context context) {
return ThemeUtils.getActionBarContext(context);
}
private static Context getThemedContext(final Context context) {
return ThemeUtils.getActionBarContext(context);
}
}

View File

@ -9,10 +9,12 @@ import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.view.iface.PagerIndicator;
@ -110,7 +112,7 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
}
public void setBadge(int position, int count) {
mIndicatorAdapter.setBadge(position, count);
}
public void setDisplayLabel(boolean display) {
@ -137,17 +139,24 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
mIndicatorAdapter.setItemContext(context);
}
public void setDisplayBadge(boolean display) {
mIndicatorAdapter.setDisplayBadge(display);
}
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> implements OnClickListener, OnLongClickListener {
private final TabPagerIndicator mIndicator;
private final SparseIntArray mUnreadCounts;
private Context mItemContext;
private LayoutInflater mInflater;
private TabProvider mTabProvider;
private int mStripColor, mIconColor;
private boolean mDisplayBadge;
public TabPagerIndicatorAdapter(TabPagerIndicator indicator) {
mIndicator = indicator;
mUnreadCounts = new SparseIntArray();
}
@Override
@ -169,6 +178,7 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
holder.setTabData(position, icon, title, mIndicator.getCurrentItem() == position);
holder.setStripColor(mStripColor);
holder.setIconColor(mIconColor);
holder.setBadge(mUnreadCounts.get(position, 0), mDisplayBadge);
}
@Override
@ -214,6 +224,16 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
public Context getItemContext() {
return mItemContext;
}
public void setBadge(int position, int count) {
mUnreadCounts.put(position, count);
notifyDataSetChanged();
}
public void setDisplayBadge(boolean display) {
mDisplayBadge = display;
notifyDataSetChanged();
}
}
private void dispatchTabClick(int position) {
@ -244,12 +264,14 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
private final View itemView;
private final ImageView iconView;
private final View selectedIndicator;
private final TextView badgeView;
public TabItemHolder(View itemView) {
super(itemView);
this.itemView = itemView;
selectedIndicator = itemView.findViewById(R.id.selected_indicator);
iconView = (ImageView) itemView.findViewById(R.id.tab_icon);
badgeView = (TextView) itemView.findViewById(R.id.unread_indicator);
}
@ -268,6 +290,11 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
public void setIconColor(int color) {
iconView.setColorFilter(color);
}
public void setBadge(int count, boolean display) {
badgeView.setText(String.valueOf(count));
badgeView.setVisibility(display && count > 0 ? VISIBLE : GONE);
}
}
public static class TabLayoutManager extends LinearLayoutManager {

View File

@ -0,0 +1,36 @@
/*
* Copyright 2007 Yusuke Yamamoto
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package twitter4j;
import java.io.Serializable;
/**
* @author Mariotaku Lee
* @since Twitter4J 2.2.5
*/
public interface ExtendedEntitySupport extends EntitySupport {
/**
* Returns an array of MediaEntities if medias are available in the tweet,
* or null if no media is included in the tweet.
*
* @return an array of MediaEntities.
* @since Twitter4J 2.2.3
*/
MediaEntity[] getExtendedMediaEntities();
}

View File

@ -24,7 +24,7 @@ import java.util.Date;
*
* @author Yusuke Yamamoto - yusuke at mac.com
*/
public interface Status extends Comparable<Status>, TwitterResponse, EntitySupport, Serializable {
public interface Status extends Comparable<Status>, TwitterResponse, ExtendedEntitySupport, Serializable {
/**
* Returns an array of contributors, or null if no contributor is associated

View File

@ -16,17 +16,13 @@
package twitter4j.internal.json;
import static twitter4j.internal.util.InternalParseUtil.getBoolean;
import static twitter4j.internal.util.InternalParseUtil.getDate;
import static twitter4j.internal.util.InternalParseUtil.getHTMLUnescapedString;
import static twitter4j.internal.util.InternalParseUtil.getLong;
import static twitter4j.internal.util.InternalParseUtil.getRawString;
import static twitter4j.internal.util.InternalParseUtil.getUnescapedString;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.Date;
import twitter4j.GeoLocation;
import twitter4j.HashtagEntity;
import twitter4j.MediaEntity;
@ -41,424 +37,450 @@ import twitter4j.conf.Configuration;
import twitter4j.http.HttpResponse;
import twitter4j.internal.logging.Logger;
import java.util.Arrays;
import java.util.Date;
import static twitter4j.internal.util.InternalParseUtil.getBoolean;
import static twitter4j.internal.util.InternalParseUtil.getDate;
import static twitter4j.internal.util.InternalParseUtil.getHTMLUnescapedString;
import static twitter4j.internal.util.InternalParseUtil.getLong;
import static twitter4j.internal.util.InternalParseUtil.getRawString;
import static twitter4j.internal.util.InternalParseUtil.getUnescapedString;
/**
* A data class representing one single status of a user.
*
*
* @author Yusuke Yamamoto - yusuke at mac.com
*/
final class StatusJSONImpl extends TwitterResponseImpl implements Status {
/**
*
*/
private static final long serialVersionUID = 8982739445731837548L;
/**
*
*/
private static final long serialVersionUID = 8982739445731837548L;
private static final Logger logger = Logger.getLogger(StatusJSONImpl.class);
private static final Logger logger = Logger.getLogger(StatusJSONImpl.class);
private Date createdAt;
private long id;
private String text;
private String rawText;
private String source;
private boolean isTruncated;
private long inReplyToStatusId;
private long inReplyToUserId;
private long currentUserRetweet;
private boolean isFavorited;
private String inReplyToScreenName;
private GeoLocation geoLocation = null;
private Place place = null;
private long retweetCount;
private long favoriteCount;
private boolean wasRetweetedByMe;
private boolean isPossiblySensitive;
private Date createdAt;
private long id;
private String text;
private String rawText;
private String source;
private boolean isTruncated;
private long inReplyToStatusId;
private long inReplyToUserId;
private long currentUserRetweet;
private boolean isFavorited;
private String inReplyToScreenName;
private GeoLocation geoLocation = null;
private Place place = null;
private long retweetCount;
private long favoriteCount;
private boolean wasRetweetedByMe;
private boolean isPossiblySensitive;
private String[] contributors = null;
private long[] contributorsIDs;
private String[] contributors = null;
private long[] contributorsIDs;
private Status retweetedStatus;
private UserMentionEntity[] userMentionEntities;
private URLEntity[] urlEntities;
private HashtagEntity[] hashtagEntities;
private MediaEntity[] mediaEntities;
private Status retweetedStatus;
private UserMentionEntity[] userMentionEntities;
private URLEntity[] urlEntities;
private HashtagEntity[] hashtagEntities;
private MediaEntity[] mediaEntities;
private MediaEntity[] extendedMediaEntities;
private User user = null;
private User user = null;
/* package */StatusJSONImpl(final HttpResponse res, final Configuration conf) throws TwitterException {
super(res);
final JSONObject json = res.asJSONObject();
init(json);
}
/* package */StatusJSONImpl(final HttpResponse res, final Configuration conf) throws TwitterException {
super(res);
final JSONObject json = res.asJSONObject();
init(json);
}
/* package */StatusJSONImpl(final JSONObject json) throws TwitterException {
super();
init(json);
}
/* package */StatusJSONImpl(final JSONObject json) throws TwitterException {
super();
init(json);
}
@Override
public int compareTo(final Status that) {
final long delta = id - that.getId();
if (delta < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
else if (delta > Integer.MAX_VALUE) return Integer.MAX_VALUE;
return (int) delta;
}
@Override
public int compareTo(final Status that) {
final long delta = id - that.getId();
if (delta < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
else if (delta > Integer.MAX_VALUE) return Integer.MAX_VALUE;
return (int) delta;
}
@Override
public boolean equals(final Object obj) {
if (null == obj) return false;
if (this == obj) return true;
return obj instanceof Status && ((Status) obj).getId() == id;
}
@Override
public boolean equals(final Object obj) {
if (null == obj) return false;
if (this == obj) return true;
return obj instanceof Status && ((Status) obj).getId() == id;
}
/**
* {@inheritDoc}
*/
@Override
public long[] getContributors() {
if (contributors != null) {
// http://twitter4j.org/jira/browse/TFJ-592
// preserving serialized form compatibility with older versions
contributorsIDs = new long[contributors.length];
for (int i = 0; i < contributors.length; i++) {
try {
contributorsIDs[i] = Long.parseLong(contributors[i]);
} catch (final NumberFormatException nfe) {
nfe.printStackTrace();
logger.warn("failed to parse contributors:" + nfe);
}
}
contributors = null;
}
return contributorsIDs;
}
/**
* {@inheritDoc}
*/
@Override
public long[] getContributors() {
if (contributors != null) {
// http://twitter4j.org/jira/browse/TFJ-592
// preserving serialized form compatibility with older versions
contributorsIDs = new long[contributors.length];
for (int i = 0; i < contributors.length; i++) {
try {
contributorsIDs[i] = Long.parseLong(contributors[i]);
} catch (final NumberFormatException nfe) {
nfe.printStackTrace();
logger.warn("failed to parse contributors:" + nfe);
}
}
contributors = null;
}
return contributorsIDs;
}
/**
* {@inheritDoc}
*/
@Override
public Date getCreatedAt() {
return createdAt;
}
/**
* {@inheritDoc}
*/
@Override
public Date getCreatedAt() {
return createdAt;
}
@Override
public long getCurrentUserRetweet() {
return currentUserRetweet;
}
@Override
public long getCurrentUserRetweet() {
return currentUserRetweet;
}
@Override
public long getFavoriteCount() {
return favoriteCount;
}
@Override
public long getFavoriteCount() {
return favoriteCount;
}
/**
* {@inheritDoc}
*/
@Override
public GeoLocation getGeoLocation() {
return geoLocation;
}
/**
* {@inheritDoc}
*/
@Override
public GeoLocation getGeoLocation() {
return geoLocation;
}
/**
* {@inheritDoc}
*/
@Override
public HashtagEntity[] getHashtagEntities() {
return hashtagEntities;
}
/**
* {@inheritDoc}
*/
@Override
public HashtagEntity[] getHashtagEntities() {
return hashtagEntities;
}
/**
* {@inheritDoc}
*/
@Override
public long getId() {
return id;
}
/**
* {@inheritDoc}
*/
@Override
public long getId() {
return id;
}
/**
* {@inheritDoc}
*/
@Override
public String getInReplyToScreenName() {
return inReplyToScreenName;
}
/**
* {@inheritDoc}
*/
@Override
public String getInReplyToScreenName() {
return inReplyToScreenName;
}
/**
* {@inheritDoc}
*/
@Override
public long getInReplyToStatusId() {
return inReplyToStatusId;
}
/**
* {@inheritDoc}
*/
@Override
public long getInReplyToStatusId() {
return inReplyToStatusId;
}
/**
* {@inheritDoc}
*/
@Override
public long getInReplyToUserId() {
return inReplyToUserId;
}
/**
* {@inheritDoc}
*/
@Override
public long getInReplyToUserId() {
return inReplyToUserId;
}
/**
* {@inheritDoc}
*/
@Override
public MediaEntity[] getMediaEntities() {
return mediaEntities;
}
/**
* {@inheritDoc}
*/
@Override
public MediaEntity[] getMediaEntities() {
return mediaEntities;
}
/**
* {@inheritDoc}
*/
@Override
public Place getPlace() {
return place;
}
/**
* {@inheritDoc}
*/
@Override
public Place getPlace() {
return place;
}
@Override
public String getRawText() {
return rawText;
}
@Override
public String getRawText() {
return rawText;
}
/**
* {@inheritDoc}
*/
@Override
public long getRetweetCount() {
return retweetCount;
}
/**
* {@inheritDoc}
*/
@Override
public long getRetweetCount() {
return retweetCount;
}
/**
* {@inheritDoc}
*/
@Override
public Status getRetweetedStatus() {
return retweetedStatus;
}
/**
* {@inheritDoc}
*/
@Override
public Status getRetweetedStatus() {
return retweetedStatus;
}
/**
* {@inheritDoc}
*/
@Override
public String getSource() {
return source;
}
/**
* {@inheritDoc}
*/
@Override
public String getSource() {
return source;
}
/**
* {@inheritDoc}
*/
@Override
public String getText() {
return text;
}
/**
* {@inheritDoc}
*/
@Override
public String getText() {
return text;
}
/**
* {@inheritDoc}
*/
@Override
public URLEntity[] getURLEntities() {
return urlEntities;
}
/**
* {@inheritDoc}
*/
@Override
public URLEntity[] getURLEntities() {
return urlEntities;
}
/**
* {@inheritDoc}
*/
@Override
public User getUser() {
return user;
}
/**
* {@inheritDoc}
*/
@Override
public User getUser() {
return user;
}
/**
* {@inheritDoc}
*/
@Override
public UserMentionEntity[] getUserMentionEntities() {
return userMentionEntities;
}
/**
* {@inheritDoc}
*/
@Override
public UserMentionEntity[] getUserMentionEntities() {
return userMentionEntities;
}
@Override
public int hashCode() {
return (int) id;
}
@Override
public int hashCode() {
return (int) id;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isFavorited() {
return isFavorited;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isFavorited() {
return isFavorited;
}
@Override
public boolean isPossiblySensitive() {
return isPossiblySensitive;
}
@Override
public boolean isPossiblySensitive() {
return isPossiblySensitive;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRetweet() {
return retweetedStatus != null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRetweet() {
return retweetedStatus != null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRetweetedByMe() {
return wasRetweetedByMe;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isRetweetedByMe() {
return wasRetweetedByMe;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isTruncated() {
return isTruncated;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isTruncated() {
return isTruncated;
}
@Override
public String toString() {
return "StatusJSONImpl{createdAt=" + createdAt + ", id=" + id + ", text=" + text + ", rawText=" + rawText
+ ", source=" + source + ", isTruncated=" + isTruncated + ", inReplyToStatusId=" + inReplyToStatusId
+ ", inReplyToUserId=" + inReplyToUserId + ", currentUserRetweet=" + currentUserRetweet
+ ", isFavorited=" + isFavorited + ", inReplyToScreenName=" + inReplyToScreenName + ", geoLocation="
+ geoLocation + ", place=" + place + ", retweetCount=" + retweetCount + ", wasRetweetedByMe="
+ wasRetweetedByMe + ", isPossiblySensitive=" + isPossiblySensitive + ", contributors="
+ Arrays.toString(contributors) + ", contributorsIDs=" + Arrays.toString(contributorsIDs)
+ ", retweetedStatus=" + retweetedStatus + ", userMentionEntities="
+ Arrays.toString(userMentionEntities) + ", urlEntities=" + Arrays.toString(urlEntities)
+ ", hashtagEntities=" + Arrays.toString(hashtagEntities) + ", mediaEntities="
+ Arrays.toString(mediaEntities) + ", user=" + user + "}";
}
@Override
public String toString() {
return "StatusJSONImpl{createdAt=" + createdAt + ", id=" + id + ", text=" + text + ", rawText=" + rawText
+ ", source=" + source + ", isTruncated=" + isTruncated + ", inReplyToStatusId=" + inReplyToStatusId
+ ", inReplyToUserId=" + inReplyToUserId + ", currentUserRetweet=" + currentUserRetweet
+ ", isFavorited=" + isFavorited + ", inReplyToScreenName=" + inReplyToScreenName + ", geoLocation="
+ geoLocation + ", place=" + place + ", retweetCount=" + retweetCount + ", wasRetweetedByMe="
+ wasRetweetedByMe + ", isPossiblySensitive=" + isPossiblySensitive + ", contributors="
+ Arrays.toString(contributors) + ", contributorsIDs=" + Arrays.toString(contributorsIDs)
+ ", retweetedStatus=" + retweetedStatus + ", userMentionEntities="
+ Arrays.toString(userMentionEntities) + ", urlEntities=" + Arrays.toString(urlEntities)
+ ", hashtagEntities=" + Arrays.toString(hashtagEntities) + ", mediaEntities="
+ Arrays.toString(mediaEntities) + ", user=" + user + "}";
}
private void init(final JSONObject json) throws TwitterException {
id = getLong("id", json);
rawText = getRawString("text", json);
text = getUnescapedString("text", json);
source = getHTMLUnescapedString("source", json);
createdAt = getDate("created_at", json);
isTruncated = getBoolean("truncated", json);
inReplyToStatusId = getLong("in_reply_to_status_id", json);
inReplyToUserId = getLong("in_reply_to_user_id", json);
isFavorited = getBoolean("favorited", json);
inReplyToScreenName = getHTMLUnescapedString("in_reply_to_screen_name", json);
isPossiblySensitive = getBoolean("possibly_sensitive", json);
retweetCount = getLong("retweet_count", json);
favoriteCount = getLong("favorite_count", json);
try {
if (!json.isNull("user")) {
user = new UserJSONImpl(json.getJSONObject("user"));
}
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
}
geoLocation = InternalJSONFactoryImpl.createGeoLocation(json);
if (!json.isNull("place")) {
try {
place = new PlaceJSONImpl(json.getJSONObject("place"));
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse place:" + json);
}
}
private void init(final JSONObject json) throws TwitterException {
id = getLong("id", json);
rawText = getRawString("text", json);
text = getUnescapedString("text", json);
source = getHTMLUnescapedString("source", json);
createdAt = getDate("created_at", json);
isTruncated = getBoolean("truncated", json);
inReplyToStatusId = getLong("in_reply_to_status_id", json);
inReplyToUserId = getLong("in_reply_to_user_id", json);
isFavorited = getBoolean("favorited", json);
inReplyToScreenName = getHTMLUnescapedString("in_reply_to_screen_name", json);
isPossiblySensitive = getBoolean("possibly_sensitive", json);
retweetCount = getLong("retweet_count", json);
favoriteCount = getLong("favorite_count", json);
try {
if (!json.isNull("user")) {
user = new UserJSONImpl(json.getJSONObject("user"));
}
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
}
geoLocation = InternalJSONFactoryImpl.createGeoLocation(json);
if (!json.isNull("place")) {
try {
place = new PlaceJSONImpl(json.getJSONObject("place"));
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse place:" + json);
}
}
if (!json.isNull("retweeted_status")) {
try {
retweetedStatus = new StatusJSONImpl(json.getJSONObject("retweeted_status"));
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse retweeted_status:" + json);
}
}
if (!json.isNull("contributors")) {
try {
final JSONArray contributorsArray = json.getJSONArray("contributors");
contributorsIDs = new long[contributorsArray.length()];
for (int i = 0; i < contributorsArray.length(); i++) {
contributorsIDs[i] = Long.parseLong(contributorsArray.getString(i));
}
} catch (final NumberFormatException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse contributors:" + json);
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse contributors:" + json);
}
} else {
contributors = null;
}
if (!json.isNull("entities")) {
try {
final JSONObject entities = json.getJSONObject("entities");
int len;
if (!entities.isNull("user_mentions")) {
final JSONArray userMentionsArray = entities.getJSONArray("user_mentions");
len = userMentionsArray.length();
userMentionEntities = new UserMentionEntity[len];
for (int i = 0; i < len; i++) {
userMentionEntities[i] = new UserMentionEntityJSONImpl(userMentionsArray.getJSONObject(i));
}
}
if (!entities.isNull("urls")) {
final JSONArray urlsArray = entities.getJSONArray("urls");
len = urlsArray.length();
urlEntities = new URLEntity[len];
for (int i = 0; i < len; i++) {
urlEntities[i] = new URLEntityJSONImpl(urlsArray.getJSONObject(i));
}
}
if (!entities.isNull("hashtags")) {
final JSONArray hashtagsArray = entities.getJSONArray("hashtags");
len = hashtagsArray.length();
hashtagEntities = new HashtagEntity[len];
for (int i = 0; i < len; i++) {
hashtagEntities[i] = new HashtagEntityJSONImpl(hashtagsArray.getJSONObject(i));
}
}
if (!entities.isNull("media")) {
final JSONArray mediaArray = entities.getJSONArray("media");
len = mediaArray.length();
mediaEntities = new MediaEntity[len];
for (int i = 0; i < len; i++) {
mediaEntities[i] = new MediaEntityJSONImpl(mediaArray.getJSONObject(i));
}
}
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
}
}
if (!json.isNull("current_user_retweet")) {
try {
currentUserRetweet = getLong("id", json.getJSONObject("current_user_retweet"));
wasRetweetedByMe = currentUserRetweet > 0;
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse current_user_retweet:" + json);
}
}
}
if (!json.isNull("retweeted_status")) {
try {
retweetedStatus = new StatusJSONImpl(json.getJSONObject("retweeted_status"));
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse retweeted_status:" + json);
}
}
if (!json.isNull("contributors")) {
try {
final JSONArray contributorsArray = json.getJSONArray("contributors");
contributorsIDs = new long[contributorsArray.length()];
for (int i = 0; i < contributorsArray.length(); i++) {
contributorsIDs[i] = Long.parseLong(contributorsArray.getString(i));
}
} catch (final NumberFormatException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse contributors:" + json);
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse contributors:" + json);
}
} else {
contributors = null;
}
if (!json.isNull("entities")) {
try {
final JSONObject entities = json.getJSONObject("entities");
int len;
if (!entities.isNull("user_mentions")) {
final JSONArray userMentionsArray = entities.getJSONArray("user_mentions");
len = userMentionsArray.length();
userMentionEntities = new UserMentionEntity[len];
for (int i = 0; i < len; i++) {
userMentionEntities[i] = new UserMentionEntityJSONImpl(userMentionsArray.getJSONObject(i));
}
}
if (!entities.isNull("urls")) {
final JSONArray urlsArray = entities.getJSONArray("urls");
len = urlsArray.length();
urlEntities = new URLEntity[len];
for (int i = 0; i < len; i++) {
urlEntities[i] = new URLEntityJSONImpl(urlsArray.getJSONObject(i));
}
}
if (!entities.isNull("hashtags")) {
final JSONArray hashtagsArray = entities.getJSONArray("hashtags");
len = hashtagsArray.length();
hashtagEntities = new HashtagEntity[len];
for (int i = 0; i < len; i++) {
hashtagEntities[i] = new HashtagEntityJSONImpl(hashtagsArray.getJSONObject(i));
}
}
if (!entities.isNull("media")) {
final JSONArray mediaArray = entities.getJSONArray("media");
len = mediaArray.length();
mediaEntities = new MediaEntity[len];
for (int i = 0; i < len; i++) {
mediaEntities[i] = new MediaEntityJSONImpl(mediaArray.getJSONObject(i));
}
}
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
}
}
if (!json.isNull("extended_entities")) {
try {
final JSONObject entities = json.getJSONObject("extended_entities");
if (!entities.isNull("media")) {
int len;
final JSONArray mediaArray = entities.getJSONArray("media");
len = mediaArray.length();
extendedMediaEntities = new MediaEntity[len];
for (int i = 0; i < len; i++) {
extendedMediaEntities[i] = new MediaEntityJSONImpl(mediaArray.getJSONObject(i));
}
}
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
}
}
if (!json.isNull("current_user_retweet")) {
try {
currentUserRetweet = getLong("id", json.getJSONObject("current_user_retweet"));
wasRetweetedByMe = currentUserRetweet > 0;
} catch (final JSONException ignore) {
ignore.printStackTrace();
logger.warn("failed to parse current_user_retweet:" + json);
}
}
}
/* package */
static ResponseList<Status> createStatusList(final HttpResponse res, final Configuration conf)
throws TwitterException {
try {
final JSONArray list = res.asJSONArray();
final int size = list.length();
final ResponseList<Status> statuses = new ResponseListImpl<Status>(size, res);
for (int i = 0; i < size; i++) {
final JSONObject json = list.getJSONObject(i);
final Status status = new StatusJSONImpl(json);
statuses.add(status);
}
return statuses;
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
} catch (final TwitterException te) {
throw te;
}
}
/* package */
static ResponseList<Status> createStatusList(final HttpResponse res, final Configuration conf)
throws TwitterException {
try {
final JSONArray list = res.asJSONArray();
final int size = list.length();
final ResponseList<Status> statuses = new ResponseListImpl<Status>(size, res);
for (int i = 0; i < size; i++) {
final JSONObject json = list.getJSONObject(i);
final Status status = new StatusJSONImpl(json);
statuses.add(status);
}
return statuses;
} catch (final JSONException jsone) {
throw new TwitterException(jsone);
} catch (final TwitterException te) {
throw te;
}
}
@Override
public MediaEntity[] getExtendedMediaEntities() {
return extendedMediaEntities;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 B

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 389 B

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

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