code cleanup

This commit is contained in:
Mariotaku Lee 2017-01-20 22:08:42 +08:00
parent 70b5eb2f0f
commit 289d9fe904
No known key found for this signature in database
GPG Key ID: 9C0706AE47FCE2AD
39 changed files with 1033 additions and 1055 deletions

View File

@ -12,7 +12,7 @@ import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity
* Created by mariotaku on 2016/12/25.
*/
class GooglePlayExtraFeaturesService() : ExtraFeaturesService() {
class GooglePlayExtraFeaturesService : ExtraFeaturesService() {
private lateinit var bp: BillingProcessor

View File

@ -1,194 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IDirectMessagesAdapter;
import org.mariotaku.twidere.model.ParcelableDirectMessage;
import org.mariotaku.twidere.model.ParcelableDirectMessageCursorIndices;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.util.DirectMessageOnLinkClickHandler;
import org.mariotaku.twidere.util.IntentUtils;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CardMediaContainer;
import org.mariotaku.twidere.view.holder.IncomingMessageViewHolder;
import org.mariotaku.twidere.view.holder.MessageViewHolder;
import java.lang.ref.WeakReference;
public class MessageConversationAdapter extends BaseRecyclerViewAdapter<ViewHolder> implements
Constants, IDirectMessagesAdapter {
private static final int ITEM_VIEW_TYPE_MESSAGE_OUTGOING = 1;
private static final int ITEM_VIEW_TYPE_MESSAGE_INCOMING = 2;
private final int mOutgoingMessageColor;
private final int mIncomingMessageColor;
private final int mMediaPreviewStyle;
private final LayoutInflater mInflater;
private final MediaLoadingHandler mMediaLoadingHandler;
private Cursor mCursor;
private ParcelableDirectMessageCursorIndices mIndices;
private TwidereLinkify mLinkify;
private CardMediaContainer.OnMediaClickListener mEventListener;
public MessageConversationAdapter(final Context context) {
super(context);
mInflater = LayoutInflater.from(context);
mLinkify = new TwidereLinkify(new DirectMessageOnLinkClickHandler(context, null, preferences));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mMediaLoadingHandler = new MediaLoadingHandler(R.id.media_preview_progress);
mIncomingMessageColor = ThemeUtils.getUserAccentColor(context);
mOutgoingMessageColor = ThemeUtils.getCardBackgroundColor(context,
ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context));
mEventListener = new EventListener(this);
}
public MediaLoadingHandler getMediaLoadingHandler() {
return mMediaLoadingHandler;
}
public TwidereLinkify getLinkify() {
return mLinkify;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_MESSAGE_INCOMING: {
final View view = mInflater.inflate(R.layout.card_item_message_conversation_incoming, parent, false);
final MessageViewHolder holder = new IncomingMessageViewHolder(this, view);
holder.setMessageColor(mIncomingMessageColor);
holder.setTextSize(getTextSize());
return holder;
}
case ITEM_VIEW_TYPE_MESSAGE_OUTGOING: {
final View view = mInflater.inflate(R.layout.card_item_message_conversation_outgoing, parent, false);
final MessageViewHolder holder = new MessageViewHolder(this, view);
holder.setMessageColor(mOutgoingMessageColor);
holder.setTextSize(getTextSize());
return holder;
}
}
throw new UnsupportedOperationException("Unknown viewType " + viewType);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case ITEM_VIEW_TYPE_MESSAGE_INCOMING:
case ITEM_VIEW_TYPE_MESSAGE_OUTGOING: {
final Cursor c = mCursor;
c.moveToPosition(getCursorPosition(position));
((MessageViewHolder) holder).displayMessage(c, mIndices);
}
}
}
private int getCursorPosition(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
final Cursor c = mCursor;
c.moveToPosition(position);
if (c.getInt(mIndices.is_outgoing) == 1) {
return ITEM_VIEW_TYPE_MESSAGE_OUTGOING;
} else {
return ITEM_VIEW_TYPE_MESSAGE_INCOMING;
}
}
@Override
public int getItemCount() {
final Cursor c = mCursor;
if (c == null) return 0;
return c.getCount();
}
@Override
public ParcelableDirectMessage findItem(final long id) {
for (int i = 0, count = getItemCount(); i < count; i++) {
if (getItemId(i) == id) return getDirectMessage(i);
}
return null;
}
public ParcelableDirectMessage getDirectMessage(final int position) {
final Cursor c = mCursor;
if (c == null || c.isClosed()) return null;
c.moveToPosition(position);
final UserKey accountKey = UserKey.valueOf(c.getString(mIndices.account_key));
final long messageId = c.getLong(mIndices.id);
return Utils.findDirectMessageInDatabases(getContext(), accountKey, messageId);
}
@Override
public final int getMediaPreviewStyle() {
return mMediaPreviewStyle;
}
public void setCursor(final Cursor cursor) {
if (cursor != null) {
mIndices = new ParcelableDirectMessageCursorIndices(cursor);
} else {
mIndices = null;
}
mCursor = cursor;
notifyDataSetChanged();
}
public CardMediaContainer.OnMediaClickListener getOnMediaClickListener() {
return mEventListener;
}
static class EventListener implements CardMediaContainer.OnMediaClickListener {
private final WeakReference<MessageConversationAdapter> adapterRef;
public EventListener(MessageConversationAdapter adapter) {
this.adapterRef = new WeakReference<>(adapter);
}
@Override
public void onMediaClick(View view, ParcelableMedia media, UserKey accountKey, long extraId) {
final MessageConversationAdapter adapter = adapterRef.get();
IntentUtils.openMedia(adapter.getContext(), adapter.getDirectMessage((int) extraId), media,
null, adapter.preferences.getBoolean(KEY_NEW_DOCUMENT_API));
}
}
}

View File

@ -646,8 +646,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
mAccountKey, false);
}
}
ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details,
getUserColorNameManager());
ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details
);
Utils.setLastSeen(getContext(), result.mentions, System.currentTimeMillis());
final ContentValues values = new ContentValues();
values.put(Statuses.IS_FAVORITE, true);
@ -1369,8 +1369,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
try {
final ParcelableStatus result = ParcelableStatusUtils.INSTANCE.fromStatus(microBlog.retweetStatus(mStatusId),
mAccountKey, false);
ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details,
getUserColorNameManager());
ParcelableStatusUtils.INSTANCE.updateExtraInformation(result, details
);
Utils.setLastSeen(getContext(), result.mentions, System.currentTimeMillis());
final ContentValues values = new ContentValues();
values.put(Statuses.MY_RETWEET_ID, result.id);

View File

