improved some settings

fixed #13
added credits
This commit is contained in:
Mariotaku Lee 2014-11-09 13:02:43 +08:00
parent 73a607df6a
commit f1db4e6ca7
59 changed files with 2918 additions and 1936 deletions

View File

@ -274,6 +274,9 @@
<data
android:host="user_timeline"
android:scheme="twidere"/>
<data
android:host="user_media_timeline"
android:scheme="twidere"/>
<data
android:host="user_favorites"
android:scheme="twidere"/>

View File

@ -118,6 +118,7 @@ public interface Constants extends TwidereConstants {
public static final int LINK_ID_USER_FOLLOWERS = 5;
public static final int LINK_ID_USER_FRIENDS = 6;
public static final int LINK_ID_USER_BLOCKS = 7;
public static final int LINK_ID_USER_MEDIA_TIMELINE = 8;
public static final int LINK_ID_DIRECT_MESSAGES_CONVERSATION = 9;
public static final int LINK_ID_USER_LIST = 10;
public static final int LINK_ID_USER_LISTS = 11;

View File

@ -65,6 +65,7 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
public static final String AUTHORITY_USER = "user";
public static final String AUTHORITY_USERS = "users";
public static final String AUTHORITY_USER_TIMELINE = "user_timeline";
public static final String AUTHORITY_USER_MEDIA_TIMELINE = "user_media_timeline";
public static final String AUTHORITY_USER_FAVORITES = "user_favorites";
public static final String AUTHORITY_USER_FOLLOWERS = "user_followers";
public static final String AUTHORITY_USER_FRIENDS = "user_friends";

View File

@ -80,11 +80,6 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
return ThemeUtils.getSettingsThemeResource(this);
}
@Override
public boolean isDarkDrawerEnabled() {
return false;
}
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);

View File

@ -84,11 +84,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
@Override
public abstract int getThemeResourceId();
@Override
public boolean isDarkDrawerEnabled() {
return false;
}
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);

View File

@ -64,8 +64,6 @@ public class SettingsActivity extends BasePreferenceActivity {
private String mCurrentThemeFontFamily;
private boolean mCurrentIsDarkDrawerEnabled;
@Override
public void finish() {
if (shouldNotifyThemeChange()) {
@ -183,7 +181,6 @@ public class SettingsActivity extends BasePreferenceActivity {
mCurrentThemeColor = ThemeUtils.getUserAccentColor(this);
mCurrentThemeFontFamily = getThemeFontFamily();
mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha();
mCurrentIsDarkDrawerEnabled = isDarkDrawerEnabled();
super.onCreate(savedInstanceState);
setIntent(getIntent().addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
final ActionBar actionBar = getActionBar();
@ -201,8 +198,7 @@ public class SettingsActivity extends BasePreferenceActivity {
|| getThemeResourceId() != getCurrentThemeResourceId()
|| ThemeUtils.getUserAccentColor(this) != mCurrentThemeColor
|| !CompareUtils.objectEquals(getThemeFontFamily(), mCurrentThemeFontFamily)
|| getThemeBackgroundAlpha() != mCurrentThemeBackgroundAlpha
|| isDarkDrawerEnabled() != mCurrentIsDarkDrawerEnabled;
|| getThemeBackgroundAlpha() != mCurrentThemeBackgroundAlpha;
}
private static class HeaderAdapter extends ArrayAdapter<Header> {

View File

@ -35,8 +35,6 @@ public interface IThemedActivity {
int getThemeResourceId();
public boolean isDarkDrawerEnabled();
public void navigateUpFromSameTask();
public void overrideCloseAnimationIfNeeded();

View File

@ -65,11 +65,6 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
return ThemeUtils.getThemeFontFamily(this);
}
@Override
public boolean isDarkDrawerEnabled() {
return ThemeUtils.isDarkDrawerEnabled(this);
}
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);

View File

@ -45,6 +45,7 @@ import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.widget.ListPopupWindowCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@ -54,11 +55,13 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
@ -77,8 +80,6 @@ import com.twitter.Extractor;
import org.mariotaku.dynamicgridview.DraggableArrayAdapter;
import org.mariotaku.menucomponent.internal.widget.IListPopupWindow;
import org.mariotaku.menucomponent.widget.MenuBar;
import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.BaseArrayAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
@ -107,6 +108,7 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.view.ColorLabelFrameLayout;
import org.mariotaku.twidere.view.StatusTextCountView;
import org.mariotaku.twidere.view.TwidereMenuBar;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import java.io.File;
@ -150,7 +152,7 @@ import static org.mariotaku.twidere.util.Utils.showErrorMessage;
import static org.mariotaku.twidere.util.Utils.showMenuItemToast;
public class ComposeActivity extends BaseSupportDialogActivity implements TextWatcher, LocationListener,
MenuBarListener, OnClickListener, OnEditorActionListener, OnLongClickListener, OnItemClickListener {
OnMenuItemClickListener, OnClickListener, OnEditorActionListener, OnLongClickListener, OnItemClickListener {
private static final String FAKE_IMAGE_LINK = "https://www.example.com/fake_image.jpg";
@ -177,7 +179,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
private TextView mTitleView, mSubtitleView;
private GridView mMediasPreviewGrid;
private MenuBar mMenuBar;
private TwidereMenuBar mMenuBar;
private EditText mEditText;
private ProgressBar mProgress;
private View mSendView;
@ -441,7 +443,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
mTitleView = (TextView) findViewById(R.id.actionbar_title);
mSubtitleView = (TextView) findViewById(R.id.actionbar_subtitle);
mMediasPreviewGrid = (GridView) findViewById(R.id.medias_thumbnail_preview);
mMenuBar = (MenuBar) findViewById(R.id.menu_bar);
mMenuBar = (TwidereMenuBar) findViewById(R.id.menu_bar);
mProgress = (ProgressBar) findViewById(R.id.actionbar_progress_indeterminate);
final View composeActionBar = findViewById(R.id.compose_actionbar);
final View composeBottomBar = findViewById(R.id.compose_bottombar);
@ -579,16 +581,20 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
return;
}
mMenuBar.setIsBottomBar(true);
mMenuBar.setMenuBarListener(this);
mMenuBar.setOnMenuItemClickListener(this);
mEditText.setOnEditorActionListener(mPreferences.getBoolean(KEY_QUICK_SEND, false) ? this : null);
mEditText.addTextChangedListener(this);
final AccountSelectorAdapter accountAdapter = new AccountSelectorAdapter(this);
accountAdapter.addAll(Account.getAccountsList(this, false));
mAccountSelectorPopup = IListPopupWindow.InstanceHelper.getInstance(mMenuBar.getPopupContext());
mAccountSelectorPopup.setInputMethodMode(IListPopupWindow.INPUT_METHOD_NOT_NEEDED);
mAccountSelectorPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
mAccountSelectorPopup.setModal(true);
mAccountSelectorPopup.setContentWidth(getResources().getDimensionPixelSize(R.dimen.mc__popup_window_width));
mAccountSelectorPopup.setContentWidth(getResources().getDimensionPixelSize(R.dimen.account_selector_popup_width));
mAccountSelectorPopup.setAdapter(accountAdapter);
mAccountSelectorPopup.setAnchorView(mSelectAccountButton);
// mSelectAccountButton.setOnTouchListener(ListPopupWindowCompat.createDragToOpenListener(
// mAccountSelectorPopup, mSelectAccountButton));
mSelectAccountButton.setOnClickListener(this);
mSelectAccountButton.setOnLongClickListener(this);
@ -1100,11 +1106,6 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
mSendTextCountView.setTextCount(validatedCount);
}
@Override
public void onPreShowMenu(Menu menu) {
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final ListView listView = (ListView) parent;

View File

@ -79,6 +79,8 @@ import org.mariotaku.twidere.model.Account;
import org.mariotaku.twidere.model.SupportTabSpec;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.task.AsyncTask;
import org.mariotaku.twidere.util.ActivityAccessor;
import org.mariotaku.twidere.util.ActivityAccessor.TaskDescriptionCompat;
import org.mariotaku.twidere.util.ArrayUtils;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.FlymeUtils;
@ -572,6 +574,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
homeActionButton.setIconColor(contrastColor, Mode.SRC_ATOP);
mTabIndicator.setStripColor(contrastColor);
mTabIndicator.setIconColor(contrastColor);
ActivityAccessor.setTaskDescription(this, new TaskDescriptionCompat(null, null, themeColor));
} else {
final int backgroundColor = ThemeUtils.getThemeBackgroundColor(mTabIndicator.getItemContext());
final int foregroundColor = ThemeUtils.getThemeForegroundColor(mTabIndicator.getItemContext());

View File

@ -246,6 +246,10 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
setTitle(R.string.statuses);
break;
}
case LINK_ID_USER_MEDIA_TIMELINE: {
setTitle(R.string.medias);
break;
}
case LINK_ID_STATUS_RETWEETERS: {
setTitle(R.string.users_retweeted_this);
break;
@ -263,9 +267,6 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
// setSubtitle(uri.getQueryParameter(QUERY_PARAM_QUERY));
break;
}
default: {
return false;
}
}
mFinishOnly = Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY));
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

View File

@ -265,7 +265,7 @@ public interface SharedPreferenceConstants {
public static final String KEY_NOTIFICATION_TYPE_HOME = "notification_type_home";
public static final String KEY_NOTIFICATION_TYPE_MENTIONS = "notification_type_mentions";
public static final String KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES = "notification_type_direct_messages";
public static final String KEY_MY_FOLLOWING_ONLY = "my_following_only";
public static final String KEY_NOTIFICATION_FOLLOWING_ONLY = "notification_following_only";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
public static final String KEY_COMPACT_CARDS = "compact_cards";
@ -282,8 +282,6 @@ public interface SharedPreferenceConstants {
public static final String KEY_IMAGE_PREVIEW_SCALE_TYPE = "image_preview_scale_type";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
public static final String KEY_PLAIN_LIST_STYLE = "plain_list_style";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
public static final String KEY_DARK_DRAWER = "dark_drawer";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
public static final String KEY_SORT_TIMELINE_BY_ID = "sort_timeline_by_id";

View File

@ -351,8 +351,6 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
private Context getThemedContext() {
if (mThemedContext != null) return mThemedContext;
final Context context = getActivity();
if (!ThemeUtils.isDarkDrawerEnabled(context))
return mThemedContext = context;
final int themeResource = ThemeUtils.getDrawerThemeResource(context);
return mThemedContext = new ContextThemeWrapper(context, themeResource);
}

View File

@ -24,15 +24,26 @@ import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.View;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
public class BaseSupportFragment extends Fragment implements Constants {
public class BaseSupportFragment extends Fragment implements IBaseFragment, Constants {
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
requestFitSystemWindows();
}
public BaseSupportFragment() {
@ -94,4 +105,29 @@ public class BaseSupportFragment extends Fragment implements Constants {
if (activity == null) return;
activity.unregisterReceiver(receiver);
}
@Override
public Bundle getExtraConfiguration() {
return null;
}
@Override
public int getTabPosition() {
return 0;
}
@Override
public void requestFitSystemWindows() {
final Activity activity = getActivity();
if (!(activity instanceof SystemWindowsInsetsCallback)) return;
final SystemWindowsInsetsCallback callback = (SystemWindowsInsetsCallback) activity;
final Rect insets = new Rect();
if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets);
}
}
protected void fitSystemWindows(Rect insets) {
}
}

View File

@ -89,13 +89,13 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
}
@Override
public final int getStatuses(final long[] account_ids, final long[] max_ids, final long[] since_ids) {
public final int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
mStatusesRestored = true;
final long max_id = max_ids != null && max_ids.length == 1 ? max_ids[0] : -1;
final long since_id = since_ids != null && since_ids.length == 1 ? since_ids[0] : -1;
final long maxId = maxIds != null && maxIds.length == 1 ? maxIds[0] : -1;
final long sinceId = sinceIds != null && sinceIds.length == 1 ? sinceIds[0] : -1;
final Bundle args = new Bundle(getArguments());
args.putLong(EXTRA_MAX_ID, max_id);
args.putLong(EXTRA_SINCE_ID, since_id);
args.putLong(EXTRA_MAX_ID, maxId);
args.putLong(EXTRA_SINCE_ID, sinceId);
getLoaderManager().restartLoader(0, args, this);
return -1;
}

View File

@ -103,16 +103,7 @@ public class QuickMenuFragment extends BaseSupportFragment {
if (mThemedContext != null) return mThemedContext;
final Context context = getActivity();
final int currentThemeResource = ThemeUtils.getThemeResource(context);
final int themeResource;
if (!ThemeUtils.isDarkDrawerEnabled(context)) {
if (ThemeUtils.isDarkTheme(currentThemeResource)) {
return mThemedContext = context;
}
themeResource = ThemeUtils.getLightDrawerThemeResource(currentThemeResource);
} else {
themeResource = ThemeUtils.getDrawerThemeResource(currentThemeResource);
}
// final int accentColor = ThemeUtils.getUserAccentColor(context);
final int themeResource = ThemeUtils.getDrawerThemeResource(currentThemeResource);
return mThemedContext = new ContextThemeWrapper(context, themeResource);
}

View File

@ -0,0 +1,183 @@
package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.loader.support.MediaTimelineLoader;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.view.MediaSizeImageView;
import java.util.List;
/**
* Created by mariotaku on 14/11/5.
*/
public class UserMediaTimelineFragment extends BaseSupportFragment
implements LoaderCallbacks<List<ParcelableStatus>> {
private RecyclerView mRecyclerView;
private ProgressBar mProgress;
private MediaTimelineAdapter mAdapter;
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
}
};
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
assert view != null;
final Context context = view.getContext();
mAdapter = new MediaTimelineAdapter(context);
final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setOnScrollListener(mOnScrollListener);
getLoaderManager().initLoader(0, getArguments(), this);
setListShown(false);
}
public void setListShown(boolean shown) {
mRecyclerView.setVisibility(shown ? View.VISIBLE : View.GONE);
mProgress.setVisibility(shown ? View.GONE : View.VISIBLE);
}
public int getStatuses(final long maxId, final long sinceId) {
final Bundle args = new Bundle(getArguments());
args.putLong(EXTRA_MAX_ID, maxId);
args.putLong(EXTRA_SINCE_ID, sinceId);
getLoaderManager().restartLoader(0, args, this);
return -1;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
}
@Override
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
final Context context = getActivity();
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
return new MediaTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, null,
null, tabPosition);
}
@Override
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
mAdapter.setData(data);
setListShown(true);
}
@Override
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
mAdapter.setData(null);
}
private static class MediaTimelineAdapter extends Adapter<MediaTimelineViewHolder> {
private final LayoutInflater mInflater;
private final ImageLoaderWrapper mImageLoader;
private final ImageLoadingHandler mLoadingHandler;
private List<ParcelableStatus> mData;
MediaTimelineAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
mLoadingHandler = new ImageLoadingHandler(R.id.media_image_progress);
}
@Override
public MediaTimelineViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = mInflater.inflate(R.layout.adapter_item_media_status, parent, false);
return new MediaTimelineViewHolder(view);
}
@Override
public void onBindViewHolder(MediaTimelineViewHolder holder, int position) {
if (mData == null) return;
holder.setMedia(mImageLoader, mLoadingHandler, mData.get(position));
}
public void setData(List<ParcelableStatus> data) {
mData = data;
notifyDataSetChanged();
}
@Override
public int getItemCount() {
if (mData == null) return 0;
return mData.size();
}
}
private static class MediaTimelineViewHolder extends ViewHolder {
private final MediaSizeImageView mediaImageView;
private final ImageView mediaProfileImageView;
private final TextView mediaTextView;
public MediaTimelineViewHolder(View itemView) {
super(itemView);
mediaImageView = (MediaSizeImageView) itemView.findViewById(R.id.media_image);
mediaProfileImageView = (ImageView) itemView.findViewById(R.id.media_profile_image);
mediaTextView = (TextView) itemView.findViewById(R.id.media_text);
}
public void setMedia(ImageLoaderWrapper loader, ImageLoadingHandler loadingHandler, ParcelableStatus status) {
final ParcelableMedia[] medias = status.medias;
if (medias == null || medias.length < 1) return;
final ParcelableMedia firstMedia = medias[0];
if (status.text_plain.codePointCount(0, status.text_plain.length()) == firstMedia.end) {
mediaTextView.setText(status.text_unescaped.substring(0, firstMedia.start));
} else {
mediaTextView.setText(status.text_unescaped);
}
loader.displayProfileImage(mediaProfileImageView, status.user_profile_image_url);
mediaImageView.setMediaSize(firstMedia.width, firstMedia.height);
loader.displayPreviewImageWithCredentials(mediaImageView, firstMedia.media_url, status.account_id, loadingHandler);
}
}
}

