mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-02 17:56:56 +01:00
activities about me supports my following only limitation
This commit is contained in:
parent
f8264eddc0
commit
76547896ba
@ -521,11 +521,6 @@
|
|||||||
android:grantUriPermissions="true"
|
android:grantUriPermissions="true"
|
||||||
android:label="@string/label_data_provider"
|
android:label="@string/label_data_provider"
|
||||||
tools:ignore="ExportedContentProvider"/>
|
tools:ignore="ExportedContentProvider"/>
|
||||||
<provider
|
|
||||||
android:name=".provider.TwidereCommandProvider"
|
|
||||||
android:authorities="twidere.command"
|
|
||||||
android:exported="true"
|
|
||||||
tools:ignore="ExportedContentProvider"/>
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".provider.RecentSearchProvider"
|
android:name=".provider.RecentSearchProvider"
|
||||||
android:authorities="org.mariotaku.twidere.provider.SearchRecentSuggestions"
|
android:authorities="org.mariotaku.twidere.provider.SearchRecentSuggestions"
|
||||||
|
@ -59,13 +59,14 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.support.SupportFixedFragmentStatePagerAdapter;
|
import org.mariotaku.twidere.adapter.support.SupportFixedFragmentStatePagerAdapter;
|
||||||
import org.mariotaku.twidere.fragment.support.DownloadingMediaPageFragment;
|
import org.mariotaku.twidere.fragment.support.CacheDownloadFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.ViewStatusDialogFragment;
|
import org.mariotaku.twidere.fragment.support.ViewStatusDialogFragment;
|
||||||
import org.mariotaku.twidere.loader.support.CacheDownloadLoader.Listener;
|
import org.mariotaku.twidere.loader.support.CacheDownloadLoader.Listener;
|
||||||
import org.mariotaku.twidere.loader.support.CacheDownloadLoader.Result;
|
import org.mariotaku.twidere.loader.support.CacheDownloadLoader.Result;
|
||||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||||
import org.mariotaku.twidere.model.ParcelableMedia.VideoInfo.Variant;
|
import org.mariotaku.twidere.model.ParcelableMedia.VideoInfo.Variant;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
import org.mariotaku.twidere.util.IntentUtils;
|
||||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||||
import org.mariotaku.twidere.util.MenuUtils;
|
import org.mariotaku.twidere.util.MenuUtils;
|
||||||
import org.mariotaku.twidere.util.ThemeUtils;
|
import org.mariotaku.twidere.util.ThemeUtils;
|
||||||
@ -79,7 +80,7 @@ import pl.droidsonroids.gif.GifTextureView;
|
|||||||
|
|
||||||
|
|
||||||
public final class MediaViewerActivity extends BaseAppCompatActivity implements Constants,
|
public final class MediaViewerActivity extends BaseAppCompatActivity implements Constants,
|
||||||
OnPageChangeListener, DownloadingMediaPageFragment.ShareIntentProcessor {
|
OnPageChangeListener, CacheDownloadFragment.ShareIntentProcessor {
|
||||||
|
|
||||||
private static final String EXTRA_LOOP = "loop";
|
private static final String EXTRA_LOOP = "loop";
|
||||||
private static boolean ANIMATED_GIF_SUPPORTED = GifSupportChecker.isSupported();
|
private static boolean ANIMATED_GIF_SUPPORTED = GifSupportChecker.isSupported();
|
||||||
@ -244,10 +245,13 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processShareIntent(Intent intent) {
|
public void processShareIntent(Intent intent) {
|
||||||
|
if (!hasStatus()) return;
|
||||||
|
final ParcelableStatus status = getStatus();
|
||||||
|
intent.putExtra(Intent.EXTRA_SUBJECT, IntentUtils.getStatusShareSubject(this, status));
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, IntentUtils.getStatusShareText(this, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BaseImagePageFragment extends MediaPageFragment implements OnClickListener {
|
public static class ImagePageFragment extends MediaPageFragment implements OnClickListener {
|
||||||
|
|
||||||
private SubsamplingScaleImageView mImageView;
|
private SubsamplingScaleImageView mImageView;
|
||||||
private ProgressWheel mProgressBar;
|
private ProgressWheel mProgressBar;
|
||||||
@ -291,17 +295,17 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasValidMedia() {
|
protected boolean isAbleToLoad() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Uri getMediaUrl() {
|
protected Uri getDownloadUri() {
|
||||||
return Uri.parse(getMedia().media_url);
|
return Uri.parse(getMedia().media_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayMedia(Result data) {
|
protected void displayDownloaded(Result data) {
|
||||||
mImageView.setImage(ImageSource.uri(data.cacheUri));
|
mImageView.setImage(ImageSource.uri(data.cacheUri));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,12 +328,11 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareOptionsMenu(Menu menu) {
|
public void onPrepareOptionsMenu(Menu menu) {
|
||||||
super.onPrepareOptionsMenu(menu);
|
|
||||||
final boolean isLoading = getLoaderManager().hasRunningLoaders();
|
final boolean isLoading = getLoaderManager().hasRunningLoaders();
|
||||||
final boolean hasImage = hasValidMedia();
|
final boolean isDownloaded = hasDownloadedData();
|
||||||
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !hasImage && !isLoading);
|
MenuUtils.setMenuItemAvailability(menu, R.id.save, !isLoading && isDownloaded);
|
||||||
MenuUtils.setMenuItemAvailability(menu, R.id.share, hasImage && !isLoading);
|
MenuUtils.setMenuItemAvailability(menu, R.id.share, !isLoading && isDownloaded);
|
||||||
MenuUtils.setMenuItemAvailability(menu, R.id.save, hasImage && !isLoading);
|
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !isLoading && !isDownloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -347,11 +350,11 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.save: {
|
case R.id.save: {
|
||||||
requestAndSaveToGallery();
|
requestAndSaveToStorage();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.refresh: {
|
case R.id.refresh: {
|
||||||
loadMedia();
|
startLoading();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.share: {
|
case R.id.share: {
|
||||||
@ -375,12 +378,12 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
loadMedia();
|
startLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ImagePageFragment extends BaseImagePageFragment
|
public static final class GifSupportedImagePageFragment extends ImagePageFragment
|
||||||
implements Listener, LoaderCallbacks<Result>, OnClickListener {
|
implements Listener, LoaderCallbacks<Result>, OnClickListener {
|
||||||
|
|
||||||
private GifTextureView mGifImageView;
|
private GifTextureView mGifImageView;
|
||||||
@ -392,22 +395,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayMedia(Result data) {
|
protected boolean isAbleToLoad() {
|
||||||
// if (data.hasData() && "image/gif".equals(data.options.outMimeType)) {
|
|
||||||
// mGifImageView.setVisibility(View.VISIBLE);
|
|
||||||
// setImageViewVisibility(View.GONE);
|
|
||||||
// mGifImageView.setInputSource(new InS(data.file));
|
|
||||||
// setLoadProgressVisibility(View.GONE);
|
|
||||||
// setLoadProgress(0);
|
|
||||||
// invalidateOptionsMenu();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
super.displayMedia(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasValidMedia() {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,9 +441,9 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
}
|
}
|
||||||
case ParcelableMedia.TYPE_IMAGE: {
|
case ParcelableMedia.TYPE_IMAGE: {
|
||||||
if (ANIMATED_GIF_SUPPORTED) {
|
if (ANIMATED_GIF_SUPPORTED) {
|
||||||
return Fragment.instantiate(mActivity, ImagePageFragment.class.getName(), args);
|
return Fragment.instantiate(mActivity, GifSupportedImagePageFragment.class.getName(), args);
|
||||||
}
|
}
|
||||||
return Fragment.instantiate(mActivity, BaseImagePageFragment.class.getName(), args);
|
return Fragment.instantiate(mActivity, ImagePageFragment.class.getName(), args);
|
||||||
}
|
}
|
||||||
case ParcelableMedia.TYPE_EXTERNAL_PLAYER: {
|
case ParcelableMedia.TYPE_EXTERNAL_PLAYER: {
|
||||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(media.card);
|
return TwitterCardFragmentFactory.createGenericPlayerFragment(media.card);
|
||||||
@ -475,7 +463,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
public static class UnsupportedPageFragment extends Fragment {
|
public static class UnsupportedPageFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static abstract class MediaPageFragment extends DownloadingMediaPageFragment implements
|
private static abstract class MediaPageFragment extends CacheDownloadFragment implements
|
||||||
LoaderCallbacks<Result>, Listener {
|
LoaderCallbacks<Result>, Listener {
|
||||||
|
|
||||||
protected final ParcelableMedia getMedia() {
|
protected final ParcelableMedia getMedia() {
|
||||||
@ -533,18 +521,19 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasValidMedia() {
|
protected boolean isAbleToLoad() {
|
||||||
return true;
|
return getDownloadUri() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Uri getMediaUrl() {
|
protected Uri getDownloadUri() {
|
||||||
final Pair<String, String> bestVideoUrlAndType = getBestVideoUrlAndType(getMedia());
|
final Pair<String, String> bestVideoUrlAndType = getBestVideoUrlAndType(getMedia());
|
||||||
|
if (bestVideoUrlAndType == null || bestVideoUrlAndType.first == null) return null;
|
||||||
return Uri.parse(bestVideoUrlAndType.first);
|
return Uri.parse(bestVideoUrlAndType.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void displayMedia(Result data) {
|
protected void displayDownloaded(Result data) {
|
||||||
mVideoView.setVideoURI(data.cacheUri);
|
mVideoView.setVideoURI(data.cacheUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +646,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
|
|
||||||
mPlayPauseButton.setOnClickListener(this);
|
mPlayPauseButton.setOnClickListener(this);
|
||||||
mVolumeButton.setOnClickListener(this);
|
mVolumeButton.setOnClickListener(this);
|
||||||
loadMedia();
|
startLoading();
|
||||||
updateVolume();
|
updateVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,15 +729,24 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
|||||||
inflater.inflate(R.menu.menu_media_viewer_video_page, menu);
|
inflater.inflate(R.menu.menu_media_viewer_video_page, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepareOptionsMenu(Menu menu) {
|
||||||
|
final boolean isLoading = getLoaderManager().hasRunningLoaders();
|
||||||
|
final boolean isDownloaded = hasDownloadedData();
|
||||||
|
MenuUtils.setMenuItemAvailability(menu, R.id.save, !isLoading && isDownloaded);
|
||||||
|
MenuUtils.setMenuItemAvailability(menu, R.id.share, !isLoading && isDownloaded);
|
||||||
|
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !isLoading && !isDownloaded);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.save: {
|
case R.id.save: {
|
||||||
requestAndSaveToGallery();
|
requestAndSaveToStorage();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.refresh: {
|
case R.id.refresh: {
|
||||||
loadMedia();
|
startLoading();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.share: {
|
case R.id.share: {
|
||||||
|
@ -40,7 +40,7 @@ import javax.inject.Inject;
|
|||||||
/**
|
/**
|
||||||
* Created by mariotaku on 16/1/2.
|
* Created by mariotaku on 16/1/2.
|
||||||
*/
|
*/
|
||||||
public abstract class DownloadingMediaPageFragment extends BaseSupportFragment implements LoaderManager.LoaderCallbacks<CacheDownloadLoader.Result>, CacheDownloadLoader.Listener {
|
public abstract class CacheDownloadFragment extends BaseSupportFragment implements LoaderManager.LoaderCallbacks<CacheDownloadLoader.Result>, CacheDownloadLoader.Listener {
|
||||||
|
|
||||||
protected static final int REQUEST_SHARE_MEDIA = 201;
|
protected static final int REQUEST_SHARE_MEDIA = 201;
|
||||||
private boolean mLoaderInitialized;
|
private boolean mLoaderInitialized;
|
||||||
@ -61,6 +61,10 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean hasDownloadedData() {
|
||||||
|
return mData != null && mData.cacheUri != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onDownloadError(Throwable t) {
|
public final void onDownloadError(Throwable t) {
|
||||||
hideProgress();
|
hideProgress();
|
||||||
@ -85,7 +89,7 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_REQUEST_PERMISSIONS: {
|
case REQUEST_REQUEST_PERMISSIONS: {
|
||||||
if (PermissionUtils.hasPermission(permissions, grantResults, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
if (PermissionUtils.hasPermission(permissions, grantResults, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
saveToGallery();
|
saveToStorage();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), R.string.save_media_no_storage_permission_message, Toast.LENGTH_LONG).show();
|
Toast.makeText(getContext(), R.string.save_media_no_storage_permission_message, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
@ -102,11 +106,11 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Loader<CacheDownloadLoader.Result> onCreateLoader(int id, Bundle args) {
|
public final Loader<CacheDownloadLoader.Result> onCreateLoader(int id, Bundle args) {
|
||||||
return new CacheDownloadLoader(getContext(), new MediaDownloader(getContext()), this, getMediaUrl());
|
return new CacheDownloadLoader(getContext(), new MediaDownloader(getContext()), this, getDownloadUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected final void saveToGallery() {
|
protected final void saveToStorage() {
|
||||||
if (mData == null) return;
|
if (mData == null) return;
|
||||||
if (mSaveFileTask != null && mSaveFileTask.getStatus() == AsyncTask.Status.RUNNING) return;
|
if (mSaveFileTask != null && mSaveFileTask.getStatus() == AsyncTask.Status.RUNNING) return;
|
||||||
final Uri cacheUri = mData.cacheUri;
|
final Uri cacheUri = mData.cacheUri;
|
||||||
@ -116,8 +120,8 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
AsyncTaskUtils.executeTask(mSaveFileTask);
|
AsyncTaskUtils.executeTask(mSaveFileTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void loadMedia() {
|
public final void startLoading() {
|
||||||
if (!hasValidMedia()) return;
|
if (!isAbleToLoad()) return;
|
||||||
getLoaderManager().destroyLoader(0);
|
getLoaderManager().destroyLoader(0);
|
||||||
if (!mLoaderInitialized) {
|
if (!mLoaderInitialized) {
|
||||||
getLoaderManager().initLoader(0, null, this);
|
getLoaderManager().initLoader(0, null, this);
|
||||||
@ -127,7 +131,7 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract boolean hasValidMedia();
|
protected abstract boolean isAbleToLoad();
|
||||||
|
|
||||||
|
|
||||||
protected final void shareMedia() {
|
protected final void shareMedia() {
|
||||||
@ -190,9 +194,9 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
task.execute();
|
task.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void requestAndSaveToGallery() {
|
protected final void requestAndSaveToStorage() {
|
||||||
if (PermissionUtils.hasPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
if (PermissionUtils.hasPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
saveToGallery();
|
saveToStorage();
|
||||||
} else {
|
} else {
|
||||||
final String[] permissions;
|
final String[] permissions;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
@ -205,16 +209,16 @@ public abstract class DownloadingMediaPageFragment extends BaseSupportFragment i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Uri getMediaUrl();
|
protected abstract Uri getDownloadUri();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onLoadFinished(Loader<CacheDownloadLoader.Result> loader, @NonNull CacheDownloadLoader.Result data) {
|
public final void onLoadFinished(Loader<CacheDownloadLoader.Result> loader, @NonNull CacheDownloadLoader.Result data) {
|
||||||
mData = data;
|
mData = data;
|
||||||
hideProgress();
|
hideProgress();
|
||||||
displayMedia(data);
|
displayDownloaded(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void displayMedia(CacheDownloadLoader.Result data);
|
protected abstract void displayDownloaded(CacheDownloadLoader.Result data);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onLoaderReset(Loader<CacheDownloadLoader.Result> loader) {
|
public final void onLoaderReset(Loader<CacheDownloadLoader.Result> loader) {
|
@ -11,7 +11,7 @@ import org.mariotaku.twidere.model.ParcelableUser;
|
|||||||
public class ParcelableActivityUtils {
|
public class ParcelableActivityUtils {
|
||||||
public static void getAfterFilteredSourceIds(ParcelableActivity activity, long[] filteredUserIds, boolean followingOnly) {
|
public static void getAfterFilteredSourceIds(ParcelableActivity activity, long[] filteredUserIds, boolean followingOnly) {
|
||||||
if (activity.after_filtered_source_ids != null) return;
|
if (activity.after_filtered_source_ids != null) return;
|
||||||
if (!ArrayUtils.isEmpty(filteredUserIds)) {
|
if (followingOnly || !ArrayUtils.isEmpty(filteredUserIds)) {
|
||||||
ArrayLongList list = new ArrayLongList();
|
ArrayLongList list = new ArrayLongList();
|
||||||
for (ParcelableUser user : activity.sources) {
|
for (ParcelableUser user : activity.sources) {
|
||||||
if (followingOnly && !user.is_following) {
|
if (followingOnly && !user.is_following) {
|
||||||
|
@ -1,171 +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.provider;
|
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.UriMatcher;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.MatrixCursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
|
||||||
import org.mariotaku.twidere.provider.TwidereCommands.Refresh;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.PermissionsManager;
|
|
||||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
public class TwidereCommandProvider extends ContentProvider implements Constants {
|
|
||||||
|
|
||||||
private static final UriMatcher COMMAND_URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
|
|
||||||
|
|
||||||
private static final int CODE_REFRESH_ALL = 10;
|
|
||||||
private static final int CODE_REFRESH_HOME_TIMELINE = 11;
|
|
||||||
private static final int CODE_REFRESH_MENTIONS = 12;
|
|
||||||
private static final int CODE_REFRESH_INBOX = 13;
|
|
||||||
private static final int CODE_REFRESH_OUTBOX = 14;
|
|
||||||
|
|
||||||
static {
|
|
||||||
COMMAND_URI_MATCHER.addURI(TwidereCommands.AUTHORITY, Refresh.ACTION_REFRESH_ALL, CODE_REFRESH_ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private PermissionsManager mPermissionsManager;
|
|
||||||
@Inject
|
|
||||||
AsyncTwitterWrapper mTwitterWrapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int delete(@NonNull final Uri uri, final String where, final String[] whereArgs) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType(@NonNull final Uri uri) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uri insert(@NonNull final Uri uri, final ContentValues values) {
|
|
||||||
if (handleInsertCommand(uri, values)) return uri;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreate() {
|
|
||||||
mContext = getContext();
|
|
||||||
GeneralComponentHelper.build(mContext).inject(this);
|
|
||||||
mPermissionsManager = new PermissionsManager(mContext);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cursor query(@NonNull final Uri uri, final String[] projection, final String where, final String[] whereArgs,
|
|
||||||
final String sortOrder) {
|
|
||||||
return handleQueryCommand(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(@NonNull final Uri uri, final ContentValues values, final String where, final String[] whereArgs) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkInsertPermission(final int uri_code) {
|
|
||||||
switch (uri_code) {
|
|
||||||
case CODE_REFRESH_ALL:
|
|
||||||
case CODE_REFRESH_HOME_TIMELINE:
|
|
||||||
case CODE_REFRESH_MENTIONS:
|
|
||||||
case CODE_REFRESH_INBOX:
|
|
||||||
case CODE_REFRESH_OUTBOX: {
|
|
||||||
if (!mPermissionsManager.checkCallingPermission(PERMISSION_REFRESH))
|
|
||||||
throw new SecurityException("Executing this command requires level PERMISSION_REFRESH");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkQueryPermission(final int uri_code) {
|
|
||||||
switch (uri_code) {
|
|
||||||
case CODE_REFRESH_ALL:
|
|
||||||
case CODE_REFRESH_HOME_TIMELINE:
|
|
||||||
case CODE_REFRESH_MENTIONS:
|
|
||||||
case CODE_REFRESH_INBOX:
|
|
||||||
case CODE_REFRESH_OUTBOX: {
|
|
||||||
if (!mPermissionsManager.checkCallingPermission(PERMISSION_REFRESH))
|
|
||||||
throw new SecurityException("Executing this command requires level PERMISSION_REFRESH");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cursor getEmptyCursor() {
|
|
||||||
return new MatrixCursor(new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean handleInsertCommand(final Uri uri, final ContentValues values) {
|
|
||||||
final int uri_code = COMMAND_URI_MATCHER.match(uri);
|
|
||||||
checkInsertPermission(uri_code);
|
|
||||||
try {
|
|
||||||
switch (uri_code) {
|
|
||||||
case CODE_REFRESH_ALL: {
|
|
||||||
mTwitterWrapper.refreshAll();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// something blah blah blah
|
|
||||||
} catch (final RuntimeException e) {
|
|
||||||
Log.w(LOGTAG, e);
|
|
||||||
if (Thread.currentThread().getId() != 1)
|
|
||||||
throw new IllegalStateException("This method cannot be called from non-UI thread");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cursor handleQueryCommand(final Uri uri) {
|
|
||||||
final int uri_code = COMMAND_URI_MATCHER.match(uri);
|
|
||||||
checkQueryPermission(uri_code);
|
|
||||||
try {
|
|
||||||
switch (uri_code) {
|
|
||||||
case CODE_REFRESH_HOME_TIMELINE:
|
|
||||||
if (mTwitterWrapper.isHomeTimelineRefreshing()) return getEmptyCursor();
|
|
||||||
case CODE_REFRESH_MENTIONS:
|
|
||||||
if (mTwitterWrapper.isMentionsTimelineRefreshing()) return getEmptyCursor();
|
|
||||||
case CODE_REFRESH_INBOX:
|
|
||||||
if (mTwitterWrapper.isReceivedDirectMessagesRefreshing())
|
|
||||||
return getEmptyCursor();
|
|
||||||
case CODE_REFRESH_OUTBOX:
|
|
||||||
if (mTwitterWrapper.isSentDirectMessagesRefreshing()) return getEmptyCursor();
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// something blah blah blah
|
|
||||||
} catch (final RuntimeException e) {
|
|
||||||
Log.w(LOGTAG, e);
|
|
||||||
if (Thread.currentThread().getId() != 1)
|
|
||||||
throw new IllegalStateException("This method cannot be called from non-UI thread");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,133 +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.provider;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableLocation;
|
|
||||||
import org.mariotaku.twidere.util.ParseUtils;
|
|
||||||
import org.mariotaku.twidere.util.TwidereArrayUtils;
|
|
||||||
|
|
||||||
public class TwidereCommands {
|
|
||||||
|
|
||||||
public static final String AUTHORITY = "twidere.command";
|
|
||||||
|
|
||||||
public static final Uri BASE_CONTENT_URI = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
|
||||||
.authority(AUTHORITY).build();
|
|
||||||
public static final String EXTRA_IN_REPLY_TO_STATUS_ID = "in_reply_to_status_id";
|
|
||||||
public static final String EXTRA_IS_POSSIBLY_SENSITIVE = "is_possibly_sensitive";
|
|
||||||
public static final String EXTRA_DELETE_IMAGE = "delete_image";
|
|
||||||
|
|
||||||
public static class DirectMessage {
|
|
||||||
|
|
||||||
public static final String ACTION_SEND_DIRECT_MESSAGE = "send_direct_message";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Refresh {
|
|
||||||
|
|
||||||
public static final String ACTION_REFRESH_ALL = "refresh_all";
|
|
||||||
public static final String ACTION_REFRESH_HOME_TIMELINE = "refresh_home_timeline";
|
|
||||||
public static final String ACTION_REFRESH_MENTIONS = "refresh_mentions";
|
|
||||||
public static final String ACTION_REFRESH_INBOX = "refresh_inbox";
|
|
||||||
public static final String ACTION_REFRESH_OUTBOX = "refresh_inbox";
|
|
||||||
|
|
||||||
public static boolean isHomeTimelineRefreshing(final Context context) {
|
|
||||||
return Utils.isQueryCommandTrue(context, ACTION_REFRESH_HOME_TIMELINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInboxRefreshing(final Context context) {
|
|
||||||
return Utils.isQueryCommandTrue(context, ACTION_REFRESH_INBOX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isMentionsRefreshing(final Context context) {
|
|
||||||
return Utils.isQueryCommandTrue(context, ACTION_REFRESH_MENTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOutboxRefreshing(final Context context) {
|
|
||||||
return Utils.isQueryCommandTrue(context, ACTION_REFRESH_OUTBOX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refreshAll(final Context context) {
|
|
||||||
Utils.sendInsertCommand(context, ACTION_REFRESH_ALL, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refreshHomeTimeline(final Context context) {
|
|
||||||
Utils.sendInsertCommand(context, ACTION_REFRESH_HOME_TIMELINE, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refreshInbox(final Context context) {
|
|
||||||
Utils.sendInsertCommand(context, ACTION_REFRESH_INBOX, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refreshMentions(final Context context) {
|
|
||||||
Utils.sendInsertCommand(context, ACTION_REFRESH_MENTIONS, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refreshOutbox(final Context context) {
|
|
||||||
Utils.sendInsertCommand(context, ACTION_REFRESH_OUTBOX, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Send {
|
|
||||||
|
|
||||||
public static final String ACTION_UPDATE_STATUS = "update_status";
|
|
||||||
|
|
||||||
public void updateStatus(final Context context, final long[] account_ids, final String content,
|
|
||||||
final ParcelableLocation location, final Uri image_uri, final long in_reply_to_status_id,
|
|
||||||
final boolean is_possibly_sensitive, final boolean delete_image) {
|
|
||||||
final ContentValues values = new ContentValues();
|
|
||||||
values.put(Constants.EXTRA_ACCOUNT_IDS, TwidereArrayUtils.toString(account_ids, ',', false));
|
|
||||||
values.put(Constants.EXTRA_TEXT, content);
|
|
||||||
values.put(Constants.EXTRA_LOCATION, ParcelableLocation.toString(location));
|
|
||||||
values.put(Constants.EXTRA_URI, ParseUtils.parseString(image_uri));
|
|
||||||
values.put(EXTRA_IN_REPLY_TO_STATUS_ID, in_reply_to_status_id);
|
|
||||||
values.put(EXTRA_IS_POSSIBLY_SENSITIVE, is_possibly_sensitive);
|
|
||||||
values.put(EXTRA_DELETE_IMAGE, delete_image);
|
|
||||||
Utils.sendInsertCommand(context, ACTION_UPDATE_STATUS, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static class Utils {
|
|
||||||
|
|
||||||
private static boolean isQueryCommandTrue(final Context context, final String action) {
|
|
||||||
final Cursor cur = sendQueryCommand(context, action);
|
|
||||||
if (cur == null) return false;
|
|
||||||
cur.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Uri sendInsertCommand(final Context context, final String action, final ContentValues values) {
|
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
|
||||||
final Uri uri = Uri.withAppendedPath(BASE_CONTENT_URI, action);
|
|
||||||
return resolver.insert(uri, values != null ? values : new ContentValues());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Cursor sendQueryCommand(final Context context, final String action) {
|
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
|
||||||
final Uri uri = Uri.withAppendedPath(BASE_CONTENT_URI, action);
|
|
||||||
return resolver.query(uri, null, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.mariotaku.twidere.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.mariotaku.twidere.R;
|
||||||
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 16/1/2.
|
||||||
|
*/
|
||||||
|
public class IntentUtils {
|
||||||
|
public static String getStatusShareText(@NonNull final Context context, @NonNull final ParcelableStatus status) {
|
||||||
|
final Uri link = LinkCreator.getTwitterStatusLink(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);
|
||||||
|
}
|
||||||
|
}
|
@ -924,8 +924,8 @@ public final class Utils implements Constants {
|
|||||||
public static Intent createStatusShareIntent(@NonNull final Context context, @NonNull final ParcelableStatus status) {
|
public static Intent createStatusShareIntent(@NonNull final Context context, @NonNull final ParcelableStatus status) {
|
||||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||||
intent.setType("text/plain");
|
intent.setType("text/plain");
|
||||||
intent.putExtra(Intent.EXTRA_SUBJECT, getStatusShareSubject(context, status));
|
intent.putExtra(Intent.EXTRA_SUBJECT, IntentUtils.getStatusShareSubject(context, status));
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, getStatusShareText(context, status));
|
intent.putExtra(Intent.EXTRA_TEXT, IntentUtils.getStatusShareText(context, status));
|
||||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
@ -967,18 +967,6 @@ public final class Utils implements Constants {
|
|||||||
return tag + "_" + TwidereArrayUtils.toString(accountIdsClone, '_', false);
|
return tag + "_" + TwidereArrayUtils.toString(accountIdsClone, '_', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStatusShareText(@NonNull final Context context, @NonNull final ParcelableStatus status) {
|
|
||||||
final Uri link = LinkCreator.getTwitterStatusLink(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 = 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 String encodeQueryParams(final String value) throws IOException {
|
public static String encodeQueryParams(final String value) throws IOException {
|
||||||
final String encoded = URLEncoder.encode(value, "UTF-8");
|
final String encoded = URLEncoder.encode(value, "UTF-8");
|
||||||
final StringBuilder buf = new StringBuilder();
|
final StringBuilder buf = new StringBuilder();
|
||||||
|
@ -40,12 +40,11 @@ import org.mariotaku.twidere.fragment.BasePreferenceFragment;
|
|||||||
import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
|
import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.DownloadingMediaPageFragment;
|
import org.mariotaku.twidere.fragment.support.CacheDownloadFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.MessagesConversationFragment;
|
import org.mariotaku.twidere.fragment.support.MessagesConversationFragment;
|
||||||
import org.mariotaku.twidere.loader.support.CacheDownloadLoader;
|
import org.mariotaku.twidere.loader.support.CacheDownloadLoader;
|
||||||
import org.mariotaku.twidere.preference.AccountsListPreference;
|
import org.mariotaku.twidere.preference.AccountsListPreference;
|
||||||
import org.mariotaku.twidere.provider.CacheProvider;
|
import org.mariotaku.twidere.provider.CacheProvider;
|
||||||
import org.mariotaku.twidere.provider.TwidereCommandProvider;
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataProvider;
|
import org.mariotaku.twidere.provider.TwidereDataProvider;
|
||||||
import org.mariotaku.twidere.service.BackgroundOperationService;
|
import org.mariotaku.twidere.service.BackgroundOperationService;
|
||||||
import org.mariotaku.twidere.service.RefreshService;
|
import org.mariotaku.twidere.service.RefreshService;
|
||||||
@ -84,8 +83,6 @@ public interface GeneralComponent {
|
|||||||
|
|
||||||
void inject(ThemedFragmentActivity object);
|
void inject(ThemedFragmentActivity object);
|
||||||
|
|
||||||
void inject(TwidereCommandProvider object);
|
|
||||||
|
|
||||||
void inject(TwidereDataProvider object);
|
void inject(TwidereDataProvider object);
|
||||||
|
|
||||||
void inject(BaseListFragment object);
|
void inject(BaseListFragment object);
|
||||||
@ -134,5 +131,5 @@ public interface GeneralComponent {
|
|||||||
|
|
||||||
void inject(CacheProvider object);
|
void inject(CacheProvider object);
|
||||||
|
|
||||||
void inject(DownloadingMediaPageFragment.MediaDownloader object);
|
void inject(CacheDownloadFragment.MediaDownloader object);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user