@ -163,7 +163,7 @@ public final class ContentValuesCreator implements TwidereConstants {
activity.account_color = details.color;
if (status != null) {
ParcelableStatusUtils.INSTANCE.updateExtraInformation(status, details, manager);
ParcelableStatusUtils.INSTANCE.updateExtraInformation(status, details);
activity.status_id = status.id;
activity.status_retweet_id = status.retweet_id;

View File

@ -1,690 +0,0 @@
package org.mariotaku.twidere.util;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.text.TextUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.MediaViewerActivity;
import org.mariotaku.twidere.annotation.Referral;
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
import org.mariotaku.twidere.fragment.SensitiveContentWarningDialogFragment;
import org.mariotaku.twidere.model.ParcelableDirectMessage;
import org.mariotaku.twidere.model.ParcelableGroup;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.util.ParcelableLocationUtils;
import org.mariotaku.twidere.model.util.ParcelableMediaUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import static android.text.TextUtils.isEmpty;
/**
* Created by mariotaku on 16/1/2.
*/
public class IntentUtils implements Constants {
private IntentUtils() {
}
public static String getStatusShareText(@NonNull final Context context, @NonNull final ParcelableStatus status) {
final Uri link = LinkCreator.getStatusWebLink(status);
return context.getString(R.string.status_share_text_format_with_link,
status.text_plain, link.toString());
}
public static String getStatusShareSubject(@NonNull final Context context, @NonNull final ParcelableStatus status) {
final String timeString = Utils.formatToLongTimeString(context, status.timestamp);
return context.getString(R.string.status_share_subject_format_with_time,
status.user_name, status.user_screen_name, timeString);
}
public static void openUserProfile(@NonNull final Context context, @NonNull final ParcelableUser user,
final Bundle activityOptions, final boolean newDocument,
@Referral final String referral) {
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_USER, user);
if (user.extras != null) {
extras.putString(EXTRA_PROFILE_URL, user.extras.statusnet_profile_url);
}
final Uri uri = LinkCreator.getTwidereUserLink(user.account_key, user.key, user.screen_name);
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setExtrasClassLoader(context.getClassLoader());
intent.putExtras(extras);
intent.putExtra(EXTRA_REFERRAL, referral);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
ActivityCompat.startActivity(context, intent, activityOptions);
}
public static void openUserProfile(@NonNull final Context context, @Nullable final UserKey accountKey,
final UserKey userKey, final String screenName,
final Bundle activityOptions, final boolean newDocument,
@Referral final String referral) {
final Intent intent = userProfile(accountKey, userKey, screenName, referral, null);
if (intent == null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
ActivityCompat.startActivity(context, intent, activityOptions);
}
public static Intent userProfile(@Nullable UserKey accountKey, UserKey userKey, String screenName,
@Referral String referral, String profileUrl) {
if (userKey == null && isEmpty(screenName)) return null;
final Uri uri = LinkCreator.getTwidereUserLink(accountKey, userKey, screenName);
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(EXTRA_REFERRAL, referral);
intent.putExtra(EXTRA_PROFILE_URL, profileUrl);
return intent;
}
public static void openItems(@NonNull final Context context, final List<Parcelable> items) {
if (items == null) return;
final Bundle extras = new Bundle();
extras.putParcelableArrayList(EXTRA_ITEMS, new ArrayList<>(items));
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_ITEMS);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.putExtras(extras);
context.startActivity(intent);
}
public static void openUserMentions(@NonNull final Context context, @Nullable final UserKey accountKey,
@NonNull final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_MENTIONS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openMedia(@NonNull final Context context, final ParcelableDirectMessage message,
final ParcelableMedia current, @Nullable final Bundle options,
final boolean newDocument) {
openMedia(context, message.account_key, false, null, message, current, message.media,
options, newDocument);
}
public static void openMedia(@NonNull final Context context, final ParcelableStatus status,
final ParcelableMedia current, final Bundle options,
final boolean newDocument) {
openMedia(context, status.account_key, status.is_possibly_sensitive, status, null, current,
ParcelableMediaUtils.getPrimaryMedia(status), options, newDocument);
}
public static void openMedia(@NonNull final Context context, @Nullable final UserKey accountKey, final boolean isPossiblySensitive,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
openMedia(context, accountKey, isPossiblySensitive, null, null, current, media, options, newDocument);
}
public static void openMedia(@NonNull final Context context, @Nullable final UserKey accountKey, final boolean isPossiblySensitive,
final ParcelableStatus status, final ParcelableDirectMessage message,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
if (media == null) return;
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
if (context instanceof FragmentActivity && isPossiblySensitive
&& !prefs.getBoolean(SharedPreferenceConstants.KEY_DISPLAY_SENSITIVE_CONTENTS, false)) {
final FragmentActivity activity = (FragmentActivity) context;
final FragmentManager fm = activity.getSupportFragmentManager();
final DialogFragment fragment = new SensitiveContentWarningDialogFragment();
final Bundle args = new Bundle();
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey);
args.putParcelable(EXTRA_CURRENT_MEDIA, current);
if (status != null) {
args.putParcelable(EXTRA_STATUS, status);
}
if (message != null) {
args.putParcelable(EXTRA_MESSAGE, message);
}
args.putParcelableArray(EXTRA_MEDIA, media);
args.putBundle(EXTRA_ACTIVITY_OPTIONS, options);
args.putBundle(EXTRA_ACTIVITY_OPTIONS, options);
args.putBoolean(EXTRA_NEW_DOCUMENT, newDocument);
fragment.setArguments(args);
fragment.show(fm, "sensitive_content_warning");
} else {
openMediaDirectly(context, accountKey, status, message, current, media, options,
newDocument);
}
}
public static void openMediaDirectly(@NonNull final Context context, @Nullable final UserKey accountKey,
final ParcelableStatus status, final ParcelableMedia current,
final Bundle options, final boolean newDocument) {
openMediaDirectly(context, accountKey, status, null, current, ParcelableMediaUtils.getPrimaryMedia(status),
options, newDocument);
}
public static String getDefaultBrowserPackage(Context context, Uri uri, boolean checkHandled) {
if (checkHandled && !isWebLinkHandled(context, uri)) {
return null;
}
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
Uri.Builder testBuilder = new Uri.Builder();
testBuilder.scheme(SCHEME_HTTP);
StringBuilder sb = new StringBuilder();
Random random = new Random();
int range = 'z' - 'a';
for (int i = 0; i < 20; i++) {
sb.append((char) ('a' + (Math.abs(random.nextInt()) % range)));
}
sb.append(".com");
testBuilder.authority(sb.toString());
intent.setData(testBuilder.build());
final ComponentName componentName = intent.resolveActivity(context.getPackageManager());
if (componentName == null || componentName.getClassName() == null) return null;
if (TextUtils.equals("android", componentName.getPackageName())) return null;
return componentName.getPackageName();
}
public static boolean isWebLinkHandled(Context context, Uri uri) {
final IntentFilter filter = getWebLinkIntentFilter(context);
if (filter == null) return false;
return filter.match(Intent.ACTION_VIEW, null, uri.getScheme(), uri,
Collections.singleton(Intent.CATEGORY_BROWSABLE), LOGTAG) >= 0;
}
@Nullable
public static IntentFilter getWebLinkIntentFilter(Context context) {
Intent testIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/user_name"));
testIntent.addCategory(Intent.CATEGORY_BROWSABLE);
testIntent.setPackage(context.getPackageName());
final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(testIntent,
PackageManager.GET_RESOLVED_FILTER);
return resolveInfo != null ? resolveInfo.filter : null;
}
public static void openMediaDirectly(@NonNull final Context context,
@Nullable final UserKey accountKey,
final ParcelableDirectMessage message, final ParcelableMedia current,
final ParcelableMedia[] media, final Bundle options,
final boolean newDocument) {
openMediaDirectly(context, accountKey, null, message, current, media, options, newDocument);
}
public static void openMediaDirectly(@NonNull final Context context, @Nullable final UserKey accountKey,
final ParcelableStatus status, final ParcelableDirectMessage message,
final ParcelableMedia current, final ParcelableMedia[] media,
final Bundle options, final boolean newDocument) {
if (media == null) return;
final Intent intent = new Intent(context, MediaViewerActivity.class);
intent.putExtra(EXTRA_ACCOUNT_KEY, accountKey);
intent.putExtra(EXTRA_CURRENT_MEDIA, current);
intent.putExtra(EXTRA_MEDIA, media);
if (status != null) {
intent.putExtra(EXTRA_STATUS, status);
intent.setData(getMediaViewerUri("status", status.id, accountKey));
}
if (message != null) {
intent.putExtra(EXTRA_MESSAGE, message);
intent.setData(getMediaViewerUri("message", String.valueOf(message.id), accountKey));
}
if (newDocument && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
ActivityCompat.startActivity(context, intent, options);
}
public static Uri getMediaViewerUri(@NonNull final String type, final String id,
@Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority("media");
builder.appendPath(type);
builder.appendPath(id);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
return builder.build();
}
public static void openMessageConversation(@NonNull final Context context,
@Nullable final UserKey accountKey,
final String recipientId) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
if (recipientId != null) {
builder.appendQueryParameter(QUERY_PARAM_RECIPIENT_ID, recipientId);
}
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openIncomingFriendships(@NonNull final Context context,
@Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_INCOMING_FRIENDSHIPS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openMap(@NonNull final Context context, final double latitude, final double longitude) {
if (!ParcelableLocationUtils.isValidLocation(latitude, longitude)) return;
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_MAP);
builder.appendQueryParameter(QUERY_PARAM_LAT, String.valueOf(latitude));
builder.appendQueryParameter(QUERY_PARAM_LNG, String.valueOf(longitude));
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openMutesUsers(@NonNull final Context context,
@Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_MUTES_USERS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openScheduledStatuses(@NonNull final Context context,
@Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_SCHEDULED_STATUSES);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openSavedSearches(@NonNull final Context context, @Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_SAVED_SEARCHES);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openSearch(@NonNull final Context context, @Nullable final UserKey accountKey, final String query) {
openSearch(context, accountKey, query, null);
}
public static void openSearch(@NonNull final Context context, @Nullable final UserKey accountKey, final String query, String type) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
// Some devices cannot process query parameter with hashes well, so add this intent extra
intent.putExtra(EXTRA_QUERY, query);
if (accountKey != null) {
intent.putExtra(EXTRA_ACCOUNT_KEY, accountKey);
}
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_SEARCH);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
builder.appendQueryParameter(QUERY_PARAM_QUERY, query);
if (!TextUtils.isEmpty(type)) {
builder.appendQueryParameter(QUERY_PARAM_TYPE, type);
intent.putExtra(EXTRA_TYPE, type);
}
intent.setData(builder.build());
context.startActivity(intent);
}
public static void openStatus(@NonNull final Context context, @Nullable final UserKey accountKey,
@NonNull final String statusId) {
final Uri uri = LinkCreator.getTwidereStatusLink(accountKey, statusId);
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
context.startActivity(intent);
}
public static void openStatus(@NonNull final Context context, @NonNull final ParcelableStatus status, Bundle activityOptions) {
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_STATUS, status);
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_STATUS);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, status.account_key.toString());
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, status.id);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setExtrasClassLoader(context.getClassLoader());
intent.putExtras(extras);
ActivityCompat.startActivity(context, intent, activityOptions);
}
public static void openStatusFavoriters(@NonNull final Context context, @Nullable final UserKey accountKey,
@NonNull final String statusId) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_STATUS_FAVORITERS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, statusId);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
ActivityCompat.startActivity(context, intent, null);
}
public static void openStatusRetweeters(@NonNull final Context context, @Nullable final UserKey accountKey,
@NonNull final String statusId) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_STATUS_RETWEETERS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, statusId);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
ActivityCompat.startActivity(context, intent, null);
}
public static void openTweetSearch(@NonNull final Context context, @Nullable final UserKey accountKey,
@NonNull final String query) {
openSearch(context, accountKey, query, QUERY_PARAM_VALUE_TWEETS);
}
public static void openUserBlocks(final Activity activity, final UserKey accountKey) {
if (activity == null) return;
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_BLOCKS);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
activity.startActivity(intent);
}
public static void openUserFavorites(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final UserKey userKey,
@Nullable final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_FAVORITES);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openUserFollowers(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final UserKey userKey,
@Nullable final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_FOLLOWERS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openUserFriends(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final UserKey userKey,
@Nullable final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_FRIENDS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openUserListDetails(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final String listId,
@Nullable final UserKey userId,
@Nullable final String screenName, final String listName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_LIST);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (listId != null) {
builder.appendQueryParameter(QUERY_PARAM_LIST_ID, listId);
}
if (userId != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userId.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
if (listName != null) {
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, listName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openUserListDetails(@NonNull final Context context,
@NonNull final ParcelableUserList userList) {
final UserKey userKey = userList.user_key;
final String listId = userList.id;
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_USER_LIST, userList);
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_LIST);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, userList.account_key.toString());
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
builder.appendQueryParameter(QUERY_PARAM_LIST_ID, listId);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setExtrasClassLoader(context.getClassLoader());
intent.putExtras(extras);
context.startActivity(intent);
}
public static void openGroupDetails(@NonNull final Context context, @NonNull final ParcelableGroup group) {
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_GROUP, group);
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_GROUP);
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, group.account_key.toString());
builder.appendQueryParameter(QUERY_PARAM_GROUP_ID, group.id);
builder.appendQueryParameter(QUERY_PARAM_GROUP_NAME, group.nickname);
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setExtrasClassLoader(context.getClassLoader());
intent.putExtras(extras);
context.startActivity(intent);
}
public static void openUserLists(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final UserKey userKey,
@Nullable final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_LISTS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openUserGroups(@NonNull final Context context,
@Nullable final UserKey accountKey,
@Nullable final UserKey userId,
@Nullable final String screenName) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_USER_GROUPS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
if (userId != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userId.toString());
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openDirectMessages(@NonNull final Context context, @Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_DIRECT_MESSAGES);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openInteractions(@NonNull final Context context, @Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_INTERACTIONS);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openPublicTimeline(@NonNull final Context context, @Nullable final UserKey accountKey) {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_PUBLIC_TIMELINE);
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString());
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
}
public static void openAccountsManager(Context context) {
final Intent intent = new Intent();
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_ACCOUNTS);
intent.setData(builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openDrafts(Context context) {
final Intent intent = new Intent();
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_DRAFTS);
intent.setData(builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openProfileEditor(Context context, @Nullable UserKey accountId) {
final Intent intent = new Intent();
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_PROFILE_EDITOR);
if (accountId != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountId.toString());
}
intent.setData(builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void openFilters(Context context) {
final Intent intent = new Intent();
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_FILTERS);
intent.setData(builder.build());
intent.setPackage(BuildConfig.APPLICATION_ID);
context.startActivity(intent);
}
public static void applyNewDocument(Intent intent, boolean enable) {
if (enable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
}
}

View File

@ -173,7 +173,7 @@ public class KeyboardShortcutsHandler implements KeyboardShortcutConstants {
return true;
}
case ACTION_MESSAGE: {
IntentUtils.openMessageConversation(context, null, null);
IntentUtils.INSTANCE.openMessageConversation(context, null, null);
return true;
}
}