View File

@ -19,9 +19,6 @@
package org.mariotaku.twidere.fragment.support;
import static org.mariotaku.twidere.util.Utils.getAccountId;
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.content.Loader;
@ -32,62 +29,66 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import static org.mariotaku.twidere.util.Utils.getAccountId;
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
public class UserTimelineFragment extends ParcelableStatusesListFragment {
@Override
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
if (args == null) return null;
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
final long user_id = args.getLong(EXTRA_USER_ID, -1);
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
return new UserTimelineLoader(context, account_id, user_id, screen_name, max_id, since_id, getData(),
getSavedStatusesFileArgs(), tab_position);
}
@Override
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
if (args == null) return null;
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
return new UserTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, getData(),
getSavedStatusesFileArgs(), tabPosition);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
final long account_id = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long user_id = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
final String screen_name = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
final boolean is_my_timeline = user_id > 0 ? account_id == user_id : account_id == getAccountId(getActivity(),
screen_name);
final IStatusesAdapter<List<ParcelableStatus>> adapter = getListAdapter();
adapter.setIndicateMyStatusDisabled(is_my_timeline);
adapter.setFiltersEnabled(!is_my_timeline);
adapter.setIgnoredFilterFields(true, false, false, false, false);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
final boolean isMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(getActivity(),
screenName);
final IStatusesAdapter<List<ParcelableStatus>> adapter = getListAdapter();
adapter.setIndicateMyStatusDisabled(isMyTimeline);
adapter.setFiltersEnabled(!isMyTimeline);
adapter.setIgnoredFilterFields(true, false, false, false, false);
}
@Override
protected String[] getSavedStatusesFileArgs() {
final Bundle args = getArguments();
if (args == null) return null;
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long user_id = args.getLong(EXTRA_USER_ID, -1);
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
return new String[] { AUTHORITY_USER_TIMELINE, "account" + account_id, "user" + user_id + "name" + screen_name };
}
@Override
protected String[] getSavedStatusesFileArgs() {
final Bundle args = getArguments();
if (args == null) return null;
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
return new String[]{AUTHORITY_USER_TIMELINE, "account" + accountId, "user" + userId + "name" + screenName};
}
@Override
protected boolean isMyTimeline() {
final Bundle args = getArguments();
if (args != null) {
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long user_id = args.getLong(EXTRA_USER_ID, -1);
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
if (account_id == user_id || screen_name != null
&& screen_name.equals(getAccountScreenName(getActivity(), account_id))) return true;
}
return false;
}
@Override
protected boolean isMyTimeline() {
final Bundle args = getArguments();
if (args != null) {
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
if (accountId == userId || screenName != null
&& screenName.equals(getAccountScreenName(getActivity(), accountId)))
return true;
}
return false;
}
@Override
protected boolean shouldShowAccountColor() {
return false;
}
@Override
protected boolean shouldShowAccountColor() {
return false;
}
}

View File