View File

@ -310,8 +310,8 @@ public final class Utils implements Constants {
public static Intent createStatusShareIntent(@NonNull final Context context, @NonNull final ParcelableStatus status) {
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, IntentUtils.getStatusShareSubject(context, status));
intent.putExtra(Intent.EXTRA_TEXT, IntentUtils.getStatusShareText(context, status));
intent.putExtra(Intent.EXTRA_SUBJECT, IntentUtils.INSTANCE.getStatusShareSubject(context, status));
intent.putExtra(Intent.EXTRA_TEXT, IntentUtils.INSTANCE.getStatusShareText(context, status));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
return intent;
}

View File

@ -58,6 +58,7 @@ import org.mariotaku.twidere.preference.iface.IDialogPreference
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.support.ActivitySupport
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat
import org.mariotaku.twidere.util.theme.TwidereAppearanceCreator
@ -92,6 +93,8 @@ open class BaseActivity : ChameleonActivity(), IExtendedActivity<BaseActivity>,
lateinit var userColorNameManager: UserColorNameManager
@Inject
lateinit var permissionsManager: PermissionsManager
@Inject
lateinit var extraFeaturesService: ExtraFeaturesService
private val actionHelper = IExtendedActivity.ActionHelper(this)

View File

@ -20,11 +20,9 @@ import java.util.concurrent.atomic.AtomicBoolean
class PremiumDashboardActivity : BaseActivity() {
private lateinit var extraFeaturesService: ExtraFeaturesService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
extraFeaturesService = ExtraFeaturesService.newInstance(this)
setContentView(R.layout.activity_premium_dashboard)
if (extraFeaturesService.isSupported()) {
extraFeaturesService.getDashboardLayouts().forEach { layout ->

View File

@ -127,18 +127,18 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
when (adapter.getItemViewType(position)) {
SuggestionsAdapter.VIEW_TYPE_USER_SUGGESTION_ITEM -> {
IntentUtils.openUserProfile(this, selectedAccountDetails?.key,
UserKey.valueOf(item.extra_id!!), item.summary, null,
preferences[newDocumentApiKey],
Referral.DIRECT)
UserKey.valueOf(item.extra_id!!), item.summary, preferences[newDocumentApiKey],
Referral.DIRECT,
null)
finish()
}
SuggestionsAdapter.VIEW_TYPE_USER_SCREEN_NAME -> {
IntentUtils.openUserProfile(this, selectedAccountDetails?.key, null, item.title,
null, preferences[newDocumentApiKey], Referral.DIRECT)
preferences[newDocumentApiKey], Referral.DIRECT, null)
finish()
}
SuggestionsAdapter.VIEW_TYPE_SAVED_SEARCH, SuggestionsAdapter.VIEW_TYPE_SEARCH_HISTORY -> {
IntentUtils.openSearch(this, selectedAccountDetails?.key, item.title)
IntentUtils.openSearch(this, selectedAccountDetails?.key, item.title!!)
finish()
}
}

View File

@ -0,0 +1,167 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter
import android.content.Context
import android.database.Cursor
import android.support.v7.widget.RecyclerView.ViewHolder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IDirectMessagesAdapter
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.model.ParcelableDirectMessage
import org.mariotaku.twidere.model.ParcelableDirectMessageCursorIndices
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.DirectMessageOnLinkClickHandler
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.MediaLoadingHandler
import org.mariotaku.twidere.util.ThemeUtils
import org.mariotaku.twidere.util.TwidereLinkify
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.view.CardMediaContainer
import org.mariotaku.twidere.view.holder.IncomingMessageViewHolder
import org.mariotaku.twidere.view.holder.MessageViewHolder
import java.lang.ref.WeakReference
class MessageConversationAdapter(context: Context) : BaseRecyclerViewAdapter<ViewHolder>(context), Constants, IDirectMessagesAdapter {
private val outgoingMessageColor: Int = ThemeUtils.getCardBackgroundColor(context,
ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context))
private val incomingMessageColor: Int = ThemeUtils.getUserAccentColor(context)
override val mediaPreviewStyle: Int = Utils.getMediaPreviewStyle(preferences.getString(SharedPreferenceConstants.KEY_MEDIA_PREVIEW_STYLE, null))
private val inflater: LayoutInflater = LayoutInflater.from(context)
val mediaLoadingHandler: MediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
val linkify: TwidereLinkify = TwidereLinkify(DirectMessageOnLinkClickHandler(context, null, preferences))
val onMediaClickListener: CardMediaContainer.OnMediaClickListener
private var cursor: Cursor? = null
private var indices: ParcelableDirectMessageCursorIndices? = null
init {
onMediaClickListener = EventListener(this)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
when (viewType) {
ITEM_VIEW_TYPE_MESSAGE_INCOMING -> {
val view = inflater.inflate(R.layout.card_item_message_conversation_incoming, parent, false)
val holder = IncomingMessageViewHolder(this, view)
holder.setMessageColor(incomingMessageColor)
holder.setTextSize(textSize)
return holder
}
ITEM_VIEW_TYPE_MESSAGE_OUTGOING -> {
val view = inflater.inflate(R.layout.card_item_message_conversation_outgoing, parent, false)
val holder = MessageViewHolder(this, view)
holder.setMessageColor(outgoingMessageColor)
holder.setTextSize(textSize)
return holder
}
}
throw UnsupportedOperationException("Unknown viewType " + viewType)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (holder.itemViewType) {
ITEM_VIEW_TYPE_MESSAGE_INCOMING, ITEM_VIEW_TYPE_MESSAGE_OUTGOING -> {
val c = cursor
c!!.moveToPosition(getCursorPosition(position))
(holder as MessageViewHolder).displayMessage(c, indices!!)
}
}
}
private fun getCursorPosition(position: Int): Int {
return position
}
override fun getItemViewType(position: Int): Int {
val c = cursor!!
val i = indices!!
c.moveToPosition(getCursorPosition(position))
if (c.getInt(i.is_outgoing) == 1) {
return ITEM_VIEW_TYPE_MESSAGE_OUTGOING
} else {
return ITEM_VIEW_TYPE_MESSAGE_INCOMING
}
}
override fun getItemCount(): Int {
val c = cursor ?: return 0
return c.count
}
override fun findItem(id: Long): ParcelableDirectMessage? {
for (i in 0 until itemCount) {
if (getItemId(i) == id) return getDirectMessage(i)
}
return null
}
fun getDirectMessage(position: Int): ParcelableDirectMessage? {
val c = cursor
if (c == null || c.isClosed) return null
c.moveToPosition(position)
val accountKey = UserKey.valueOf(c.getString(indices!!.account_key))
val messageId = c.getLong(indices!!.id)
return Utils.findDirectMessageInDatabases(context, accountKey, messageId)
}
fun setCursor(cursor: Cursor?) {
if (cursor != null) {
indices = ParcelableDirectMessageCursorIndices(cursor)
} else {
indices = null
}
this.cursor = cursor
notifyDataSetChanged()
}
internal class EventListener(adapter: MessageConversationAdapter) : CardMediaContainer.OnMediaClickListener {
private val adapterRef: WeakReference<MessageConversationAdapter>
init {
this.adapterRef = WeakReference(adapter)
}
override fun onMediaClick(view: View, media: ParcelableMedia, accountKey: UserKey, extraId: Long) {
val adapter = adapterRef.get()
IntentUtils.openMedia(adapter.context, adapter.getDirectMessage(extraId.toInt())!!, media,
adapter.preferences[newDocumentApiKey], adapter.preferences[displaySensitiveContentsKey])
}
}
companion object {
private val ITEM_VIEW_TYPE_MESSAGE_OUTGOING = 1
private val ITEM_VIEW_TYPE_MESSAGE_INCOMING = 2
}
}

View File

@ -387,11 +387,7 @@ class ParcelableActivitiesAdapter(
internal class EventListener(adapter: ParcelableActivitiesAdapter) : IStatusViewHolder.StatusClickListener, IGapSupportedAdapter.GapClickListener, IActivitiesAdapter.ActivityEventListener {
val adapterRef: WeakReference<ParcelableActivitiesAdapter>
init {
adapterRef = WeakReference(adapter)
}
val adapterRef = WeakReference(adapter)
override fun onGapClick(holder: GapViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
@ -413,8 +409,8 @@ class ParcelableActivitiesAdapter(
val adapter = adapterRef.get() ?: return
val status = adapter.getActivity(position)?.getActivityStatus() ?: return
IntentUtils.openUserProfile(adapter.context, status.account_key, status.user_key,
status.user_screen_name, null, adapter.preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.TIMELINE_STATUS)
status.user_screen_name, adapter.preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.TIMELINE_STATUS,
null)
}
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {

View File

@ -10,6 +10,7 @@ import org.mariotaku.twidere.Constants.KEY_DISPLAY_PROFILE_IMAGE
import org.mariotaku.twidere.Constants.KEY_NO_CLOSE_AFTER_TWEET_SENT
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_DISPLAY_SENSITIVE_CONTENTS
import org.mariotaku.twidere.extension.getNonEmptyString
import org.mariotaku.twidere.model.CustomAPIConfig
import org.mariotaku.twidere.model.account.cred.Credentials

View File

@ -51,10 +51,8 @@ import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter.Companion.ITEM_
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
import org.mariotaku.twidere.constant.readFromBottomKey
import org.mariotaku.twidere.constant.rememberPositionKey
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.fragment.AbsStatusesFragment.DefaultOnLikedListener
import org.mariotaku.twidere.loader.iface.IExtendedLoader
@ -299,7 +297,8 @@ abstract class AbsActivitiesFragment protected constructor() :
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, position: Int) {
val status = adapter.getActivity(position)?.getActivityStatus() ?: return
IntentUtils.openMedia(activity, status, media, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, status, media, preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey],
null)
// BEGIN HotMobi
val event = MediaEvent.create(activity, status, media, timelineType, adapter.mediaPreviewEnabled)
HotMobiLogger.getInstance(activity).log(status.account_key, event)

View File

@ -47,11 +47,9 @@ import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.constant.readFromBottomKey
import org.mariotaku.twidere.constant.rememberPositionKey
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
import org.mariotaku.twidere.loader.iface.IExtendedLoader
@ -354,8 +352,8 @@ abstract class AbsStatusesFragment protected constructor() :
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
val status = adapter.getStatus(statusPosition) ?: return
IntentUtils.openMedia(activity, status, media, null,
preferences.getBoolean(SharedPreferenceConstants.KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, status, media, preferences[newDocumentApiKey],
preferences[displaySensitiveContentsKey])
// BEGIN HotMobi
val event = MediaEvent.create(activity, status, media, timelineType,
adapter.mediaPreviewEnabled)
@ -420,11 +418,11 @@ abstract class AbsStatusesFragment protected constructor() :
}
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position)
val intent = IntentUtils.userProfile(status!!.account_key, status.user_key,
val status = adapter.getStatus(position)!!
val intent = IntentUtils.userProfile(status.account_key, status.user_key,
status.user_screen_name, Referral.TIMELINE_STATUS,
status.extras.user_statusnet_profile_url)
IntentUtils.applyNewDocument(intent, preferences.getBoolean(SharedPreferenceConstants.KEY_NEW_DOCUMENT_API))
IntentUtils.applyNewDocument(intent, preferences[newDocumentApiKey])
startActivity(intent)
}

View File

@ -233,14 +233,14 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
val account = accountsAdapter.selectedAccount ?: return
val activity = activity
if (account.user != null) {
IntentUtils.openUserProfile(activity, account.user!!, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.SELF_PROFILE)
IntentUtils.openUserProfile(activity, account.user!!, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.SELF_PROFILE,
null)
} else {
IntentUtils.openUserProfile(activity, account.key, account.key,
account.user.screen_name, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.SELF_PROFILE)
account.user.screen_name, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.SELF_PROFILE,
null)
}
}
}

View File

@ -150,8 +150,8 @@ class AccountsManagerFragment : BaseFragment(), LoaderManager.LoaderCallbacks<Li
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val account = adapter.getItem(position)
IntentUtils.openUserProfile(context, account.user, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.SELF_PROFILE)
IntentUtils.openUserProfile(context, account.user, preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.SELF_PROFILE,
null)
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<AccountDetails>> {

View File

@ -25,6 +25,7 @@ import com.squareup.otto.Bus
import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import javax.inject.Inject
open class BaseDialogFragment : DialogFragment() {
@ -43,6 +44,8 @@ open class BaseDialogFragment : DialogFragment() {
lateinit var keyboardShortcutsHandler: KeyboardShortcutsHandler
@Inject
lateinit var bus: Bus
@Inject
lateinit var extraFeaturesService: ExtraFeaturesService
override fun onAttach(context: Context?) {
super.onAttach(context)
@ -50,6 +53,7 @@ open class BaseDialogFragment : DialogFragment() {
}
override fun onDestroy() {
extraFeaturesService.release()
super.onDestroy()
DebugModeUtils.watchReferenceLeak(this)
}

View File

@ -37,6 +37,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
import org.mariotaku.sqliteqb.library.ArgsArray
@ -55,6 +56,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.ACTION_NAVIGATION_REFRESH
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NEW_DOCUMENT_API
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.model.BaseRefreshTaskParam
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey
@ -192,9 +194,8 @@ class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntries
}
override fun onUserClick(position: Int, entry: DirectMessageEntry) {
IntentUtils.openUserProfile(activity, entry.account_key,
UserKey.valueOf(entry.conversation_id), entry.screen_name, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API), null)
IntentUtils.openUserProfile(activity, entry.account_key, UserKey.valueOf(entry.conversation_id),
entry.screen_name, preferences[newDocumentApiKey])
}
@Subscribe

View File

@ -26,18 +26,10 @@ import org.mariotaku.twidere.util.premium.ExtraFeaturesService
class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
private lateinit var extraFeaturesService: ExtraFeaturesService
val feature: String get() = arguments.getString(EXTRA_FEATURE)
val requestCode: Int get() = arguments.getInt(EXTRA_REQUEST_CODE, 0)
override fun onDestroy() {
extraFeaturesService.release()
super.onDestroy()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
extraFeaturesService = ExtraFeaturesService.newInstance(context)
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.title_extra_features)
builder.setView(R.layout.dialog_extra_features_introduction)

View File

@ -16,12 +16,15 @@ import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaEvent
import edu.tsinghua.hotmobi.model.TimelineType
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.VariousItemsAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ITEMS
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NEW_DOCUMENT_API
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.MenuUtils
@ -71,8 +74,8 @@ class ItemsListFragment : AbsContentListRecyclerViewFragment<VariousItemsAdapter
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
val status = dummyItemAdapter.getStatus(statusPosition) ?: return
IntentUtils.openMedia(activity, status, media, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, status, media, preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey],
null)
// BEGIN HotMobi
val event = MediaEvent.create(activity, status, media,
TimelineType.OTHER, dummyItemAdapter.mediaPreviewEnabled)
@ -84,16 +87,15 @@ class ItemsListFragment : AbsContentListRecyclerViewFragment<VariousItemsAdapter
val activity = activity
val status = dummyItemAdapter.getStatus(position) ?: return
IntentUtils.openUserProfile(activity, status.account_key, status.user_key,
status.user_screen_name, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.TIMELINE_STATUS)
status.user_screen_name, preferences[newDocumentApiKey])
}
}
dummyItemAdapter.userClickListener = object : IUsersAdapter.SimpleUserClickListener() {
override fun onUserClick(holder: UserViewHolder, position: Int) {
val user = dummyItemAdapter.getUser(position) ?: return
IntentUtils.openUserProfile(getContext(), user, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.TIMELINE_STATUS)
IntentUtils.openUserProfile(getContext(), user, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.TIMELINE_STATUS,
null)
}
}
return adapter