@ -27,69 +27,69 @@ import android.graphics.drawable.Drawable;
* This drawable that draws a simple white and gray chessboard pattern. It's
* pattern you will often see as a background behind a partly transparent image
* in many applications.
*
*
* @author Daniel Nilsson
*/
public class AlphaPatternDrawable extends Drawable {
private final int mAlphaPatternSize;
private final int mAlphaPatternSize;
private int mNumRectanglesHorizontal;
private int mNumRectanglesVertical;
private int mNumRectanglesHorizontal;
private int mNumRectanglesVertical;
private final Rect mRect = new Rect(), mBounds = new Rect();
private final Paint mPaint = new Paint();
private final Rect mRect = new Rect(), mBounds = new Rect();
private final Paint mPaint = new Paint();
public AlphaPatternDrawable(final int alphaPatternSize) {
mAlphaPatternSize = alphaPatternSize;
}
public AlphaPatternDrawable(final int alphaPatternSize) {
mAlphaPatternSize = alphaPatternSize;
}
@Override
public void draw(final Canvas canvas) {
@Override
public void draw(final Canvas canvas) {
boolean verticalStartWhite = true;
for (int i = 0; i <= mNumRectanglesVertical; i++) {
boolean horizontalStartWhite = verticalStartWhite;
for (int j = 0; j <= mNumRectanglesHorizontal; j++) {
mRect.setEmpty();
mRect.top = i * mAlphaPatternSize + mBounds.top;
mRect.left = j * mAlphaPatternSize + mBounds.left;
mRect.bottom = Math.min(mRect.top + mAlphaPatternSize, mBounds.bottom);
mRect.right = Math.min(mRect.left + mAlphaPatternSize, mBounds.right);
boolean verticalStartWhite = true;
for (int i = 0; i <= mNumRectanglesVertical; i++) {
boolean horizontalStartWhite = verticalStartWhite;
for (int j = 0; j <= mNumRectanglesHorizontal; j++) {
mRect.setEmpty();
mRect.top = i * mAlphaPatternSize + mBounds.top;
mRect.left = j * mAlphaPatternSize + mBounds.left;
mRect.bottom = Math.min(mRect.top + mAlphaPatternSize, mBounds.bottom);
mRect.right = Math.min(mRect.left + mAlphaPatternSize, mBounds.right);
mPaint.setColor(horizontalStartWhite ? Color.WHITE : Color.GRAY);
canvas.drawRect(mRect, mPaint);
mPaint.setColor(horizontalStartWhite ? Color.WHITE : Color.LTGRAY);
canvas.drawRect(mRect, mPaint);
horizontalStartWhite = !horizontalStartWhite;
}
verticalStartWhite = !verticalStartWhite;
}
}
horizontalStartWhite = !horizontalStartWhite;
}
verticalStartWhite = !verticalStartWhite;
}
}
@Override
public int getOpacity() {
return 0;
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(final int alpha) {
@Override
public void setAlpha(final int alpha) {
}
}
@Override
public void setColorFilter(final ColorFilter cf) {
@Override
public void setColorFilter(final ColorFilter cf) {
}
}
@Override
protected void onBoundsChange(final Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
final int height = bounds.height();
final int width = bounds.width();
mNumRectanglesHorizontal = (int) Math.ceil(width / mAlphaPatternSize);
mNumRectanglesVertical = (int) Math.ceil(height / mAlphaPatternSize);
invalidateSelf();
}
@Override
protected void onBoundsChange(final Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
final int height = bounds.height();
final int width = bounds.width();
mNumRectanglesHorizontal = (int) Math.ceil(width / mAlphaPatternSize);
mNumRectanglesVertical = (int) Math.ceil(height / mAlphaPatternSize);
invalidateSelf();
}
}

View File

@ -0,0 +1,68 @@
/*
* 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.loader.support;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import static org.mariotaku.twidere.util.Utils.getAccountId;
import static org.mariotaku.twidere.util.Utils.isFiltered;
public class MediaTimelineLoader extends Twitter4JStatusesLoader {
private final long mUserId;
private final String mUserScreenName;
private final boolean mIsMyTimeline;
public MediaTimelineLoader(final Context context, final long accountId, final long userId, final String screenName,
final long maxId, final long sinceId, final List<ParcelableStatus> data, final String[] savedStatusesArgs,
final int tabPosition) {
super(context, accountId, maxId, sinceId, data, savedStatusesArgs, tabPosition);
mUserId = userId;
mUserScreenName = screenName;
mIsMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(context, screenName);
}
@Override
protected ResponseList<Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException {
if (twitter == null) return null;
if (mUserId != -1)
return twitter.getMediaTimeline(mUserId, paging);
else if (mUserScreenName != null)
return twitter.getMediaTimeline(mUserScreenName, paging);
else
return null;
}
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {
return !mIsMyTimeline && isFiltered(database, -1, status.text_plain, status.text_html, status.source, -1);
}
}

View File

@ -19,64 +19,50 @@
package org.mariotaku.twidere.loader.support;
import static org.mariotaku.twidere.util.Utils.getAccountId;
import static org.mariotaku.twidere.util.Utils.isFiltered;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import org.mariotaku.twidere.model.ParcelableStatus;
import java.util.List;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.User;
import java.util.List;
import static org.mariotaku.twidere.util.Utils.getAccountId;
import static org.mariotaku.twidere.util.Utils.isFiltered;
public class UserTimelineLoader extends Twitter4JStatusesLoader {
private final long mUserId;
private final String mUserScreenName;
private final boolean mIsMyTimeline;
private int mTotalItemsCount;
private final long mUserId;
private final String mUserScreenName;
private final boolean mIsMyTimeline;
public UserTimelineLoader(final Context context, final long accountId, final long userId, final String screenName,
final long maxId, final long sinceId, final List<ParcelableStatus> data, final String[] savedStatusesArgs,
final int tabPosition) {
super(context, accountId, maxId, sinceId, data, savedStatusesArgs, tabPosition);
mUserId = userId;
mUserScreenName = screenName;
mIsMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(context, screenName);
}
public UserTimelineLoader(final Context context, final long accountId, final long userId, final String screenName,
final long maxId, final long sinceId, final List<ParcelableStatus> data, final String[] savedStatusesArgs,
final int tabPosition) {
super(context, accountId, maxId, sinceId, data, savedStatusesArgs, tabPosition);
mUserId = userId;
mUserScreenName = screenName;
mIsMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(context, screenName);
}
public int getTotalItemsCount() {
return mTotalItemsCount;
}
@Override
protected ResponseList<Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException {
if (twitter == null) return null;
if (mUserId != -1)
return twitter.getUserTimeline(mUserId, paging);
else if (mUserScreenName != null)
return twitter.getUserTimeline(mUserScreenName, paging);
else
return null;
}
@Override
protected ResponseList<Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException {
if (twitter == null) return null;
final ResponseList<Status> statuses;
if (mUserId != -1) {
statuses = twitter.getUserTimeline(mUserId, paging);
} else if (mUserScreenName != null) {
statuses = twitter.getUserTimeline(mUserScreenName, paging);
} else
return null;
if (mTotalItemsCount == -1 && !statuses.isEmpty()) {
final User user = statuses.get(0).getUser();
if (user != null) {
mTotalItemsCount = user.getStatusesCount();
}
}
return statuses;
}
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {
return !mIsMyTimeline && isFiltered(database, -1, status.text_plain, status.text_html, status.source, -1);
}
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {
return !mIsMyTimeline && isFiltered(database, -1, status.text_plain, status.text_html, status.source, -1);
}
}

View File

@ -29,142 +29,142 @@ import org.mariotaku.twidere.Constants;
public class AccountPreferences implements Constants {
private final Context mContext;
private final long mAccountId;
private final SharedPreferences mPreferences;
private final Context mContext;
private final long mAccountId;
private final SharedPreferences mPreferences;
public AccountPreferences(final Context context, final long accountId) {
mContext = context;
mAccountId = accountId;
final String name = ACCOUNT_PREFERENCES_NAME_PREFIX + accountId;
mPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE);
}
public AccountPreferences(final Context context, final long accountId) {
mContext = context;
mAccountId = accountId;
final String name = ACCOUNT_PREFERENCES_NAME_PREFIX + accountId;
mPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE);
}
public long getAccountId() {
return mAccountId;
}
public long getAccountId() {
return mAccountId;
}
public int getDefaultNotificationLightColor() {
final Account a = Account.getAccount(mContext, mAccountId);
return a != null ? a.color : HOLO_BLUE_LIGHT;
}
public int getDefaultNotificationLightColor() {
final Account a = Account.getAccount(mContext, mAccountId);
return a != null ? a.color : HOLO_BLUE_LIGHT;
}
public int getDirectMessagesNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES, DEFAULT_NOTIFICATION_TYPE_DIRECT_MESSAGES);
}
public int getDirectMessagesNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES, DEFAULT_NOTIFICATION_TYPE_DIRECT_MESSAGES);
}
public int getHomeTimelineNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_HOME, DEFAULT_NOTIFICATION_TYPE_HOME);
}
public int getHomeTimelineNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_HOME, DEFAULT_NOTIFICATION_TYPE_HOME);
}
public int getMentionsNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_MENTIONS, DEFAULT_NOTIFICATION_TYPE_MENTIONS);
}
public int getMentionsNotificationType() {
return mPreferences.getInt(KEY_NOTIFICATION_TYPE_MENTIONS, DEFAULT_NOTIFICATION_TYPE_MENTIONS);
}
public int getNotificationLightColor() {
return mPreferences.getInt(KEY_NOTIFICATION_LIGHT_COLOR, getDefaultNotificationLightColor());
}
public int getNotificationLightColor() {
return mPreferences.getInt(KEY_NOTIFICATION_LIGHT_COLOR, getDefaultNotificationLightColor());
}
public Uri getNotificationRingtone() {
final Uri def = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
final String path = mPreferences.getString(KEY_NOTIFICATION_RINGTONE, null);
return TextUtils.isEmpty(path) ? def : Uri.parse(path);
}
public Uri getNotificationRingtone() {
final Uri def = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
final String path = mPreferences.getString(KEY_NOTIFICATION_RINGTONE, null);
return TextUtils.isEmpty(path) ? def : Uri.parse(path);
}
public boolean isAutoRefreshDirectMessagesEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_DIRECT_MESSAGES, DEFAULT_AUTO_REFRESH_DIRECT_MESSAGES);
}
public boolean isAutoRefreshDirectMessagesEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_DIRECT_MESSAGES, DEFAULT_AUTO_REFRESH_DIRECT_MESSAGES);
}
public boolean isAutoRefreshEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH, DEFAULT_AUTO_REFRESH);
}
public boolean isAutoRefreshEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH, DEFAULT_AUTO_REFRESH);
}
public boolean isAutoRefreshHomeTimelineEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_HOME_TIMELINE, DEFAULT_AUTO_REFRESH_HOME_TIMELINE);
}
public boolean isAutoRefreshHomeTimelineEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_HOME_TIMELINE, DEFAULT_AUTO_REFRESH_HOME_TIMELINE);
}
public boolean isAutoRefreshMentionsEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_MENTIONS, DEFAULT_AUTO_REFRESH_MENTIONS);
}
public boolean isAutoRefreshMentionsEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_MENTIONS, DEFAULT_AUTO_REFRESH_MENTIONS);
}
public boolean isAutoRefreshTrendsEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_TRENDS, DEFAULT_AUTO_REFRESH_TRENDS);
}
public boolean isAutoRefreshTrendsEnabled() {
return mPreferences.getBoolean(KEY_AUTO_REFRESH_TRENDS, DEFAULT_AUTO_REFRESH_TRENDS);
}
public boolean isDirectMessagesNotificationEnabled() {
return mPreferences.getBoolean(KEY_DIRECT_MESSAGES_NOTIFICATION, DEFAULT_DIRECT_MESSAGES_NOTIFICATION);
}
public boolean isDirectMessagesNotificationEnabled() {
return mPreferences.getBoolean(KEY_DIRECT_MESSAGES_NOTIFICATION, DEFAULT_DIRECT_MESSAGES_NOTIFICATION);
}
public boolean isHomeTimelineNotificationEnabled() {
return mPreferences.getBoolean(KEY_HOME_TIMELINE_NOTIFICATION, DEFAULT_HOME_TIMELINE_NOTIFICATION);
}
public boolean isHomeTimelineNotificationEnabled() {
return mPreferences.getBoolean(KEY_HOME_TIMELINE_NOTIFICATION, DEFAULT_HOME_TIMELINE_NOTIFICATION);
}
public boolean isMentionsNotificationEnabled() {
return mPreferences.getBoolean(KEY_MENTIONS_NOTIFICATION, DEFAULT_MENTIONS_NOTIFICATION);
}
public boolean isMentionsNotificationEnabled() {
return mPreferences.getBoolean(KEY_MENTIONS_NOTIFICATION, DEFAULT_MENTIONS_NOTIFICATION);
}
public boolean isMyFollowingOnly() {
return mPreferences.getBoolean(KEY_MY_FOLLOWING_ONLY, false);
}
public boolean isNotificationFollowingOnly() {
return mPreferences.getBoolean(KEY_NOTIFICATION_FOLLOWING_ONLY, false);
}
public boolean isNotificationEnabled() {
return mPreferences.getBoolean(KEY_NOTIFICATION, DEFAULT_NOTIFICATION);
}
public boolean isNotificationEnabled() {
return mPreferences.getBoolean(KEY_NOTIFICATION, DEFAULT_NOTIFICATION);
}
public static AccountPreferences getAccountPreferences(final AccountPreferences[] prefs, final long accountId) {
for (final AccountPreferences pref : prefs) {
if (pref.getAccountId() == accountId) return pref;
}
return null;
}
public static AccountPreferences getAccountPreferences(final AccountPreferences[] prefs, final long accountId) {
for (final AccountPreferences pref : prefs) {
if (pref.getAccountId() == accountId) return pref;
}
return null;
}
public static AccountPreferences[] getAccountPreferences(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final AccountPreferences[] preferences = new AccountPreferences[accountIds.length];
for (int i = 0, j = preferences.length; i < j; i++) {
preferences[i] = new AccountPreferences(context, accountIds[i]);
}
return preferences;
}
public static AccountPreferences[] getAccountPreferences(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final AccountPreferences[] preferences = new AccountPreferences[accountIds.length];
for (int i = 0, j = preferences.length; i < j; i++) {
preferences[i] = new AccountPreferences(context, accountIds[i]);
}
return preferences;
}
public static long[] getAutoRefreshEnabledAccountIds(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final long[] temp = new long[accountIds.length];
int i = 0;
for (final long accountId : accountIds) {
if (new AccountPreferences(context, accountId).isAutoRefreshEnabled()) {
temp[i++] = accountId;
}
}
final long[] enabledIds = new long[i];
System.arraycopy(temp, 0, enabledIds, 0, i);
return enabledIds;
}
public static long[] getAutoRefreshEnabledAccountIds(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final long[] temp = new long[accountIds.length];
int i = 0;
for (final long accountId : accountIds) {
if (new AccountPreferences(context, accountId).isAutoRefreshEnabled()) {
temp[i++] = accountId;
}
}
final long[] enabledIds = new long[i];
System.arraycopy(temp, 0, enabledIds, 0, i);
return enabledIds;
}
public static AccountPreferences[] getNotificationEnabledPreferences(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final AccountPreferences[] temp = new AccountPreferences[accountIds.length];
int i = 0;
for (final long accountId : accountIds) {
final AccountPreferences preference = new AccountPreferences(context, accountId);
if (preference.isNotificationEnabled()) {
temp[i++] = preference;
}
}
final AccountPreferences[] enabledIds = new AccountPreferences[i];
System.arraycopy(temp, 0, enabledIds, 0, i);
return enabledIds;
}
public static AccountPreferences[] getNotificationEnabledPreferences(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return null;
final AccountPreferences[] temp = new AccountPreferences[accountIds.length];
int i = 0;
for (final long accountId : accountIds) {
final AccountPreferences preference = new AccountPreferences(context, accountId);
if (preference.isNotificationEnabled()) {
temp[i++] = preference;
}
}
final AccountPreferences[] enabledIds = new AccountPreferences[i];
System.arraycopy(temp, 0, enabledIds, 0, i);
return enabledIds;
}
public static boolean isNotificationHasLight(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_LIGHT) != 0;
}
public static boolean isNotificationHasLight(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_LIGHT) != 0;
}
public static boolean isNotificationHasRingtone(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_RINGTONE) != 0;
}
public static boolean isNotificationHasRingtone(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_RINGTONE) != 0;
}
public static boolean isNotificationHasVibration(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_VIBRATION) != 0;
}
public static boolean isNotificationHasVibration(final int flags) {
return (flags & VALUE_NOTIFICATION_FLAG_VIBRATION) != 0;
}
}

View File

@ -19,6 +19,7 @@ import java.util.List;
import twitter4j.EntitySupport;
import twitter4j.ExtendedEntitySupport;
import twitter4j.MediaEntity;
import twitter4j.MediaEntity.Size;
import twitter4j.URLEntity;
public class ParcelableMedia implements Parcelable, JSONParcelable {
@ -51,6 +52,7 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
public final String url, media_url;
public final int start, end, type;
public final int width, height;
public ParcelableMedia(final JSONParcel in) {
url = in.readString("url");
@ -58,6 +60,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
start = in.readInt("start");
end = in.readInt("end");
type = in.readInt("type");
width = in.readInt("width");
height = in.readInt("height");
}
public ParcelableMedia(final MediaEntity entity) {
@ -66,6 +70,9 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
start = entity.getStart();
end = entity.getEnd();
type = TYPE_IMAGE;
final Size size = entity.getSizes().get(Size.LARGE);
width = size != null ? size.getWidth() : 0;
height = size != null ? size.getHeight() : 0;
}
public ParcelableMedia(final Parcel in) {
@ -74,6 +81,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
start = in.readInt();
end = in.readInt();
type = in.readInt();
width = in.readInt();
height = in.readInt();
}
private ParcelableMedia(final String url, final String media_url, final int start, final int end, final int type) {
@ -82,6 +91,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
this.start = start;
this.end = end;
this.type = type;
this.width = 0;
this.height = 0;
}
@Override
@ -96,6 +107,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
out.writeInt("start", start);
out.writeInt("end", end);
out.writeInt("type", type);
out.writeInt("width", width);
out.writeInt("height", height);
}
@Override
@ -105,6 +118,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
dest.writeInt(start);
dest.writeInt(end);
dest.writeInt(type);
dest.writeInt(width);
dest.writeInt(height);
}
public static ParcelableMedia[] fromEntities(final EntitySupport entities) {
@ -119,8 +134,8 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
}
if (medias != null) {
for (final MediaEntity media : medias) {
final URL media_url = media.getMediaURL();
if (media_url != null) {
final URL mediaURL = media.getMediaURL();
if (mediaURL != null) {
list.add(new ParcelableMedia(media));
}
}
@ -152,4 +167,14 @@ public class ParcelableMedia implements Parcelable, JSONParcelable {
return new ParcelableMedia(url, media_url, 0, 0, TYPE_IMAGE);
}
public static class MediaSize {
public static final int LARGE = 1;
public static final int MEDIUM = 2;
public static final int SMALL = 3;
public static final int THUMB = 4;
}
}

View File

@ -24,10 +24,10 @@ import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Color;
import android.preference.Preference;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.mariotaku.twidere.Constants;
@ -37,129 +37,107 @@ import org.mariotaku.twidere.view.ColorPickerView;
public class ColorPickerPreference extends Preference implements DialogInterface.OnClickListener, Constants {
private View mView;
protected int mDefaultValue = Color.WHITE;
private boolean mAlphaSliderEnabled = false;
protected int mDefaultValue = Color.WHITE;
private boolean mAlphaSliderEnabled = false;
private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";
private static final String ATTR_DEFAULTVALUE = "defaultValue";
private static final String ATTR_ALPHASLIDER = "alphaSlider";
private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";
private static final String ATTR_DEFAULTVALUE = "defaultValue";
private static final String ATTR_ALPHASLIDER = "alphaSlider";
private final Resources mResources;
private final Resources mResources;
private ColorPickerDialog mDialog;
private ColorPickerDialog mDialog;
public ColorPickerPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.preferenceStyle);
}
public ColorPickerPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.preferenceStyle);
}
public ColorPickerPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
mResources = context.getResources();
init(context, attrs);
}
public ColorPickerPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
mResources = context.getResources();
setWidgetLayoutResource(R.layout.preference_widget_color_picker);
init(context, attrs);
}
public void onActivityDestroy() {
if (mDialog == null || !mDialog.isShowing()) return;
mDialog.dismiss();
}
public void onActivityDestroy() {
if (mDialog == null || !mDialog.isShowing()) return;
mDialog.dismiss();
}
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (mDialog == null) return;
final int color = mDialog.getColor();
if (isPersistent()) {
persistInt(color);
}
setPreviewColor();
final OnPreferenceChangeListener listener = getOnPreferenceChangeListener();
if (listener != null) {
listener.onPreferenceChange(this, color);
}
break;
}
}
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (mDialog == null) return;
final int color = mDialog.getColor();
if (isPersistent()) {
persistInt(color);
}
final OnPreferenceChangeListener listener = getOnPreferenceChangeListener();
if (listener != null) {
listener.onPreferenceChange(this, color);
}
break;
}
}
@Override
public void setDefaultValue(final Object value) {
if (!(value instanceof Integer)) return;
mDefaultValue = (Integer) value;
}
@Override
public void setDefaultValue(final Object value) {
if (!(value instanceof Integer)) return;
mDefaultValue = (Integer) value;
}
protected void init(final Context context, final AttributeSet attrs) {
if (attrs != null) {
final String defaultValue = attrs.getAttributeValue(ANDROID_NS, ATTR_DEFAULTVALUE);
if (defaultValue != null && defaultValue.startsWith("#")) {
try {
setDefaultValue(Color.parseColor(defaultValue));
} catch (final IllegalArgumentException e) {
Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
setDefaultValue(Color.WHITE);
}
} else {
final int colorResourceId = attrs.getAttributeResourceValue(ANDROID_NS, ATTR_DEFAULTVALUE, 0);
if (colorResourceId != 0) {
setDefaultValue(context.getResources().getColor(colorResourceId));
}
}
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, ATTR_ALPHASLIDER, false);
}
}
protected void init(final Context context, final AttributeSet attrs) {
if (attrs != null) {
final String defaultValue = attrs.getAttributeValue(ANDROID_NS, ATTR_DEFAULTVALUE);
if (defaultValue != null && defaultValue.startsWith("#")) {
try {
setDefaultValue(Color.parseColor(defaultValue));
} catch (final IllegalArgumentException e) {
Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
setDefaultValue(Color.WHITE);
}
} else {
final int colorResourceId = attrs.getAttributeResourceValue(ANDROID_NS, ATTR_DEFAULTVALUE, 0);
if (colorResourceId != 0) {
setDefaultValue(context.getResources().getColor(colorResourceId));
}
}
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, ATTR_ALPHASLIDER, false);
}
}
@Override
protected void onBindView(final View view) {
super.onBindView(view);
mView = view;
setPreviewColor();
}
@Override
protected void onBindView(@NonNull final View view) {
super.onBindView(view);
final ImageView imageView = (ImageView) view.findViewById(R.id.color);
imageView.setImageBitmap(ColorPickerView.getColorPreviewBitmap(getContext(), getValue()));
}
@Override
protected void onClick() {
if (mDialog != null && mDialog.isShowing()) return;
mDialog = new ColorPickerDialog(getContext(), getValue(), mAlphaSliderEnabled);
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, mResources.getString(android.R.string.ok), this);
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mResources.getString(android.R.string.cancel), this);
mDialog.show();
return;
}
@Override
protected void onClick() {
if (mDialog != null && mDialog.isShowing()) return;
mDialog = new ColorPickerDialog(getContext(), getValue(), mAlphaSliderEnabled);
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, mResources.getString(android.R.string.ok), this);
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mResources.getString(android.R.string.cancel), this);
mDialog.show();
return;
}
@Override
protected void onSetInitialValue(final boolean restoreValue, final Object defaultValue) {
if (isPersistent() && defaultValue instanceof Integer) {
persistInt(restoreValue ? getValue() : (Integer) defaultValue);
}
}
@Override
protected void onSetInitialValue(final boolean restoreValue, final Object defaultValue) {
if (isPersistent() && defaultValue instanceof Integer) {
persistInt(restoreValue ? getValue() : (Integer) defaultValue);
}
}
private int getValue() {
try {
if (isPersistent()) return getPersistedInt(mDefaultValue);
} catch (final ClassCastException e) {
e.printStackTrace();
}
return mDefaultValue;
}
private void setPreviewColor() {
if (mView == null) return;
final View widgetFrameView = mView.findViewById(android.R.id.widget_frame);
if (!(widgetFrameView instanceof ViewGroup)) return;
final ViewGroup widgetFrame = (ViewGroup) widgetFrameView;
widgetFrame.setVisibility(View.VISIBLE);
// remove preview image that is already created
widgetFrame.setAlpha(isEnabled() ? 1 : 0.25f);
final View foundView = widgetFrame.findViewById(R.id.color);
final ImageView imageView;
if (foundView instanceof ImageView) {
imageView = (ImageView) foundView;
} else {
imageView = new ImageView(getContext());
widgetFrame.removeAllViews();
imageView.setId(R.id.color);
widgetFrame.addView(imageView);
}
imageView.setImageBitmap(ColorPickerView.getColorPreviewBitmap(getContext(), getValue()));
}
private int getValue() {
try {
if (isPersistent()) return getPersistedInt(mDefaultValue);
} catch (final ClassCastException e) {
e.printStackTrace();
}
return mDefaultValue;
}
}

View File

@ -0,0 +1,187 @@
package org.mariotaku.twidere.preference;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.DialogPreference;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.graphic.AlphaPatternDrawable;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
/**
* Created by mariotaku on 14/11/8.
*/
public class ThemeBackgroundPreference extends DialogPreference implements Constants {
private final String[] mBackgroundEntries, mBackgroundValues;
private String mValue;
private View mAlphaContainer;
private SeekBar mAlphaSlider;
private ImageView mAlphaPreview;
private OnClickListener mSingleChoiceListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final String value = mBackgroundValues[which];
setValue(value);
// if (!VALUE_THEME_BACKGROUND_TRANSPARENT.equals(value)) {
// ThemeBackgroundPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
// }
}
};
private OnSeekBarChangeListener mAlphaSliderChangedListener = new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
updateAlphaPreview();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
final SharedPreferences preferences = getSharedPreferences();
final SharedPreferences.Editor editor = preferences.edit();
editor.putInt(KEY_THEME_BACKGROUND_ALPHA, mAlphaSlider.getProgress());
editor.apply();
persistValue(mValue);
}
}
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
setValue(restorePersistedValue ? getPersistedString(mValue) : (String) defaultValue);
}
private void updateSummary() {
final int valueIndex = getValueIndex();
setSummary(valueIndex != -1 ? mBackgroundEntries[valueIndex] : null);
}
private void setValue(String value) {
mValue = value;
updateSummary();
updateAlphaVisibility();
}
private void persistValue(String value) {
// Always persist/notify the first time.
if (!TextUtils.equals(getPersistedString(mValue), value)) {
persistString(value);
notifyChanged();
}
updateAlphaVisibility();
updateSummary();
}
private void updateAlphaVisibility() {
if (mAlphaContainer == null) return;
final boolean isTransparent = VALUE_THEME_BACKGROUND_TRANSPARENT.equals(mValue);
mAlphaContainer.setVisibility(isTransparent ? View.VISIBLE : View.GONE);
}
public String getValue() {
return mValue;
}
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
}
public ThemeBackgroundPreference(Context context) {
this(context, null);
}
private int getValueIndex() {
return findIndexOfValue(mValue);
}
public ThemeBackgroundPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setKey(KEY_THEME_BACKGROUND);
final Resources resources = context.getResources();
mBackgroundEntries = resources.getStringArray(R.array.entries_theme_background);
mBackgroundValues = resources.getStringArray(R.array.values_theme_background);
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setSingleChoiceItems(mBackgroundEntries, getValueIndex(), mSingleChoiceListener);
}
public int findIndexOfValue(String value) {
if (value != null && mBackgroundValues != null) {
for (int i = mBackgroundValues.length - 1; i >= 0; i--) {
if (mBackgroundValues[i].equals(value)) {
return i;
}
}
}
return -1;
}
@Override
protected void showDialog(Bundle state) {
super.showDialog(state);
final Dialog dialog = getDialog();
final SharedPreferences preferences = getSharedPreferences();
if (dialog instanceof AlertDialog && preferences != null) {
final Resources res = dialog.getContext().getResources();
final LayoutInflater inflater = dialog.getLayoutInflater();
final ListView listView = ((AlertDialog) dialog).getListView();
final ViewGroup listViewParent = (ViewGroup) listView.getParent();
listViewParent.removeView(listView);
final View view = inflater.inflate(R.layout.dialog_theme_background_preference, listViewParent);
((ViewGroup) view.findViewById(R.id.list_container)).addView(listView);
mAlphaContainer = view.findViewById(R.id.alpha_container);
mAlphaSlider = (SeekBar) view.findViewById(R.id.alpha_slider);
mAlphaPreview = (ImageView) view.findViewById(R.id.alpha_preview);
mAlphaSlider.setMax(0xFF);
mAlphaSlider.setOnSeekBarChangeListener(mAlphaSliderChangedListener);
mAlphaSlider.setProgress(preferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA));
final int patternSize = res.getDimensionPixelSize(R.dimen.element_spacing_msmall);
ViewAccessor.setBackground(mAlphaPreview, new AlphaPatternDrawable(patternSize));
updateAlphaVisibility();
updateAlphaPreview();
}
}
private void updateAlphaPreview() {
if (mAlphaPreview == null || mAlphaSlider == null) return;
final Drawable drawable = mAlphaPreview.getDrawable();
if (drawable == null) return;
drawable.setAlpha(mAlphaSlider.getProgress());
}
}