View File

@ -401,7 +401,7 @@ class MessagesConversationFragment : BaseFragment(), LoaderCallbacks<Cursor?>, O
if (menuInfo == null) return
val inflater = MenuInflater(context)
val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo?
val message = adapter!!.getDirectMessage(contextMenuInfo!!.position)
val message = adapter!!.getDirectMessage(contextMenuInfo!!.position)!!
menu.setHeaderTitle(message.text_unescaped)
inflater.inflate(R.menu.action_direct_message, menu)
}

View File

@ -215,7 +215,6 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
}
private fun updateFavoritedStatus(status: ParcelableStatus) {
val context = activity ?: return
replaceStatusStates(status)
}

View File

@ -30,6 +30,7 @@ import android.view.KeyEvent
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.commons.parcel.ParcelUtils
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration
@ -40,6 +41,7 @@ import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_SIMPLE_LAYOUT
import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
@ -143,8 +145,7 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
override fun onUserClick(holder: UserViewHolder, position: Int) {
val user = adapter.getUser(position) ?: return
IntentUtils.openUserProfile(activity, user, null,
preferences.getBoolean(SharedPreferenceConstants.KEY_NEW_DOCUMENT_API), userReferral)
IntentUtils.openUserProfile(activity, user, preferences[newDocumentApiKey], userReferral)
}
override fun onFollowClicked(holder: UserViewHolder, position: Int) {

View File

@ -291,8 +291,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
val status = adapter.getStatus(statusPosition) ?: return
IntentUtils.openMedia(activity, status, media, null,
preferences.getBoolean(SharedPreferenceConstants.KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, status, media, preferences[newDocumentApiKey],
preferences[displaySensitiveContentsKey])
val event = MediaEvent.create(activity, status, media, TimelineType.DETAILS,
adapter.mediaPreviewEnabled)
@ -311,7 +311,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(activity, status.account_key, status.quoted_id)
IntentUtils.openStatus(activity, status)
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
@ -332,15 +332,15 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position)!!
IntentUtils.openUserProfile(activity, status.account_key, status.user_key,
status.user_screen_name, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.TIMELINE_STATUS)
status.user_screen_name, preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.TIMELINE_STATUS,
null)
}
override fun onMediaClick(view: View, media: ParcelableMedia?, accountKey: UserKey, extraId: Long) {
val status = adapter.status
if (status == null || media == null) return
IntentUtils.openMediaDirectly(activity, accountKey, status, media, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API))
IntentUtils.openMediaDirectly(activity, accountKey, status, media, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
null)
// BEGIN HotMobi
val event = MediaEvent.create(activity, status, media, TimelineType.OTHER,
adapter.mediaPreviewEnabled)
@ -678,8 +678,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
}
private fun onUserClick(user: ParcelableUser) {
IntentUtils.openUserProfile(context, user, null, true,
Referral.TIMELINE_STATUS)
IntentUtils.openUserProfile(context, user, true, Referral.TIMELINE_STATUS,
null)
}
class LoadSensitiveImageConfirmDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
@ -1057,15 +1057,15 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
itemView.profileContainer -> {
val activity = fragment.activity
IntentUtils.openUserProfile(activity, status.account_key, status.user_key,
status.user_screen_name, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.STATUS)
status.user_screen_name, preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.STATUS,
null)
}
retweetedByView -> {
if (status.retweet_id != null) {
IntentUtils.openUserProfile(adapter.context, status.account_key,
status.retweeted_by_user_key, status.retweeted_by_user_screen_name,
null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.STATUS)
preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.STATUS,
null)
}
}
locationView -> {
@ -1406,8 +1406,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private fun expandOrOpenMedia(current: ParcelableMedia) {
if (adapter.isDetailMediaExpanded) {
IntentUtils.openMedia(adapter.context, adapter.status, current, null,
preferences[newDocumentApiKey])
IntentUtils.openMedia(adapter.context, adapter.status!!, current,
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
return
}
adapter.isDetailMediaExpanded = true
@ -1448,7 +1448,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private var recyclerView: RecyclerView? = null
private var statusViewHolder: DetailStatusViewHolder? = null
private val mItemCounts: IntArray
private val itemCounts: IntArray
override val nameFirst: Boolean
private val cardBackgroundColor: Int
@ -1492,13 +1492,12 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
init {
setHasStableIds(true)
val context = fragment.activity
val res = context.resources
mItemCounts = IntArray(ITEM_TYPES_SUM)
itemCounts = IntArray(ITEM_TYPES_SUM)
// There's always a space at the end of the list
mItemCounts[ITEM_IDX_SPACE] = 1
mItemCounts[ITEM_IDX_STATUS] = 1
mItemCounts[ITEM_IDX_CONVERSATION_LOAD_MORE] = 1
mItemCounts[ITEM_IDX_REPLY_LOAD_MORE] = 1
itemCounts[ITEM_IDX_SPACE] = 1
itemCounts[ITEM_IDX_STATUS] = 1
itemCounts[ITEM_IDX_CONVERSATION_LOAD_MORE] = 1
itemCounts[ITEM_IDX_REPLY_LOAD_MORE] = 1
inflater = LayoutInflater.from(context)
mediaLoadingHandler = MediaLoadingHandler(R.id.media_preview_progress)
cardBackgroundColor = ThemeUtils.getCardBackgroundColor(context,
@ -1506,13 +1505,12 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
ThemeUtils.getUserThemeBackgroundAlpha(context))
nameFirst = preferences[nameFirstKey]
mediaPreviewStyle = preferences[mediaPreviewStyleKey]
linkHighlightingStyle = Utils.getLinkHighlightingStyleInt(preferences.getString(SharedPreferenceConstants.KEY_LINK_HIGHLIGHT_OPTION, null))
linkHighlightingStyle = preferences[linkHighlightOptionKey]
mediaPreviewEnabled = preferences[mediaPreviewKey]
sensitiveContentEnabled = preferences.getBoolean(SharedPreferenceConstants.KEY_DISPLAY_SENSITIVE_CONTENTS, false)
mShowCardActions = !preferences[hideCardActionsKey]
useStarsForLikes = preferences[iWantMyStarsBackKey]
val listener = StatusAdapterLinkClickHandler<List<ParcelableStatus>>(context,
preferences)
val listener = StatusAdapterLinkClickHandler<List<ParcelableStatus>>(context, preferences)
listener.setAdapter(this)
twidereLinkify = TwidereLinkify(listener)
}
@ -1538,7 +1536,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
fun getIndexStart(index: Int): Int {
if (index == 0) return 0
return TwidereMathUtils.sum(mItemCounts, 0, index - 1)
return TwidereMathUtils.sum(itemCounts, 0, index - 1)
}
override fun getStatusId(position: Int): String? {
@ -1795,7 +1793,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override fun getItemCount(): Int {
if (status == null) return 0
return TwidereMathUtils.sum(mItemCounts)
return TwidereMathUtils.sum(itemCounts)
}
override fun onAttachedToRecyclerView(recyclerView: RecyclerView?) {
@ -1809,12 +1807,12 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
}
private fun setTypeCount(idx: Int, size: Int) {
mItemCounts[idx] = size
itemCounts[idx] = size
notifyDataSetChanged()
}
fun getTypeCount(idx: Int): Int {
return mItemCounts[idx]
return itemCounts[idx]
}
fun setReplyError(error: CharSequence?) {

View File

@ -100,6 +100,8 @@ import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
import org.mariotaku.twidere.fragment.UserTimelineFragment.UserTimelineFragmentDelegate
@ -626,7 +628,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
@Referral
val referral = arguments.getString(EXTRA_REFERRAL)
IntentUtils.openUserProfile(activity, accountKey, user.key, user.screen_name,
null, preferences.getBoolean(KEY_NEW_DOCUMENT_API), referral)
preferences.getBoolean(KEY_NEW_DOCUMENT_API), referral, null)
}
}
}
@ -1143,8 +1145,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val profileImage = ParcelableMediaUtils.image(url)
profileImage.type = ParcelableMedia.Type.IMAGE
val media = arrayOf(profileImage)
IntentUtils.openMedia(activity, user.account_key, false, null, media, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, user.account_key, media, null, false,
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
}
R.id.profileBanner -> {
val bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user) ?: return
@ -1153,8 +1155,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val profileBanner = ParcelableMediaUtils.image(url)
profileBanner.type = ParcelableMedia.Type.IMAGE
val media = arrayOf(profileBanner)
IntentUtils.openMedia(activity, user.account_key, false, null, media, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API))
IntentUtils.openMedia(activity, user.account_key, media, null, false,
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
}
R.id.listedContainer -> {
IntentUtils.openUserLists(getActivity(), user.account_key, user.key,
@ -1191,8 +1193,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val user = user ?: return false
when (type) {
TwidereLinkify.LINK_TYPE_MENTION -> {
IntentUtils.openUserProfile(activity, user.account_key, null, link, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.USER_MENTION)
IntentUtils.openUserProfile(activity, user.account_key, null, link, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
Referral.USER_MENTION, null)
return true
}
TwidereLinkify.LINK_TYPE_HASHTAG -> {

View File

@ -276,8 +276,8 @@ class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener, LoaderCa
R.id.profileImage -> {
val userList = this.userList ?: return
IntentUtils.openUserProfile(activity, userList.account_key,
userList.user_key, userList.user_screen_name, null,
preferences.getBoolean(KEY_NEW_DOCUMENT_API), null)
userList.user_key, userList.user_screen_name, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
null, null)
}
}

View File

@ -27,9 +27,11 @@ import android.view.MenuItem
import android.view.View
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.loader.UserListMembersLoader
import org.mariotaku.twidere.model.ParcelableUserList
@ -82,7 +84,6 @@ class UserListMembersFragment : CursorUsersListFragment() {
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
if (!userVisibleHint || menuInfo == null) return
val userList = userList ?: return
val args = arguments
val accountId = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
@ -91,7 +92,7 @@ class UserListMembersFragment : CursorUsersListFragment() {
val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo?
inflater.inflate(R.menu.action_user_list_member, menu)
val user = adapter.getUser(contextMenuInfo!!.position)
menu.setHeaderTitle(userColorNameManager.getDisplayName(user, preferences.getBoolean(KEY_NAME_FIRST)))
menu.setHeaderTitle(userColorNameManager.getDisplayName(user, preferences[nameFirstKey]))
}
override fun onContextItemSelected(item: MenuItem?): Boolean {

View File

@ -28,9 +28,6 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
*/
class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridParcelableStatusesAdapter, StaggeredGridLayoutManager>(), LoaderCallbacks<List<ParcelableStatus>>, DrawerCallback, IStatusViewHolder.StatusClickListener {
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
layoutManager.scrollToPositionWithOffset(position, offset)
}
override var refreshing: Boolean
get() {
@ -42,6 +39,18 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
}
override val reachingEnd: Boolean
get() {
val lm = layoutManager
return ArrayUtils.contains(lm.findLastCompletelyVisibleItemPositions(null), lm.itemCount - 1)
}
override val reachingStart: Boolean
get() {
val lm = layoutManager
return ArrayUtils.contains(lm.findFirstCompletelyVisibleItemPositions(null), 0)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter.statusClickListener = this
@ -59,15 +68,8 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
return StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
}
fun getStatuses(maxId: String?, sinceId: String?): Int {
if (context == null) return -1
val args = Bundle(arguments)
args.putBoolean(EXTRA_MAKE_GAP, false)
args.putString(EXTRA_MAX_ID, maxId)
args.putString(EXTRA_SINCE_ID, sinceId)
args.putBoolean(EXTRA_FROM_USER, true)
loaderManager.restartLoader(0, args, this)
return 0
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
layoutManager.scrollToPositionWithOffset(position, offset)
}
override fun onCreateAdapter(context: Context): StaggeredGridParcelableStatusesAdapter {
@ -110,18 +112,6 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
adapter.setData(null)
}
override val reachingEnd: Boolean
get() {
val lm = layoutManager
return ArrayUtils.contains(lm.findLastCompletelyVisibleItemPositions(null), lm.itemCount - 1)
}
override val reachingStart: Boolean
get() {
val lm = layoutManager
return ArrayUtils.contains(lm.findFirstCompletelyVisibleItemPositions(null), 0)
}
override fun onLoadMoreContents(position: Long) {
// Only supports load from end, skip START flag
if (position and ILoadMoreSupportAdapter.START != 0L) return
@ -132,10 +122,6 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
}
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
}
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(context, status, null)
@ -146,23 +132,15 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
IntentUtils.openStatus(context, status.account_key, status.quoted_id)
}
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
return false
fun getStatuses(maxId: String?, sinceId: String?): Int {
if (context == null) return -1
val args = Bundle(arguments)
args.putBoolean(EXTRA_MAKE_GAP, false)
args.putString(EXTRA_MAX_ID, maxId)
args.putString(EXTRA_SINCE_ID, sinceId)
args.putBoolean(EXTRA_FROM_USER, true)
loaderManager.restartLoader(0, args, this)
return 0
}
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
}
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
}
override fun onItemMenuClick(holder: RecyclerView.ViewHolder, menuView: View, position: Int) {
}
override fun onGapClick(holder: GapViewHolder, position: Int) {
}
}

View File

@ -159,7 +159,7 @@ abstract class MicroBlogAPIStatusesLoader(
val item = ParcelableStatusUtils.fromStatus(status, accountKey, insertGap && isGapEnabled && minIdx == i)
item.position_key = GetStatusesTask.getPositionKey(item.timestamp, item.sort_id, lastSortId,
sortDiff, i, statuses.size)
ParcelableStatusUtils.updateExtraInformation(item, details, userColorNameManager)
ParcelableStatusUtils.updateExtraInformation(item, details)
data.add(item)
}
}

View File

@ -73,7 +73,7 @@ class ParcelableStatusLoader(
if (details == null) return SingleResponse(MicroBlogException("No account"))
try {
val status = findStatus(context, accountKey, statusId)
ParcelableStatusUtils.updateExtraInformation(status, details, userColorNameManager)
ParcelableStatusUtils.updateExtraInformation(status, details)
val response = SingleResponse(status)
response.extras[EXTRA_ACCOUNT] = details
return response

View File

@ -263,7 +263,7 @@ object ParcelableStatusUtils {
}
}
fun updateExtraInformation(status: ParcelableStatus, details: AccountDetails, manager: UserColorNameManager) {
fun updateExtraInformation(status: ParcelableStatus, details: AccountDetails) {
status.account_color = details.color
}

View File

@ -76,7 +76,6 @@ class DefaultAPIPreference @JvmOverloads constructor(context: Context,
private var editNoVersionSuffixChanged: Boolean = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val preference = preference
val dialog = super.onCreateDialog(savedInstanceState)
dialog.setOnShowListener { dialog ->

View File

@ -36,8 +36,7 @@ class DestroyStatusTask(
try {
status = ParcelableStatusUtils.fromStatus(microBlog.destroyStatus(statusId),
accountKey, false)
ParcelableStatusUtils.updateExtraInformation(status, details,
userColorNameManager)
ParcelableStatusUtils.updateExtraInformation(status, details)
deleteStatus = true
return SingleResponse(status)
} catch (e: MicroBlogException) {

View File

@ -177,7 +177,7 @@ abstract class GetStatusesTask(
val item = statuses[i]
val status = ParcelableStatusUtils.fromStatus(item, accountKey,
false)
ParcelableStatusUtils.updateExtraInformation(status, details, manager)
ParcelableStatusUtils.updateExtraInformation(status, details)
status.position_key = getPositionKey(status.timestamp, status.sort_id, lastSortId,
sortDiff, i, statuses.size)
status.inserted_date = System.currentTimeMillis()

View File

@ -0,0 +1,720 @@
package org.mariotaku.twidere.util
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.support.v4.app.ActivityCompat
import android.support.v4.app.FragmentActivity
import android.text.TextUtils
import android.text.TextUtils.isEmpty
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_ACCOUNTS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_DIRECT_MESSAGES
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_DIRECT_MESSAGES_CONVERSATION
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_DRAFTS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_FILTERS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_GROUP
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_INCOMING_FRIENDSHIPS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_INTERACTIONS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_ITEMS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_MAP
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_MUTES_USERS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_PROFILE_EDITOR
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_PUBLIC_TIMELINE
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_SAVED_SEARCHES
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_SCHEDULED_STATUSES
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_SEARCH
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_STATUS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_STATUS_FAVORITERS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_STATUS_RETWEETERS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_BLOCKS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_FAVORITES
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_FOLLOWERS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_FRIENDS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_GROUPS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_LIST
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_LISTS
import org.mariotaku.twidere.TwidereConstants.AUTHORITY_USER_MENTIONS
import org.mariotaku.twidere.TwidereConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.TwidereConstants.EXTRA_ACTIVITY_OPTIONS
import org.mariotaku.twidere.TwidereConstants.EXTRA_CURRENT_MEDIA
import org.mariotaku.twidere.TwidereConstants.EXTRA_GROUP
import org.mariotaku.twidere.TwidereConstants.EXTRA_MEDIA
import org.mariotaku.twidere.TwidereConstants.EXTRA_MESSAGE
import org.mariotaku.twidere.TwidereConstants.EXTRA_NEW_DOCUMENT
import org.mariotaku.twidere.TwidereConstants.EXTRA_QUERY
import org.mariotaku.twidere.TwidereConstants.EXTRA_STATUS
import org.mariotaku.twidere.TwidereConstants.EXTRA_TYPE
import org.mariotaku.twidere.TwidereConstants.EXTRA_USER
import org.mariotaku.twidere.TwidereConstants.EXTRA_USER_LIST
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_ACCOUNT_KEY
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_GROUP_ID
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_GROUP_NAME
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_LAT
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_LIST_ID
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_LIST_NAME
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_LNG
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_QUERY
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_RECIPIENT_ID
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_SCREEN_NAME
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_STATUS_ID
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_TYPE
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_USER_KEY
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_VALUE_TWEETS
import org.mariotaku.twidere.TwidereConstants.SCHEME_HTTP
import org.mariotaku.twidere.TwidereConstants.SCHEME_TWIDERE
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.activity.MediaViewerActivity
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.fragment.SensitiveContentWarningDialogFragment
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import java.util.*
/**
* Created by mariotaku on 16/1/2.
*/
object IntentUtils {
fun getStatusShareText(context: Context, status: ParcelableStatus): String {
val link = LinkCreator.getStatusWebLink(status)
return context.getString(R.string.status_share_text_format_with_link,
status.text_plain, link.toString())
}
fun getStatusShareSubject(context: Context, status: ParcelableStatus): String {
val timeString = Utils.formatToLongTimeString(context, status.timestamp)
return context.getString(R.string.status_share_subject_format_with_time,
status.user_name, status.user_screen_name, timeString)
}
fun openUserProfile(context: Context, user: ParcelableUser,
newDocument: Boolean, @Referral referral: String? = null,
activityOptions: Bundle? = null) {
val extras = Bundle()
extras.putParcelable(EXTRA_USER, user)
if (user.extras != null) {
extras.putString(EXTRA_PROFILE_URL, user.extras.statusnet_profile_url)
}
val uri = LinkCreator.getTwidereUserLink(user.account_key, user.key, user.screen_name)
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.setExtrasClassLoader(context.classLoader)
intent.putExtras(extras)
if (referral != null) {
intent.putExtra(EXTRA_REFERRAL, referral)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
}
ActivityCompat.startActivity(context, intent, activityOptions)
}
fun openUserProfile(context: Context, accountKey: UserKey?,
userKey: UserKey?, screenName: String?,
newDocument: Boolean, @Referral referral: String? = null,
activityOptions: Bundle? = null) {
val intent = userProfile(accountKey, userKey, screenName, referral, null) ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && newDocument) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
}
ActivityCompat.startActivity(context, intent, activityOptions)
}
fun userProfile(accountKey: UserKey?, userKey: UserKey?, screenName: String?,
@Referral referral: String? = null, profileUrl: String?): Intent {
val uri = LinkCreator.getTwidereUserLink(accountKey, userKey, screenName)
val intent = Intent(Intent.ACTION_VIEW, uri)
if (referral != null) {
intent.putExtra(EXTRA_REFERRAL, referral)
}
intent.putExtra(EXTRA_PROFILE_URL, profileUrl)
return intent
}
fun openItems(context: Context, items: List<Parcelable>?) {
if (items == null) return
val extras = Bundle()
extras.putParcelableArrayList(EXTRA_ITEMS, ArrayList(items))
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_ITEMS)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.putExtras(extras)
context.startActivity(intent)
}
fun openUserMentions(context: Context, accountKey: UserKey?,
screenName: String) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_MENTIONS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openMedia(context: Context, message: ParcelableDirectMessage,
current: ParcelableMedia? = null, newDocument: Boolean,
displaySensitiveContents: Boolean, options: Bundle? = null) {
openMedia(context, message.account_key, false, null, message, current, message.media,
newDocument, displaySensitiveContents, options)
}
fun openMedia(context: Context, status: ParcelableStatus,
current: ParcelableMedia? = null, newDocument: Boolean,
displaySensitiveContents: Boolean, options: Bundle? = null) {
val media = ParcelableMediaUtils.getPrimaryMedia(status) ?: return
openMedia(context, status.account_key, status.is_possibly_sensitive, status, null, current,
media, newDocument, displaySensitiveContents, options)
}
fun openMedia(context: Context, accountKey: UserKey?, media: Array<ParcelableMedia>,
current: ParcelableMedia? = null, isPossiblySensitive: Boolean,
newDocument: Boolean, displaySensitiveContents: Boolean, options: Bundle? = null) {
openMedia(context, accountKey, isPossiblySensitive, null, null, current, media, newDocument,
displaySensitiveContents, options)
}
fun openMedia(context: Context, accountKey: UserKey?, isPossiblySensitive: Boolean,
status: ParcelableStatus?, message: ParcelableDirectMessage?,
current: ParcelableMedia? = null, media: Array<ParcelableMedia>,
newDocument: Boolean, displaySensitiveContents: Boolean,
options: Bundle? = null) {
if (context is FragmentActivity && isPossiblySensitive && !displaySensitiveContents) {
val fm = context.supportFragmentManager
val fragment = SensitiveContentWarningDialogFragment()
val args = Bundle()
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey)
args.putParcelable(EXTRA_CURRENT_MEDIA, current)
if (status != null) {
args.putParcelable(EXTRA_STATUS, status)
}
if (message != null) {
args.putParcelable(EXTRA_MESSAGE, message)
}
args.putParcelableArray(EXTRA_MEDIA, media)
args.putBundle(EXTRA_ACTIVITY_OPTIONS, options)
args.putBundle(EXTRA_ACTIVITY_OPTIONS, options)
args.putBoolean(EXTRA_NEW_DOCUMENT, newDocument)
fragment.arguments = args
fragment.show(fm, "sensitive_content_warning")
} else {
openMediaDirectly(context, accountKey, status, message, current, media, options,
newDocument)
}
}
fun openMediaDirectly(context: Context, accountKey: UserKey?, status: ParcelableStatus,
current: ParcelableMedia, newDocument: Boolean, options: Bundle? = null) {
val media = ParcelableMediaUtils.getPrimaryMedia(status) ?: return
openMediaDirectly(context, accountKey, status, null, current, media, options, newDocument)
}
fun getDefaultBrowserPackage(context: Context, uri: Uri, checkHandled: Boolean): String? {
if (checkHandled && !isWebLinkHandled(context, uri)) {
return null
}
val intent = Intent(Intent.ACTION_VIEW)
intent.addCategory(Intent.CATEGORY_BROWSABLE)
val testBuilder = Uri.Builder()
testBuilder.scheme(SCHEME_HTTP)
val sb = StringBuilder()
val random = Random()
val range = 'z' - 'a'
for (i in 0..19) {
sb.append(('a' + Math.abs(random.nextInt()) % range).toChar())
}
sb.append(".com")
testBuilder.authority(sb.toString())
intent.data = testBuilder.build()
val componentName = intent.resolveActivity(context.packageManager)
if (componentName == null || componentName.className == null) return null
if (TextUtils.equals("android", componentName.packageName)) return null
return componentName.packageName
}
fun isWebLinkHandled(context: Context, uri: Uri): Boolean {
val filter = getWebLinkIntentFilter(context) ?: return false
return filter.match(Intent.ACTION_VIEW, null, uri.scheme, uri,
setOf(Intent.CATEGORY_BROWSABLE), LOGTAG) >= 0
}
fun getWebLinkIntentFilter(context: Context): IntentFilter? {
val testIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/user_name"))
testIntent.addCategory(Intent.CATEGORY_BROWSABLE)
testIntent.`package` = context.packageName
val resolveInfo = context.packageManager.resolveActivity(testIntent,
PackageManager.GET_RESOLVED_FILTER)
return resolveInfo?.filter
}
fun openMediaDirectly(context: Context,
accountKey: UserKey?,
message: ParcelableDirectMessage, current: ParcelableMedia,
media: Array<ParcelableMedia>, options: Bundle? = null,
newDocument: Boolean) {
openMediaDirectly(context, accountKey, null, message, current, media, options, newDocument)
}
fun openMediaDirectly(context: Context, accountKey: UserKey?,
status: ParcelableStatus?, message: ParcelableDirectMessage?,
current: ParcelableMedia? = null, media: Array<ParcelableMedia>,
options: Bundle? = null, newDocument: Boolean) {
val intent = Intent(context, MediaViewerActivity::class.java)
intent.putExtra(EXTRA_ACCOUNT_KEY, accountKey)
intent.putExtra(EXTRA_CURRENT_MEDIA, current)
intent.putExtra(EXTRA_MEDIA, media)
if (status != null) {
intent.putExtra(EXTRA_STATUS, status)
intent.data = getMediaViewerUri("status", status.id, accountKey)
}
if (message != null) {
intent.putExtra(EXTRA_MESSAGE, message)
intent.data = getMediaViewerUri("message", message.id.toString(), accountKey)
}
if (newDocument && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
}
ActivityCompat.startActivity(context, intent, options)
}
fun getMediaViewerUri(type: String, id: String,
accountKey: UserKey?): Uri {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority("media")
builder.appendPath(type)
builder.appendPath(id)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
return builder.build()
}
fun openMessageConversation(context: Context,
accountKey: UserKey?,
recipientId: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
if (recipientId != null) {
builder.appendQueryParameter(QUERY_PARAM_RECIPIENT_ID, recipientId)
}
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openIncomingFriendships(context: Context,
accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_INCOMING_FRIENDSHIPS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openMap(context: Context, latitude: Double, longitude: Double) {
if (!ParcelableLocationUtils.isValidLocation(latitude, longitude)) return
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_MAP)
builder.appendQueryParameter(QUERY_PARAM_LAT, latitude.toString())
builder.appendQueryParameter(QUERY_PARAM_LNG, longitude.toString())
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openMutesUsers(context: Context,
accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_MUTES_USERS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openScheduledStatuses(context: Context,
accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_SCHEDULED_STATUSES)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openSavedSearches(context: Context, accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_SAVED_SEARCHES)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openSearch(context: Context, accountKey: UserKey?, query: String, type: String? = null) {
val intent = Intent(Intent.ACTION_VIEW)
// Some devices cannot process query parameter with hashes well, so add this intent extra
intent.putExtra(EXTRA_QUERY, query)
if (accountKey != null) {
intent.putExtra(EXTRA_ACCOUNT_KEY, accountKey)
}
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_SEARCH)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
builder.appendQueryParameter(QUERY_PARAM_QUERY, query)
if (!TextUtils.isEmpty(type)) {
builder.appendQueryParameter(QUERY_PARAM_TYPE, type)
intent.putExtra(EXTRA_TYPE, type)
}
intent.data = builder.build()
context.startActivity(intent)
}
fun openStatus(context: Context, accountKey: UserKey?,
statusId: String) {
val uri = LinkCreator.getTwidereStatusLink(accountKey, statusId)
val intent = Intent(Intent.ACTION_VIEW, uri)
context.startActivity(intent)
}
fun openStatus(context: Context, status: ParcelableStatus, activityOptions: Bundle? = null) {
val extras = Bundle()
extras.putParcelable(EXTRA_STATUS, status)
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_STATUS)
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, status.account_key.toString())
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, status.id)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.setExtrasClassLoader(context.classLoader)
intent.putExtras(extras)
ActivityCompat.startActivity(context, intent, activityOptions)
}
fun openStatusFavoriters(context: Context, accountKey: UserKey?,
statusId: String) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_STATUS_FAVORITERS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, statusId)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
ActivityCompat.startActivity(context, intent, null)
}
fun openStatusRetweeters(context: Context, accountKey: UserKey?,
statusId: String) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_STATUS_RETWEETERS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, statusId)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
ActivityCompat.startActivity(context, intent, null)
}
fun openTweetSearch(context: Context, accountKey: UserKey?,
query: String) {
openSearch(context, accountKey, query, QUERY_PARAM_VALUE_TWEETS)
}
fun openUserBlocks(activity: Activity?, accountKey: UserKey) {
if (activity == null) return
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_BLOCKS)
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
val intent = Intent(Intent.ACTION_VIEW, builder.build())
activity.startActivity(intent)
}
fun openUserFavorites(context: Context,
accountKey: UserKey?,
userKey: UserKey?,
screenName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_FAVORITES)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openUserFollowers(context: Context,
accountKey: UserKey?,
userKey: UserKey?,
screenName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_FOLLOWERS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openUserFriends(context: Context,
accountKey: UserKey?,
userKey: UserKey?,
screenName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_FRIENDS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openUserListDetails(context: Context,
accountKey: UserKey?,
listId: String?,
userId: UserKey?,
screenName: String?, listName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_LIST)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (listId != null) {
builder.appendQueryParameter(QUERY_PARAM_LIST_ID, listId)
}
if (userId != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userId.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
if (listName != null) {
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, listName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openUserListDetails(context: Context,
userList: ParcelableUserList) {
val userKey = userList.user_key
val listId = userList.id
val extras = Bundle()
extras.putParcelable(EXTRA_USER_LIST, userList)
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_LIST)
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, userList.account_key.toString())
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
builder.appendQueryParameter(QUERY_PARAM_LIST_ID, listId)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.setExtrasClassLoader(context.classLoader)
intent.putExtras(extras)
context.startActivity(intent)
}
fun openGroupDetails(context: Context, group: ParcelableGroup) {
val extras = Bundle()
extras.putParcelable(EXTRA_GROUP, group)
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_GROUP)
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, group.account_key.toString())
builder.appendQueryParameter(QUERY_PARAM_GROUP_ID, group.id)
builder.appendQueryParameter(QUERY_PARAM_GROUP_NAME, group.nickname)
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.setExtrasClassLoader(context.classLoader)
intent.putExtras(extras)
context.startActivity(intent)
}
fun openUserLists(context: Context,
accountKey: UserKey?,
userKey: UserKey?,
screenName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_LISTS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (userKey != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openUserGroups(context: Context,
accountKey: UserKey?,
userId: UserKey?,
screenName: String?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_USER_GROUPS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
if (userId != null) {
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userId.toString())
}
if (screenName != null) {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openDirectMessages(context: Context, accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_DIRECT_MESSAGES)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openInteractions(context: Context, accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_INTERACTIONS)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openPublicTimeline(context: Context, accountKey: UserKey?) {
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_PUBLIC_TIMELINE)
if (accountKey != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
context.startActivity(intent)
}
fun openAccountsManager(context: Context) {
val intent = Intent()
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_ACCOUNTS)
intent.data = builder.build()
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openDrafts(context: Context) {
val intent = Intent()
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_DRAFTS)
intent.data = builder.build()
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openProfileEditor(context: Context, accountId: UserKey?) {
val intent = Intent()
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_PROFILE_EDITOR)
if (accountId != null) {
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountId.toString())
}
intent.data = builder.build()
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun openFilters(context: Context) {
val intent = Intent()
val builder = Uri.Builder()
builder.scheme(SCHEME_TWIDERE)
builder.authority(AUTHORITY_FILTERS)
intent.data = builder.build()
intent.`package` = BuildConfig.APPLICATION_ID
context.startActivity(intent)
}
fun applyNewDocument(intent: Intent, enable: Boolean) {
if (enable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
}
}
}

View File

@ -37,6 +37,7 @@ import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.chromeCustomTabKey
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
@ -62,8 +63,8 @@ open class OnLinkClickHandler(
when (type) {
TwidereLinkify.LINK_TYPE_MENTION -> {
IntentUtils.openUserProfile(context, accountKey, null, link, null,
preferences[newDocumentApiKey], Referral.USER_MENTION)
IntentUtils.openUserProfile(context, accountKey, null, link, preferences[newDocumentApiKey],
Referral.USER_MENTION, null)
return true
}
TwidereLinkify.LINK_TYPE_HASHTAG -> {
@ -103,8 +104,8 @@ open class OnLinkClickHandler(
}
val screenName = orig.substring(1, length)
IntentUtils.openUserProfile(context, accountKey, UserKey.valueOf(id),
screenName, null, preferences[newDocumentApiKey],
Referral.USER_MENTION)
screenName, preferences[newDocumentApiKey], Referral.USER_MENTION,
null)
return true
}
} else if (TwidereLinkify.isHashSymbol(ch) && TwidereLinkify.isHashSymbol(orig[length - 1])) {
@ -138,9 +139,9 @@ open class OnLinkClickHandler(
return true
}
TwidereLinkify.LINK_TYPE_USER_ID -> {
IntentUtils.openUserProfile(context, accountKey, UserKey.valueOf(link), null, null,
preferences[newDocumentApiKey],
Referral.USER_MENTION)
IntentUtils.openUserProfile(context, accountKey, UserKey.valueOf(link), null, preferences[newDocumentApiKey],
Referral.USER_MENTION,
null)
return true
}
}
@ -156,8 +157,8 @@ open class OnLinkClickHandler(
protected open fun openMedia(accountKey: UserKey, extraId: Long, sensitive: Boolean, link: String, start: Int, end: Int) {
val media = arrayOf(ParcelableMediaUtils.image(link))
IntentUtils.openMedia(context, accountKey, sensitive, null, media, null,
preferences[newDocumentApiKey])
IntentUtils.openMedia(context, accountKey, media, null, sensitive, preferences[newDocumentApiKey],
preferences[displaySensitiveContentsKey])
}
protected open fun openLink(link: String) {

View File

@ -24,6 +24,7 @@ import android.support.v7.widget.RecyclerView
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
@ -38,14 +39,14 @@ class StatusAdapterLinkClickHandler<D>(context: Context, preferences: SharedPref
override fun openMedia(accountKey: UserKey, extraId: Long, sensitive: Boolean,
link: String, start: Int, end: Int) {
if (extraId == RecyclerView.NO_POSITION.toLong()) return
val status = adapter!!.getStatus(extraId.toInt())
val status = adapter!!.getStatus(extraId.toInt())!!
val media = ParcelableMediaUtils.getAllMedia(status)
val current = StatusLinkClickHandler.findByLink(media, link)
if (current != null && current.open_browser) {
openLink(link)
} else {
val newDocument = preferences[newDocumentApiKey]
IntentUtils.openMedia(context, status, current, null, newDocument)
IntentUtils.openMedia(context, status, current, preferences[newDocumentApiKey],
preferences[displaySensitiveContentsKey])
}
}
@ -54,7 +55,7 @@ class StatusAdapterLinkClickHandler<D>(context: Context, preferences: SharedPref
val status = adapter!!.getStatus(extraId.toInt())
val media = ParcelableMediaUtils.getAllMedia(status)
val current = StatusLinkClickHandler.findByLink(media, link)
return current != null && !current.open_browser
if (current != null) return !current.open_browser
}
return super.isMedia(link, extraId)
}

View File

@ -23,6 +23,7 @@ import android.content.Context
import android.content.SharedPreferences
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.ParcelableStatus
@ -46,7 +47,8 @@ open class StatusLinkClickHandler(
if (current == null || current.open_browser) {
openLink(link)
} else {
IntentUtils.openMedia(context, status, current, null, preferences[newDocumentApiKey])
IntentUtils.openMedia(context, status, current, preferences[newDocumentApiKey],
preferences[displaySensitiveContentsKey])
}
}