View File

@ -1024,7 +1024,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
final ParcelableStatus status = new ParcelableStatus(value);
if (!enabled || !isFiltered(mDatabaseWrapper.getSQLiteDatabase(), status, filtersForRts)) {
final AccountPreferences pref = AccountPreferences.getAccountPreferences(prefs, status.account_id);
if (pref == null || status.user_is_following || !pref.isMyFollowingOnly()) {
if (pref == null || status.user_is_following || !pref.isNotificationFollowingOnly()) {
mNewMentions.add(status);
}
if (mUnreadMentions.add(new UnreadItem(status.id, status.account_id))) {

View File

@ -0,0 +1,167 @@
package org.mariotaku.twidere.util;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager.TaskDescription;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by mariotaku on 14/11/4.
*/
public class ActivityAccessor {
public static void setTaskDescription(Activity activity, TaskDescriptionCompat taskDescription) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
ActivityAccessorL.setTaskDescription(activity, taskDescription);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
static class ActivityAccessorL {
public static void setTaskDescription(Activity activity, TaskDescriptionCompat taskDescription) {
activity.setTaskDescription(toNativeTaskDescription(taskDescription));
}
private static TaskDescription toNativeTaskDescription(TaskDescriptionCompat taskDescription) {
return new TaskDescription(taskDescription.getLabel(), taskDescription.getIcon(), taskDescription.getPrimaryColor());
}
}
/**
* Information you can set and retrieve about the current activity within the recent task list.
*/
public static class TaskDescriptionCompat implements Parcelable {
private String mLabel;
private Bitmap mIcon;
private int mColorPrimary;
/**
* Creates the TaskDescription to the specified values.
*
* @param label A label and description of the current state of this task.
* @param icon An icon that represents the current state of this task.
* @param colorPrimary A color to override the theme's primary color. This color must be opaque.
*/
public TaskDescriptionCompat(String label, Bitmap icon, int colorPrimary) {
if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
throw new RuntimeException("A TaskDescription's primary color should be opaque");
}
mLabel = label;
mIcon = icon;
mColorPrimary = colorPrimary;
}
/**
* Creates the TaskDescription to the specified values.
*
* @param label A label and description of the current state of this activity.
* @param icon An icon that represents the current state of this activity.
*/
public TaskDescriptionCompat(String label, Bitmap icon) {
this(label, icon, 0);
}
/**
* Creates the TaskDescription to the specified values.
*
* @param label A label and description of the current state of this activity.
*/
public TaskDescriptionCompat(String label) {
this(label, null, 0);
}
/**
* Creates an empty TaskDescription.
*/
public TaskDescriptionCompat() {
this(null, null, 0);
}
/**
* Creates a copy of another TaskDescription.
*/
public TaskDescriptionCompat(TaskDescriptionCompat td) {
mLabel = td.mLabel;
mIcon = td.mIcon;
mColorPrimary = td.mColorPrimary;
}
private TaskDescriptionCompat(Parcel source) {
readFromParcel(source);
}
/**
* @return The label and description of the current state of this task.
*/
public String getLabel() {
return mLabel;
}
/**
* @return The icon that represents the current state of this task.
*/
public Bitmap getIcon() {
if (mIcon != null) {
return mIcon;
}
return null;
}
/**
* @return The color override on the theme's primary color.
*/
public int getPrimaryColor() {
return mColorPrimary;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (mLabel == null) {
dest.writeInt(0);
} else {
dest.writeInt(1);
dest.writeString(mLabel);
}
if (mIcon == null) {
dest.writeInt(0);
} else {
dest.writeInt(1);
mIcon.writeToParcel(dest, 0);
}
dest.writeInt(mColorPrimary);
}
public void readFromParcel(Parcel source) {
mLabel = source.readInt() > 0 ? source.readString() : null;
mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
mColorPrimary = source.readInt();
}
public static final Creator<TaskDescriptionCompat> CREATOR
= new Creator<TaskDescriptionCompat>() {
public TaskDescriptionCompat createFromParcel(Parcel source) {
return new TaskDescriptionCompat(source);
}
public TaskDescriptionCompat[] newArray(int size) {
return new TaskDescriptionCompat[size];
}
};
@Override
public String toString() {
return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
" colorPrimary: " + mColorPrimary;
}
}
}

View File

@ -26,113 +26,116 @@ import org.mariotaku.twidere.task.ManagedAsyncTask;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.concurrent.CopyOnWriteArrayList;
public class AsyncTaskManager {
public final class AsyncTaskManager {
private final ArrayList<ManagedAsyncTask<?, ?, ?>> mTasks = new ArrayList<ManagedAsyncTask<?, ?, ?>>();
private final Handler mHandler;
private static AsyncTaskManager sInstance;
private final CopyOnWriteArrayList<ManagedAsyncTask<?, ?, ?>> mTasks = new CopyOnWriteArrayList<>();
private final Handler mHandler;
private static AsyncTaskManager sInstance;
AsyncTaskManager() {
this(new Handler());
}
AsyncTaskManager() {
this(new Handler());
}
AsyncTaskManager(final Handler handler) {
mHandler = handler;
}
AsyncTaskManager(final Handler handler) {
mHandler = handler;
}
public <T> int add(final ManagedAsyncTask<T, ?, ?> task, final boolean exec, final T... params) {
final int hashCode = task.hashCode();
mTasks.add(task);
if (exec) {
execute(hashCode);
}
return hashCode;
}
@SafeVarargs
public final <T> int add(final ManagedAsyncTask<T, ?, ?> task, final boolean exec, final T... params) {
final int hashCode = task.hashCode();
mTasks.add(task);
if (exec) {
execute(hashCode, params);
}
return hashCode;
}
public boolean cancel(final int hashCode) {
return cancel(hashCode, true);
}
public boolean cancel(final int hashCode) {
return cancel(hashCode, true);
}
public boolean cancel(final int hashCode, final boolean mayInterruptIfRunning) {
final ManagedAsyncTask<?, ?, ?> task = findTask(hashCode);
if (task != null) {
task.cancel(mayInterruptIfRunning);
mTasks.remove(task);
return true;
}
return false;
}
public boolean cancel(final int hashCode, final boolean mayInterruptIfRunning) {
final ManagedAsyncTask<?, ?, ?> task = findTask(hashCode);
if (task != null) {
task.cancel(mayInterruptIfRunning);
mTasks.remove(task);
return true;
}
return false;
}
/**
* Cancel all tasks added, then clear all tasks.
*/
public void cancelAll() {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
task.cancel(true);
}
mTasks.clear();
}
/**
* Cancel all tasks added, then clear all tasks.
*/
public void cancelAll() {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
task.cancel(true);
}
mTasks.clear();
}
@SuppressWarnings("unchecked")
public <T> boolean execute(final int hashCode, final T... params) {
final ManagedAsyncTask<T, ?, ?> task = (ManagedAsyncTask<T, ?, ?>) findTask(hashCode);
if (task != null) {
task.execute(params == null || params.length == 0 ? null : params);
return true;
}
return false;
}
@SuppressWarnings("unchecked")
public final <T> boolean execute(final int hashCode, final T... params) {
final ManagedAsyncTask<T, ?, ?> task = (ManagedAsyncTask<T, ?, ?>) findTask(hashCode);
if (task != null) {
task.execute(params);
return true;
}
return false;
}
public Handler getHandler() {
return mHandler;
}
public Handler getHandler() {
return mHandler;
}
public ArrayList<ManagedAsyncTask<?, ?, ?>> getTaskSpecList() {
return new ArrayList<ManagedAsyncTask<?, ?, ?>>(mTasks);
}
public ArrayList<ManagedAsyncTask<?, ?, ?>> getTaskSpecList() {
return new ArrayList<>(mTasks);
}
public boolean hasRunningTask() {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (task.getStatus() == ManagedAsyncTask.Status.RUNNING) return true;
}
return false;
}
public boolean hasRunningTask() {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (task.getStatus() == ManagedAsyncTask.Status.RUNNING) return true;
}
return false;
}
public boolean hasRunningTasksForTag(final String tag) {
if (tag == null) return false;
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (task.getStatus() == ManagedAsyncTask.Status.RUNNING && tag.equals(task.getTag())) return true;
}
return false;
}
public boolean hasRunningTasksForTag(final String tag) {
if (tag == null) return false;
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (task.getStatus() == ManagedAsyncTask.Status.RUNNING && tag.equals(task.getTag()))
return true;
}
return false;
}
public boolean isExecuting(final int hashCode) {
final ManagedAsyncTask<?, ?, ?> task = findTask(hashCode);
if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) return true;
return false;
}
public boolean isExecuting(final int hashCode) {
final ManagedAsyncTask<?, ?, ?> task = findTask(hashCode);
if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) return true;
return false;
}
public void remove(final int hashCode) {
try {
mTasks.remove(findTask(hashCode));
} catch (final ConcurrentModificationException e) {
// Ignore.
}
}
public void remove(final int hashCode) {
try {
mTasks.remove(findTask(hashCode));
} catch (final ConcurrentModificationException e) {
// Ignore.
}
}
private <T> ManagedAsyncTask<?, ?, ?> findTask(final int hashCode) {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (hashCode == task.hashCode()) return task;
}
return null;
}
private <T> ManagedAsyncTask<?, ?, ?> findTask(final int hashCode) {
for (final ManagedAsyncTask<?, ?, ?> task : getTaskSpecList()) {
if (hashCode == task.hashCode()) return task;
}
return null;
}
public static AsyncTaskManager getInstance() {
if (sInstance == null) {
sInstance = new AsyncTaskManager();
}
return sInstance;
}
public static AsyncTaskManager getInstance() {
if (sInstance == null) {
sInstance = new AsyncTaskManager();
}
return sInstance;
}
}

View File

@ -40,26 +40,23 @@ public class ImageLoaderWrapper implements Constants {
public ImageLoaderWrapper(final ImageLoader loader) {
mImageLoader = loader;
final DisplayImageOptions.Builder profileOptsNuilder = new DisplayImageOptions.Builder();
profileOptsNuilder.cacheInMemory(true);
profileOptsNuilder.cacheOnDisk(true);
profileOptsNuilder.showImageForEmptyUri(R.drawable.ic_profile_image_default);
profileOptsNuilder.showImageOnFail(R.drawable.ic_profile_image_default);
profileOptsNuilder.showImageOnLoading(R.drawable.ic_profile_image_default);
profileOptsNuilder.bitmapConfig(Bitmap.Config.ARGB_8888);
profileOptsNuilder.resetViewBeforeLoading(true);
final DisplayImageOptions.Builder profileOptsBuilder = new DisplayImageOptions.Builder();
profileOptsBuilder.cacheInMemory(true);
profileOptsBuilder.cacheOnDisk(true);
profileOptsBuilder.showImageForEmptyUri(R.drawable.ic_profile_image_default);
profileOptsBuilder.showImageOnFail(R.drawable.ic_profile_image_default);
profileOptsBuilder.showImageOnLoading(R.drawable.ic_profile_image_default);
profileOptsBuilder.bitmapConfig(Bitmap.Config.ARGB_8888);
final DisplayImageOptions.Builder imageOptsBuilder = new DisplayImageOptions.Builder();
imageOptsBuilder.cacheInMemory(true);
imageOptsBuilder.cacheOnDisk(true);
imageOptsBuilder.bitmapConfig(Bitmap.Config.RGB_565);
imageOptsBuilder.resetViewBeforeLoading(true);
final DisplayImageOptions.Builder bannerOptsBuilder = new DisplayImageOptions.Builder();
bannerOptsBuilder.cacheInMemory(true);
bannerOptsBuilder.cacheOnDisk(true);
bannerOptsBuilder.bitmapConfig(Bitmap.Config.RGB_565);
bannerOptsBuilder.resetViewBeforeLoading(true);
mProfileImageDisplayOptions = profileOptsNuilder.build();
mProfileImageDisplayOptions = profileOptsBuilder.build();
mImageDisplayOptions = imageOptsBuilder.build();
mBannerDisplayOptions = bannerOptsBuilder.build();
}

View File

@ -36,7 +36,7 @@ import java.util.Map;
public class ImageLoadingHandler implements ImageLoadingListener, ImageLoadingProgressListener {
private final Map<View, String> mLoadingUris = new HashMap<View, String>();
private final Map<View, String> mLoadingUris = new HashMap<>();
private final int[] mProgressBarIds;
public ImageLoadingHandler() {
@ -79,11 +79,10 @@ public class ImageLoadingHandler implements ImageLoadingListener, ImageLoadingPr
view.setBackgroundResource(R.drawable.image_preview_refresh);
}
mLoadingUris.remove(view);
final View parent = (View) view.getParent();
final View progress = parent.findViewById(R.id.image_preview_progress);
if (progress != null) {
progress.setVisibility(View.GONE);
}
final ProgressBar progress = findProgressBar(view.getParent());
if (progress != null) {
progress.setVisibility(View.GONE);
}
}
@Override

View File

@ -675,13 +675,6 @@ public class ThemeUtils implements Constants {
return getWindowContentOverlay(new ContextThemeWrapper(context, themeRes));
}
public static boolean isDarkDrawerEnabled(final Context context) {
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
if (prefs == null) return false;
return prefs.getBoolean(KEY_DARK_DRAWER, true);
}
public static boolean isDarkTheme(final Context context) {
return isDarkTheme(getThemeResource(context));
}

View File

@ -137,8 +137,9 @@ import org.mariotaku.twidere.fragment.support.UserListMembershipsListFragment;
import org.mariotaku.twidere.fragment.support.UserListSubscribersFragment;
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserListsListFragment;
import org.mariotaku.twidere.fragment.support.UserMediaTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserMentionsFragment;
import org.mariotaku.twidere.fragment.support.UserProfileFragment;
import org.mariotaku.twidere.fragment.support.UserProfileFragmentOld;
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
import org.mariotaku.twidere.fragment.support.UsersListFragment;
import org.mariotaku.twidere.graphic.PaddingDrawable;
@ -310,6 +311,7 @@ public final class Utils implements Constants, TwitterConstants {
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_STATUS, null, LINK_ID_STATUS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER, null, LINK_ID_USER);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER_TIMELINE, null, LINK_ID_USER_TIMELINE);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER_MEDIA_TIMELINE, null, LINK_ID_USER_MEDIA_TIMELINE);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER_FOLLOWERS, null, LINK_ID_USER_FOLLOWERS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER_FRIENDS, null, LINK_ID_USER_FRIENDS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_USER_FAVORITES, null, LINK_ID_USER_FAVORITES);
@ -696,7 +698,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER: {
fragment = new UserProfileFragment();
fragment = new UserProfileFragmentOld();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
@ -710,26 +712,39 @@ public final class Utils implements Constants, TwitterConstants {
case LINK_ID_USER_LIST_MEMBERSHIPS: {
fragment = new UserListMembershipsListFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
args.putString(EXTRA_SCREEN_NAME, paramScreenName);
}
if (!args.containsKey(EXTRA_USER_ID)) {
args.putLong(EXTRA_USER_ID, ParseUtils.parseLong(param_user_id));
args.putLong(EXTRA_USER_ID, ParseUtils.parseLong(paramUserId));
}
break;
}
case LINK_ID_USER_TIMELINE: {
fragment = new UserTimelineFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
args.putString(EXTRA_SCREEN_NAME, paramScreenName);
}
if (!args.containsKey(EXTRA_USER_ID)) {
args.putLong(EXTRA_USER_ID, ParseUtils.parseLong(param_user_id));
args.putLong(EXTRA_USER_ID, ParseUtils.parseLong(paramUserId));
}
if (isEmpty(paramScreenName) && isEmpty(param_user_id)) return null;
if (isEmpty(paramScreenName) && isEmpty(paramUserId)) return null;
break;
}
case LINK_ID_USER_MEDIA_TIMELINE: {
fragment = new UserMediaTimelineFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
args.putString(EXTRA_SCREEN_NAME, paramScreenName);
}
if (!args.containsKey(EXTRA_USER_ID)) {
args.putLong(EXTRA_USER_ID, ParseUtils.parseLong(paramUserId));
}
if (isEmpty(paramScreenName) && isEmpty(paramUserId)) return null;
break;
}
case LINK_ID_USER_FAVORITES: {
@ -1647,14 +1662,22 @@ public final class Utils implements Constants, TwitterConstants {
return getDisplayName(context, userId, name, screenName, false);
}
public static String getDisplayName(final Context context, final long user_id, final String name,
final String screen_name, final boolean ignore_cache) {
public static String getDisplayName(final Context context, final ParcelableUser user) {
return getDisplayName(context, user, false);
}
public static String getDisplayName(final Context context, final ParcelableUser user, final boolean ignoreCache) {
return getDisplayName(context, user.id, user.name, user.screen_name, ignoreCache);
}
public static String getDisplayName(final Context context, final long userId, final String name,
final String screenName, final boolean ignoreCache) {
if (context == null) return null;
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final boolean nameFirst = prefs.getBoolean(KEY_NAME_FIRST, true);
final boolean nicknameOnly = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
.getBoolean(KEY_NICKNAME_ONLY, false);
return getDisplayName(context, user_id, name, screen_name, nameFirst, nicknameOnly, ignore_cache);
return getDisplayName(context, userId, name, screenName, nameFirst, nicknameOnly, ignoreCache);
}
public static String getDisplayName(final Context context, final long user_id, final String name,
@ -3346,7 +3369,23 @@ public final class Utils implements Constants, TwitterConstants {
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
activity.startActivity(intent);
}
public static void openUserMediaTimeline(final Activity activity, final long account_id, final long user_id,
final String screen_name) {
if (activity == null) return;
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_MEDIA_TIMELINE);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(account_id));
if (user_id > 0) {
builder.appendQueryParameter(QUERY_PARAM_USER_ID, String.valueOf(user_id));
}
if (screen_name != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screen_name);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
activity.startActivity(intent);
}
public static String replaceLast(final String text, final String regex, final String replacement) {

View File

@ -0,0 +1,28 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Created by mariotaku on 14/11/5.
*/
public class ActionIconView extends ImageView {
public ActionIconView(Context context) {
this(context, null);
}
public ActionIconView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionIconView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.colorForeground});
setColorFilter(a.getColor(0, 0), Mode.SRC_ATOP);
a.recycle();
}
}

View File

@ -0,0 +1,29 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* Created by mariotaku on 14/11/5.
*/
public class DrawerAccountHeaderContainer extends RelativeLayout {
public DrawerAccountHeaderContainer(Context context) {
super(context);
}
public DrawerAccountHeaderContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawerAccountHeaderContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
setMeasuredDimension(width, height);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
}

View File

@ -33,62 +33,57 @@ import org.mariotaku.twidere.util.accessor.ViewAccessor;
public class LeftDrawerFrameLayout extends FrameLayout {
private final Paint mClipPaint = new Paint();
private float mScrollScale, mPercentOpen;
private boolean mClipEnabled;
private final Paint mClipPaint = new Paint();
private float mScrollScale, mPercentOpen;
private boolean mClipEnabled;
public LeftDrawerFrameLayout(final Context context) {
this(context, null);
}
public LeftDrawerFrameLayout(final Context context) {
this(context, null);
}
public LeftDrawerFrameLayout(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public LeftDrawerFrameLayout(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public LeftDrawerFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final Drawable bg;
if (ThemeUtils.isDarkDrawerEnabled(context)) {
bg = ThemeUtils.getWindowBackground(context, ThemeUtils.getDrawerThemeResource(context));
} else {
bg = ThemeUtils.getWindowBackground(context);
}
ViewAccessor.setBackground(this, bg);
setWillNotDraw(false);
mClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public LeftDrawerFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final Drawable bg = ThemeUtils.getWindowBackground(context, ThemeUtils.getDrawerThemeResource(context));
ViewAccessor.setBackground(this, bg);
setWillNotDraw(false);
mClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
@Override
public boolean hasOverlappingRendering() {
return mClipEnabled;
}
@Override
public boolean hasOverlappingRendering() {
return mClipEnabled;
}
public void setClipEnabled(final boolean clipEnabled) {
mClipEnabled = clipEnabled;
if (!clipEnabled) {
setAlpha(1);
}
}
public void setClipEnabled(final boolean clipEnabled) {
mClipEnabled = clipEnabled;
if (!clipEnabled) {
setAlpha(1);
}
}
public void setPercentOpen(final float percentOpen) {
if (mPercentOpen == percentOpen) return;
mPercentOpen = percentOpen;
if (mClipEnabled) {
setAlpha(1 - (1 - mPercentOpen) * (1.0f / 0xff));
invalidate();
}
}
public void setPercentOpen(final float percentOpen) {
if (mPercentOpen == percentOpen) return;
mPercentOpen = percentOpen;
if (mClipEnabled) {
setAlpha(1 - (1 - mPercentOpen) * (1.0f / 0xff));
invalidate();
}
}
public void setScrollScale(final float scrollScale) {
mScrollScale = scrollScale;
}
public void setScrollScale(final float scrollScale) {
mScrollScale = scrollScale;
}
@Override
protected void dispatchDraw(final Canvas canvas) {
super.dispatchDraw(canvas);
if (mClipEnabled && mPercentOpen > 0 && mPercentOpen < 1) {
final int left = Math.round(getWidth() * (1 - (1 - mPercentOpen) * (1 - mScrollScale)));
canvas.drawRect(left, getTop(), getRight(), getBottom(), mClipPaint);
}
}
@Override
protected void dispatchDraw(final Canvas canvas) {
super.dispatchDraw(canvas);
if (mClipEnabled && mPercentOpen > 0 && mPercentOpen < 1) {
final int left = Math.round(getWidth() * (1 - (1 - mPercentOpen) * (1 - mScrollScale)));
canvas.drawRect(left, getTop(), getRight(), getBottom(), mClipPaint);
}
}
}

View File

@ -0,0 +1,55 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ImageView;
/**
* Created by mariotaku on 14/11/5.
*/
public class MediaSizeImageView extends ImageView {
private int mMediaWidth, mMediaHeight;
public MediaSizeImageView(final Context context) {
this(context, null);
}
public MediaSizeImageView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public MediaSizeImageView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
public void setMediaSize(int width, int height) {
mMediaWidth = width;
mMediaHeight = height;
requestLayout();
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
if (mMediaWidth == 0 || mMediaHeight == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
final float whRatio = (float) mMediaWidth / mMediaHeight;
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
final ViewGroup.LayoutParams lp = getLayoutParams();
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
final int calcWidth = Math.round(height * whRatio);
super.onMeasure(MeasureSpec.makeMeasureSpec(calcWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
setMeasuredDimension(calcWidth, height);
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
final int calcHeight = Math.round(width / whRatio);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(calcHeight, MeasureSpec.EXACTLY));
setMeasuredDimension(width, calcHeight);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}

View File

@ -47,12 +47,7 @@ public class RightDrawerFrameLayout extends FrameLayout {
public RightDrawerFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final Drawable bg;
if (!isInEditMode() && ThemeUtils.isDarkDrawerEnabled(context)) {
bg = ThemeUtils.getWindowBackground(context, ThemeUtils.getDrawerThemeResource(context));
} else {
bg = ThemeUtils.getWindowBackground(context);
}
final Drawable bg = ThemeUtils.getWindowBackground(context, ThemeUtils.getDrawerThemeResource(context));
ViewAccessor.setBackground(this, bg);
setWillNotDraw(false);
mClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

View File

@ -8,7 +8,7 @@
android:layout_height="match_parent"
app:ignorePadding="true">
<ImageView
<org.mariotaku.twidere.view.ActionIconView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@ -19,7 +19,7 @@
android:minWidth="@dimen/element_size_small"
android:textAppearance="?android:textAppearanceSmall"/>
<ImageView
<org.mariotaku.twidere.view.ActionIconView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/send"

View File

@ -4,9 +4,11 @@
<com.pkmmte.view.CircularImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="@dimen/float_action_button_size"
android:layout_height="@dimen/float_action_button_size"
android:layout_gravity="center"
app:border="false"
app:selector="true"
app:shadow="true"/>
<ProgressBar
@ -19,8 +21,8 @@
<ImageView
android:id="@android:id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_normal"
android:contentDescription="@string/compose"

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/element_spacing_small"
android:clickable="true"
android:foreground="?android:selectableItemBackground"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<org.mariotaku.twidere.view.MediaSizeImageView
android:id="@+id/media_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"/>
<ProgressBar
android:id="@+id/media_image_progress"
style="?android:progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_small"/>
</FrameLayout>
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
android:id="@+id/media_info_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/element_spacing_small">
<com.pkmmte.view.CircularImageView
android:id="@+id/media_profile_image"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"/>
<TextView
android:id="@+id/media_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/media_profile_image"
android:layout_marginLeft="@dimen/element_spacing_small"
android:layout_toRightOf="@+id/media_profile_image"
android:ellipsize="end"/>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:id="@+id/alpha_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<SeekBar
android:id="@+id/alpha_slider"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<ImageView
android:id="@+id/alpha_preview"
android:layout_width="@dimen/element_size_small"
android:visibility="gone"
android:layout_height="@dimen/element_size_small"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_weight="0"
android:scaleType="centerInside"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
</LinearLayout>

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="horizontal">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="horizontal">
<ImageView
<org.mariotaku.twidere.view.ActionIconView
android:id="@+id/add_image"
style="?android:borderlessButtonStyle"
android:layout_width="?android:actionBarSize"
@ -36,7 +37,7 @@
android:layout_height="?android:actionBarSize"
android:layout_weight="0">
<ImageView
<org.mariotaku.twidere.view.ActionIconView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/send"

View File

@ -45,7 +45,7 @@
<ImageButton
android:id="@+id/activities_config_button"
android:layout_width="@dimen/element_size_default"
android:layout_width="@dimen/element_size_normal"
android:layout_height="match_parent"
android:layout_weight="0"
android:background="?android:selectableItemBackground"

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<android.support.v7.widget.RecyclerView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar
android:id="@android:id/progress"
style="?android:progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.DrawerAccountHeaderContainer
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/profile_banner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.33"
android:scaleType="centerCrop"
android:src="@drawable/twidere_feature_graphic"/>
<ImageView
android:id="@+id/profile_image"
android:layout_width="@dimen/icon_size_user_profile"
android:layout_height="@dimen/icon_size_user_profile"
android:src="@drawable/ic_launcher"/>
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/profile_image"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/profile_image"
android:layout_toRightOf="@+id/profile_image"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/profile_image"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textAppearance="?android:textAppearanceMedium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Screen name"
android:textAppearance="?android:textAppearanceSmall"/>
</LinearLayout>
</org.mariotaku.twidere.view.DrawerAccountHeaderContainer>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/image_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/image_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/image_grid"
@ -20,10 +20,10 @@
android:gravity="center"
android:visibility="gone">
<ImageView
<org.mariotaku.twidere.view.ActionIconView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/load_images"
android:contentDescription="@string/load_images"
android:src="@drawable/ic_action_gallery"/>
<TextView

View File

@ -3,8 +3,8 @@
android:id="@+id/actions_button"
style="?android:buttonStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/float_action_button_size"
android:layout_height="@dimen/float_action_button_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/element_spacing_large"
android:layout_marginBottom="@dimen/element_spacing_normal"
android:visibility="visible"/>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<com.pkmmte.view.CircularImageView
android:id="@+id/color"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
app:border="true"
app:border_color="@android:color/white"
app:border_width="1dp"/>

View File

@ -1,21 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<menu>
<item
android:id="@+id/import_emport_submenu"
android:icon="@drawable/ic_action_import_export"
android:showAsAction="always|withText"
android:title="@string/import_export">
<menu>
<item
android:id="@id/import_settings"
android:icon="@drawable/ic_action_import"
android:title="@string/import_settings"/>
<item
android:id="@id/export_settings"
android:icon="@drawable/ic_action_export"
android:title="@string/export_settings"/>
</menu>
</item>
</menu>

View File

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="element_size_default">48dp</dimen>
<dimen name="element_size_normal">48dp</dimen>
<dimen name="element_size_small">24dp</dimen>
<dimen name="element_spacing_xsmall">2dp</dimen>
<dimen name="element_spacing_small">4dp</dimen>
<dimen name="element_spacing_msmall">6dp</dimen>
<dimen name="element_spacing_normal">8dp</dimen>
<dimen name="element_spacing_mlarge">12dp</dimen>
<dimen name="element_spacing_large">16dp</dimen>
@ -64,11 +65,12 @@
<dimen name="icon_size_alert_dialog">32dp</dimen>
<!-- Dimensions for quick menu -->
<dimen name="header_height_quick_menu">@dimen/element_size_default</dimen>
<dimen name="header_height_quick_menu">@dimen/element_size_normal</dimen>
<!-- Dimensions for buttons -->
<dimen name="button_width_content_min">72dp</dimen>
<dimen name="action_icon_size">32dp</dimen>
<dimen name="unread_indicator_size">16dp</dimen>
<dimen name="account_selector_popup_width">180dp</dimen>
</resources>

View File

@ -210,6 +210,7 @@
<string name="accounts">Accounts</string>
<string name="account">Account</string>
<string name="mention_this_user">Mention this user</string>
<string name="mention_user_name">Mention <xliff:g id="name">%1$s</xliff:g></string>
<string name="signing_in_please_wait">Signing in, please wait or press BACK to quit.</string>
<string name="connectivity">Connectivity</string>
<string name="add_member">Add member</string>
@ -548,7 +549,7 @@
<string name="general">General</string>
<string name="hints">Hints</string>
<string name="finish">Finish</string>
<string name="theme_background">Theme background</string>
<string name="background">Background</string>
<string name="theme_background_default">Default</string>
<string name="theme_background_solid">Pure white/black</string>
<string name="theme_background_transparent">Transparent</string>
@ -627,8 +628,8 @@
<string name="image_preview_scale_type_fit_center">Fit center</string>
<string name="quote_protected_status_warning_message">This tweet is protected.\n\nProtected users usually don\'t want their tweets to be shared publicly.</string>
<string name="send_anyway">Send anyway</string>
<string name="my_following_only">My following only</string>
<string name="my_following_only_summary">Display notifications from users you follow only.</string>
<string name="following_only">Your following only</string>
<string name="following_only_summary">Display notifications from users you follow only.</string>
<string name="new_direct_message">New direct message</string>
<string name="plain_list_style">Plain list style</string>
<string name="want_old_icon_back">Want old icon back?</string>
@ -660,6 +661,6 @@
<string name="action_unmuting">unmuting</string>
<string name="mute_user_confirm_message">Mute <xliff:g id="name">%s</xliff:g>? You will no longer see tweets from this user while keep following this user.</string>
<string name="remove_from_filter">Remove from filter</string>
<string name="sort_timeline_by_id">Sort timeline by id</string>
<string name="sort_timeline_by_id">Sort timeline by ID</string>
</resources>

View File

@ -106,6 +106,13 @@
android:action="android.intent.action.VIEW"
android:data="twidere://user?user_id=218536728&amp;finish_only=true"/>
</Preference>
<Preference
android:summary="Redesigned interface, polished settings &amp; writing style"
android:title="Uucky Lee">
<intent
android:action="android.intent.action.VIEW"
android:data="twidere://user?user_id=1062473329&amp;finish_only=true"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory android:title="@string/sponsored_by">
<Preference

View File

@ -1,54 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/notifications">
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/notifications">
<org.mariotaku.twidere.preference.NotificationContentPreference
android:key="content_to_notify"
android:title="@string/content_to_notify"/>
<org.mariotaku.twidere.preference.NotificationContentPreference
android:key="content_to_notify"
android:title="@string/content_to_notify"/>
<org.mariotaku.twidere.preference.RingtonePreference
android:key="notification_ringtone"
android:title="@string/notification_ringtone"/>
<org.mariotaku.twidere.preference.RingtonePreference
android:key="notification_ringtone"
android:title="@string/notification_ringtone"/>
<org.mariotaku.twidere.preference.ColorPickerPreference
android:defaultValue="@android:color/holo_blue_dark"
android:key="notification_light_color"
android:title="@string/notification_light_color"/>
<org.mariotaku.twidere.preference.ColorPickerPreference
android:defaultValue="@android:color/holo_blue_dark"
android:key="notification_light_color"
android:title="@string/notification_light_color"/>
<PreferenceCategory
android:key="cat_notifications_type"
android:title="@string/notifications_type">
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_home"
android:title="@string/home"
app:dependencyKey="home_timeline_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="none"/>
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_mentions"
android:title="@string/mentions"
app:dependencyKey="mentions_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="vibration|light"/>
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_direct_messages"
android:title="@string/direct_messages"
app:dependencyKey="direct_messages_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="ringtone|vibration|light"/>
</PreferenceCategory>
<PreferenceCategory
android:key="cat_other_settings"
android:title="@string/other_settings">
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="my_following_only"
android:summary="@string/my_following_only_summary"
android:title="@string/my_following_only"/>
</PreferenceCategory>
<PreferenceCategory
android:key="cat_notifications_type"
android:title="@string/notifications_type">
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_home"
android:title="@string/home"
app:dependencyKey="home_timeline_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="none"/>
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_mentions"
android:title="@string/mentions"
app:dependencyKey="mentions_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="vibration|light"/>
<org.mariotaku.twidere.preference.NotificationTypePreference
android:key="notification_type_direct_messages"
android:title="@string/direct_messages"
app:dependencyKey="direct_messages_notification"
app:dependencyValueDefault="false"
app:dependencyValues="@array/dependency_values_true"
app:notificationType="ringtone|vibration|light"/>
</PreferenceCategory>
<PreferenceCategory
android:key="cat_other_settings"
android:title="@string/other_settings">
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="notification_following_only"
android:summary="@string/following_only_summary"
android:title="@string/following_only"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@ -1,49 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/other_settings">
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/other_settings">
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="quick_send"
android:summary="@string/quick_send_summary"
android:title="@string/quick_send"/>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="quick_send"
android:summary="@string/quick_send_summary"
android:title="@string/quick_send"/>
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
android:defaultValue="ask"
android:entries="@array/entries_compose_quit_action"
android:entryValues="@array/values_compose_quit_action"
android:key="compose_quit_action"
android:summary="%s"
android:title="@string/compose_quit_action"/>
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
android:defaultValue="ask"
android:entries="@array/entries_compose_quit_action"
android:entryValues="@array/values_compose_quit_action"
android:key="compose_quit_action"
android:summary="%s"
android:title="@string/compose_quit_action"/>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="no_close_after_tweet_sent"
android:summary="@string/no_close_after_status_updated_summary"
android:title="@string/no_close_after_status_updated"/>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="no_close_after_tweet_sent"
android:summary="@string/no_close_after_status_updated_summary"
android:title="@string/no_close_after_status_updated"/>
<org.mariotaku.twidere.preference.ComponentStatePreference
android:name="org.mariotaku.twidere.activity.TwitterLinkHandlerActivity"
android:key="twitter_link_handler"
android:title="@string/twitter_link_handler"/>
<org.mariotaku.twidere.preference.ComponentStatePreference
android:name="org.mariotaku.twidere.activity.AssistLauncherActivity"
android:key="compose_now"
android:summary="@string/compose_now_summary"
android:title="@string/compose_now"/>
<org.mariotaku.twidere.preference.ComponentStatePreference
android:name="org.mariotaku.twidere.activity.TwitterLinkHandlerActivity"
android:key="twitter_link_handler"
android:title="@string/twitter_link_handler"/>
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
android:defaultValue="compose"
android:dependency="compose_now"
android:entries="@array/entries_compose_now_action"
android:entryValues="@array/values_compose_now_action"
android:key="compose_now_action"
android:summary="%s"
android:title="@string/compose_now_action"/>
<org.mariotaku.twidere.preference.ComponentStatePreference
android:name="org.mariotaku.twidere.activity.AssistLauncherActivity"
android:key="compose_now"
android:summary="@string/compose_now_summary"
android:title="@string/compose_now"/>
<Preference
android:fragment="org.mariotaku.twidere.fragment.DataProfilingSettingsFragment"
android:key="data_profiling_settings"
android:title="@string/data_profiling"/>
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
android:defaultValue="compose"
android:dependency="compose_now"
android:entries="@array/entries_compose_now_action"
android:entryValues="@array/values_compose_now_action"
android:key="compose_now_action"
android:summary="%s"
android:title="@string/compose_now_action"/>
<Preference
android:fragment="org.mariotaku.twidere.fragment.DataProfilingSettingsFragment"
android:key="data_profiling_settings"
android:title="@string/data_profiling"/>
<Preference android:title="@string/import_settings">
<intent
android:targetPackage="org.mariotaku.twidere"
android:targetClass="org.mariotaku.twidere.activity.support.DataImportActivity"/>
</Preference>
<Preference android:title="@string/export_settings">
<intent
android:targetPackage="org.mariotaku.twidere"
android:targetClass="org.mariotaku.twidere.activity.support.DataExportActivity"/>
</Preference>
</PreferenceScreen>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/theme">
<PreferenceCategory
@ -18,24 +17,11 @@
android:key="theme"
android:order="21"
android:title="@string/theme"/>
<org.mariotaku.twidere.preference.SummaryListPreference
android:defaultValue="default"
android:entries="@array/entries_theme_background"
android:entryValues="@array/values_theme_background"
android:key="theme_background"
android:order="22"
android:title="@string/theme_background"/>
<org.mariotaku.twidere.preference.ValueDependencySeekBarDialogPreference
android:defaultValue="160"
android:key="theme_background_alpha"
android:order="23"
android:title="@string/theme_background_alpha"
app:dependencyKey="theme_background"
app:dependencyValueDefault="default"
app:dependencyValues="@array/dependency_values_theme_background_alpha"
app:max="255"
app:min="0"/>
<org.mariotaku.twidere.preference.ThemeBackgroundPreference
android:defaultValue="default"
android:order="22"
android:title="@string/background"/>
<org.mariotaku.twidere.preference.ColorPickerPreference
android:defaultValue="@android:color/holo_blue_light"
@ -50,10 +36,4 @@
android:order="26"
android:title="@string/theme_font_family"/>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="true"
android:key="dark_drawer"
android:order="27"
android:title="@string/dark_drawer"/>
</PreferenceScreen>