Merge pull request #3426 from ByteHamster/feedinfo-fragment
Feedinfo page animation
This commit is contained in:
commit
f9fd9c3282
|
@ -139,10 +139,6 @@ dependencies {
|
|||
implementation "com.android.support:recyclerview-v7:$supportVersion"
|
||||
compileOnly 'com.google.android.wearable:wearable:2.2.0'
|
||||
|
||||
// ViewModel and LiveData
|
||||
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
|
||||
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
|
||||
|
||||
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
|
||||
implementation "commons-io:commons-io:$commonsioVersion"
|
||||
implementation "org.jsoup:jsoup:$jsoupVersion"
|
||||
|
|
|
@ -105,17 +105,6 @@
|
|||
android:value="de.danoeh.antennapod.activity.MainActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activity.FeedInfoActivity"
|
||||
android:label="@string/feed_info_label">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activity.FeedSettingsActivity"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:label="@string/feed_settings_label">
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".core.service.PlayerWidgetJobService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
package de.danoeh.antennapod.activity;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.LightingColorFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.LangUtils;
|
||||
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.MaybeOnSubscribe;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Displays information about a feed.
|
||||
*/
|
||||
public class FeedInfoActivity extends AppCompatActivity {
|
||||
|
||||
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String TAG = "FeedInfoActivity";
|
||||
private Feed feed;
|
||||
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private TextView txtvDescription;
|
||||
private TextView lblLanguage;
|
||||
private TextView txtvLanguage;
|
||||
private TextView lblAuthor;
|
||||
private TextView txtvAuthor;
|
||||
private TextView txtvUrl;
|
||||
|
||||
private Disposable disposable;
|
||||
|
||||
|
||||
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(feed != null && feed.getDownload_url() != null) {
|
||||
String url = feed.getDownload_url();
|
||||
ClipData clipData = ClipData.newPlainText(url, url);
|
||||
android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedInfoActivity.this
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cm.setPrimaryClip(clipData);
|
||||
Toast t = Toast.makeText(FeedInfoActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
|
||||
t.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(UserPreferences.getTheme());
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.feedinfo);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1);
|
||||
|
||||
imgvCover = findViewById(R.id.imgvCover);
|
||||
txtvTitle = findViewById(R.id.txtvTitle);
|
||||
TextView txtvAuthorHeader = findViewById(R.id.txtvAuthor);
|
||||
ImageView imgvBackground = findViewById(R.id.imgvBackground);
|
||||
findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
|
||||
findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
|
||||
// https://github.com/bumptech/glide/issues/529
|
||||
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
|
||||
|
||||
|
||||
txtvDescription = findViewById(R.id.txtvDescription);
|
||||
lblLanguage = findViewById(R.id.lblLanguage);
|
||||
txtvLanguage = findViewById(R.id.txtvLanguage);
|
||||
lblAuthor = findViewById(R.id.lblAuthor);
|
||||
txtvAuthor = findViewById(R.id.txtvDetailsAuthor);
|
||||
txtvUrl = findViewById(R.id.txtvUrl);
|
||||
|
||||
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
||||
|
||||
disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
|
||||
Feed feed = DBReader.getFeed(feedId);
|
||||
if (feed != null) {
|
||||
emitter.onSuccess(feed);
|
||||
} else {
|
||||
emitter.onComplete();
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
feed = result;
|
||||
Log.d(TAG, "Language is " + feed.getLanguage());
|
||||
Log.d(TAG, "Author is " + feed.getAuthor());
|
||||
Log.d(TAG, "URL is " + feed.getDownload_url());
|
||||
Glide.with(FeedInfoActivity.this)
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(imgvCover);
|
||||
Glide.with(FeedInfoActivity.this)
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.image_readability_tint)
|
||||
.error(R.color.image_readability_tint)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.transform(new FastBlurTransformation())
|
||||
.dontAnimate())
|
||||
.into(imgvBackground);
|
||||
|
||||
txtvTitle.setText(feed.getTitle());
|
||||
|
||||
String description = feed.getDescription();
|
||||
if(description != null) {
|
||||
if(Feed.TYPE_ATOM1.equals(feed.getType())) {
|
||||
HtmlToPlainText formatter = new HtmlToPlainText();
|
||||
Document feedDescription = Jsoup.parse(feed.getDescription());
|
||||
description = StringUtils.trim(formatter.getPlainText(feedDescription));
|
||||
}
|
||||
} else {
|
||||
description = "";
|
||||
}
|
||||
txtvDescription.setText(description);
|
||||
|
||||
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||
txtvAuthor.setText(feed.getAuthor());
|
||||
txtvAuthorHeader.setText(feed.getAuthor());
|
||||
} else {
|
||||
lblAuthor.setVisibility(View.GONE);
|
||||
txtvAuthor.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TextUtils.isEmpty(feed.getLanguage())) {
|
||||
txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
|
||||
} else {
|
||||
lblLanguage.setVisibility(View.GONE);
|
||||
txtvLanguage.setVisibility(View.GONE);
|
||||
}
|
||||
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
|
||||
Iconify.addIcons(txtvUrl);
|
||||
|
||||
supportInvalidateOptionsMenu();
|
||||
}, error -> {
|
||||
Log.d(TAG, Log.getStackTraceString(error));
|
||||
finish();
|
||||
}, () -> {
|
||||
Log.e(TAG, "Activity was started with invalid arguments");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.feedinfo, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
|
||||
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
|
||||
IntentUtils.isCallable(this, new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
default:
|
||||
try {
|
||||
return FeedMenuHandler.onOptionsItemClicked(this, item, feed);
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(this,
|
||||
e.getMessage());
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
package de.danoeh.antennapod.activity;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.graphics.LightingColorFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.fragment.FeedSettingsFragment;
|
||||
import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Displays information about a feed.
|
||||
*/
|
||||
public class FeedSettingsActivity extends AppCompatActivity {
|
||||
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String TAG = "FeedSettingsActivity";
|
||||
private Feed feed;
|
||||
private Disposable disposable;
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private ImageView imgvBackground;
|
||||
private TextView txtvAuthorHeader;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(UserPreferences.getTheme());
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.feedsettings);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
imgvCover = findViewById(R.id.imgvCover);
|
||||
txtvTitle = findViewById(R.id.txtvTitle);
|
||||
txtvAuthorHeader = findViewById(R.id.txtvAuthor);
|
||||
imgvBackground = findViewById(R.id.imgvBackground);
|
||||
findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
|
||||
findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
|
||||
// https://github.com/bumptech/glide/issues/529
|
||||
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
|
||||
|
||||
long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1);
|
||||
disposable = ViewModelProviders.of(this).get(FeedSettingsViewModel.class).getFeed(feedId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
feed = result;
|
||||
showFragment();
|
||||
showHeader();
|
||||
}, error -> {
|
||||
Log.d(TAG, Log.getStackTraceString(error));
|
||||
finish();
|
||||
}, () -> {
|
||||
Log.e(TAG, "Activity was started with invalid arguments");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
private void showFragment() {
|
||||
FeedSettingsFragment fragment = new FeedSettingsFragment();
|
||||
fragment.setArguments(getIntent().getExtras());
|
||||
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
FragmentTransaction fragmentTransaction =
|
||||
fragmentManager.beginTransaction();
|
||||
fragmentTransaction.replace(R.id.settings_fragment_container, fragment);
|
||||
fragmentTransaction.commit();
|
||||
}
|
||||
|
||||
private void showHeader() {
|
||||
txtvTitle.setText(feed.getTitle());
|
||||
|
||||
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||
txtvAuthorHeader.setText(feed.getAuthor());
|
||||
}
|
||||
|
||||
Glide.with(FeedSettingsActivity.this)
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(imgvCover);
|
||||
Glide.with(FeedSettingsActivity.this)
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.image_readability_tint)
|
||||
.error(R.color.image_readability_tint)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.transform(new FastBlurTransformation())
|
||||
.dontAnimate())
|
||||
.into(imgvBackground);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,6 +69,7 @@ import de.danoeh.antennapod.fragment.FeedItemlistFragment;
|
|||
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
||||
import de.danoeh.antennapod.fragment.QueueFragment;
|
||||
import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
||||
import de.danoeh.antennapod.fragment.TransitionEffect;
|
||||
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
||||
import de.danoeh.antennapod.preferences.PreferenceUpgrader;
|
||||
import io.reactivex.Observable;
|
||||
|
@ -377,15 +378,34 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||
}
|
||||
}
|
||||
|
||||
public void loadChildFragment(Fragment fragment) {
|
||||
public void loadChildFragment(Fragment fragment, TransitionEffect transition) {
|
||||
Validate.notNull(fragment);
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.main_view, fragment, "main")
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
switch (transition) {
|
||||
case FADE:
|
||||
transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
|
||||
break;
|
||||
case FLIP:
|
||||
transaction.setCustomAnimations(
|
||||
R.anim.card_flip_left_in,
|
||||
R.anim.card_flip_left_out,
|
||||
R.anim.card_flip_right_in,
|
||||
R.anim.card_flip_right_out);
|
||||
break;
|
||||
}
|
||||
|
||||
transaction
|
||||
.hide(getSupportFragmentManager().findFragmentByTag("main"))
|
||||
.add(R.id.main_view, fragment, "main")
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
}
|
||||
|
||||
public void loadChildFragment(Fragment fragment) {
|
||||
loadChildFragment(fragment, TransitionEffect.NONE);
|
||||
}
|
||||
|
||||
public void dismissChildFragment() {
|
||||
getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.LightingColorFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.LangUtils;
|
||||
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.MaybeOnSubscribe;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
/**
|
||||
* Displays information about a feed.
|
||||
*/
|
||||
public class FeedInfoFragment extends Fragment {
|
||||
|
||||
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String TAG = "FeedInfoActivity";
|
||||
|
||||
private Feed feed;
|
||||
private Disposable disposable;
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private TextView txtvDescription;
|
||||
private TextView lblLanguage;
|
||||
private TextView txtvLanguage;
|
||||
private TextView lblAuthor;
|
||||
private TextView txtvAuthor;
|
||||
private TextView txtvUrl;
|
||||
private TextView txtvAuthorHeader;
|
||||
private ImageView imgvBackground;
|
||||
|
||||
public static FeedInfoFragment newInstance(Feed feed) {
|
||||
FeedInfoFragment fragment = new FeedInfoFragment();
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(EXTRA_FEED_ID, feed.getId());
|
||||
fragment.setArguments(arguments);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(feed != null && feed.getDownload_url() != null) {
|
||||
String url = feed.getDownload_url();
|
||||
ClipData clipData = ClipData.newPlainText(url, url);
|
||||
android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext()
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cm.setPrimaryClip(clipData);
|
||||
Toast t = Toast.makeText(getContext(), R.string.copied_url_msg, Toast.LENGTH_SHORT);
|
||||
t.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
((MainActivity)getActivity()).getSupportActionBar().setTitle(R.string.feed_info_label);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.feedinfo, null);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
imgvCover = root.findViewById(R.id.imgvCover);
|
||||
txtvTitle = root.findViewById(R.id.txtvTitle);
|
||||
txtvAuthorHeader = root.findViewById(R.id.txtvAuthor);
|
||||
imgvBackground = root.findViewById(R.id.imgvBackground);
|
||||
root.findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
|
||||
root.findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
|
||||
// https://github.com/bumptech/glide/issues/529
|
||||
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
|
||||
|
||||
|
||||
txtvDescription = root.findViewById(R.id.txtvDescription);
|
||||
lblLanguage = root.findViewById(R.id.lblLanguage);
|
||||
txtvLanguage = root.findViewById(R.id.txtvLanguage);
|
||||
lblAuthor = root.findViewById(R.id.lblAuthor);
|
||||
txtvAuthor = root.findViewById(R.id.txtvDetailsAuthor);
|
||||
txtvUrl = root.findViewById(R.id.txtvUrl);
|
||||
|
||||
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
||||
postponeEnterTransition();
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
|
||||
Feed feed = DBReader.getFeed(feedId);
|
||||
if (feed != null) {
|
||||
emitter.onSuccess(feed);
|
||||
} else {
|
||||
emitter.onComplete();
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
feed = result;
|
||||
showFeed();
|
||||
}, error -> Log.d(TAG, Log.getStackTraceString(error)),
|
||||
this::startPostponedEnterTransition);
|
||||
}
|
||||
|
||||
private void showFeed() {
|
||||
Log.d(TAG, "Language is " + feed.getLanguage());
|
||||
Log.d(TAG, "Author is " + feed.getAuthor());
|
||||
Log.d(TAG, "URL is " + feed.getDownload_url());
|
||||
Glide.with(getContext())
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.fitCenter()
|
||||
.dontAnimate())
|
||||
.into(imgvCover);
|
||||
Glide.with(getContext())
|
||||
.load(feed.getImageLocation())
|
||||
.apply(new RequestOptions()
|
||||
.placeholder(R.color.image_readability_tint)
|
||||
.error(R.color.image_readability_tint)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
.transform(new FastBlurTransformation())
|
||||
.dontAnimate())
|
||||
.into(imgvBackground);
|
||||
|
||||
txtvTitle.setText(feed.getTitle());
|
||||
|
||||
String description = feed.getDescription();
|
||||
if(description != null) {
|
||||
if(Feed.TYPE_ATOM1.equals(feed.getType())) {
|
||||
HtmlToPlainText formatter = new HtmlToPlainText();
|
||||
Document feedDescription = Jsoup.parse(feed.getDescription());
|
||||
description = StringUtils.trim(formatter.getPlainText(feedDescription));
|
||||
}
|
||||
} else {
|
||||
description = "";
|
||||
}
|
||||
txtvDescription.setText(description);
|
||||
|
||||
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||
txtvAuthor.setText(feed.getAuthor());
|
||||
txtvAuthorHeader.setText(feed.getAuthor());
|
||||
} else {
|
||||
lblAuthor.setVisibility(View.GONE);
|
||||
txtvAuthor.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TextUtils.isEmpty(feed.getLanguage())) {
|
||||
txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
|
||||
} else {
|
||||
lblLanguage.setVisibility(View.GONE);
|
||||
txtvLanguage.setVisibility(View.GONE);
|
||||
}
|
||||
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
|
||||
Iconify.addIcons(txtvUrl);
|
||||
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.feedinfo, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
|
||||
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
|
||||
IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
boolean handled = false;
|
||||
try {
|
||||
handled = FeedMenuHandler.onOptionsItemClicked(getContext(), item, feed);
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getContext(), e.getMessage());
|
||||
}
|
||||
return handled || super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -38,8 +38,6 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.FeedInfoActivity;
|
||||
import de.danoeh.antennapod.activity.FeedSettingsActivity;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
|
||||
import de.danoeh.antennapod.core.asynctask.FeedRemover;
|
||||
|
@ -141,37 +139,33 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
public void onHiddenChanged(boolean hidden) {
|
||||
super.onHiddenChanged(hidden);
|
||||
if (!hidden && getActivity() != null) {
|
||||
((MainActivity) getActivity()).getSupportActionBar().setTitle("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
registerForContextMenu(getListView());
|
||||
|
||||
EventDistributor.getInstance().register(contentUpdate);
|
||||
EventBus.getDefault().register(this);
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
((MainActivity)getActivity()).getSupportActionBar().setTitle("");
|
||||
updateProgressBarVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
EventDistributor.getInstance().unregister(contentUpdate);
|
||||
EventBus.getDefault().unregister(this);
|
||||
if(disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
resetViewState();
|
||||
}
|
||||
|
||||
private void resetViewState() {
|
||||
EventDistributor.getInstance().unregister(contentUpdate);
|
||||
EventBus.getDefault().unregister(this);
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
adapter = null;
|
||||
listFooter = null;
|
||||
}
|
||||
|
@ -344,13 +338,6 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
return FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), selectedItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
registerForContextMenu(getListView());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if(adapter == null) {
|
||||
|
@ -429,8 +416,9 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
|
||||
}
|
||||
|
||||
private void onFragmentLoaded() {
|
||||
if(!isVisible()) {
|
||||
private void displayList() {
|
||||
if (getView() == null) {
|
||||
Log.e(TAG, "Required root view is not yet created. Stop binding data to UI.");
|
||||
return;
|
||||
}
|
||||
if (adapter == null) {
|
||||
|
@ -514,10 +502,8 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
imgvCover.setOnClickListener(v -> showFeedInfo());
|
||||
butShowSettings.setOnClickListener(v -> {
|
||||
if (feed != null) {
|
||||
Intent startIntent = new Intent(getActivity(), FeedSettingsActivity.class);
|
||||
startIntent.putExtra(FeedSettingsActivity.EXTRA_FEED_ID,
|
||||
feed.getId());
|
||||
startActivity(startIntent);
|
||||
FeedSettingsFragment fragment = FeedSettingsFragment.newInstance(feed);
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.FLIP);
|
||||
}
|
||||
});
|
||||
headerCreated = true;
|
||||
|
@ -525,10 +511,8 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
|
||||
private void showFeedInfo() {
|
||||
if (feed != null) {
|
||||
Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class);
|
||||
startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID,
|
||||
feed.getId());
|
||||
startActivity(startIntent);
|
||||
FeedInfoFragment fragment = FeedInfoFragment.newInstance(feed);
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.FLIP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,7 +618,7 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
feed = result.orElse(null);
|
||||
onFragmentLoaded();
|
||||
displayList();
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +1,66 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.util.Log;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedFilter;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
||||
import de.danoeh.antennapod.dialog.EpisodeFilterDialog;
|
||||
import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel;
|
||||
|
||||
import static de.danoeh.antennapod.activity.FeedSettingsActivity.EXTRA_FEED_ID;
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.MaybeOnSubscribe;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class FeedSettingsFragment extends PreferenceFragmentCompat {
|
||||
private static final CharSequence PREF_EPISODE_FILTER = "episodeFilter";
|
||||
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String TAG = "FeedSettingsFragment";
|
||||
|
||||
private Feed feed;
|
||||
private Disposable disposable;
|
||||
private FeedPreferences feedPreferences;
|
||||
|
||||
public static FeedSettingsFragment newInstance(Feed feed) {
|
||||
FeedSettingsFragment fragment = new FeedSettingsFragment();
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(EXTRA_FEED_ID, feed.getId());
|
||||
fragment.setArguments(arguments);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.feed_settings);
|
||||
|
||||
postponeEnterTransition();
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
ViewModelProviders.of(getActivity()).get(FeedSettingsViewModel.class).getFeed(feedId)
|
||||
disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
|
||||
Feed feed = DBReader.getFeed(feedId);
|
||||
if (feed != null) {
|
||||
emitter.onSuccess(feed);
|
||||
} else {
|
||||
emitter.onComplete();
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
feed = result;
|
||||
feedPreferences = feed.getPreferences();
|
||||
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
|
||||
|
||||
setupAutoDownloadPreference();
|
||||
setupKeepUpdatedPreference();
|
||||
|
@ -43,7 +70,31 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
|
|||
|
||||
updateAutoDeleteSummary();
|
||||
updateAutoDownloadEnabled();
|
||||
}).dispose();
|
||||
}, error -> Log.d(TAG, Log.getStackTraceString(error)),
|
||||
this::startPostponedEnterTransition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.feed_settings_label);
|
||||
if (feed != null) {
|
||||
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
((MainActivity) getActivity()).getSupportActionBar().setSubtitle(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupEpisodeFilterPreference() {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
public enum TransitionEffect {
|
||||
NONE, FLIP, FADE
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package de.danoeh.antennapod.viewmodel;
|
||||
|
||||
import android.arch.lifecycle.ViewModel;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import io.reactivex.Maybe;
|
||||
|
||||
public class FeedSettingsViewModel extends ViewModel {
|
||||
private Feed feed;
|
||||
|
||||
public Maybe<Feed> getFeed(long feedId) {
|
||||
if (feed == null) {
|
||||
return loadFeed(feedId);
|
||||
} else {
|
||||
return Maybe.just(feed);
|
||||
}
|
||||
}
|
||||
|
||||
private Maybe<Feed> loadFeed(long feedId) {
|
||||
return Maybe.create(emitter -> {
|
||||
Feed feed = DBReader.getFeed(feedId);
|
||||
if (feed != null) {
|
||||
this.feed = feed;
|
||||
emitter.onSuccess(feed);
|
||||
} else {
|
||||
emitter.onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Before rotating, immediately set the alpha to 0. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0"
|
||||
android:propertyName="alpha"
|
||||
android:duration="0" />
|
||||
|
||||
<!-- Rotate. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="-180"
|
||||
android:valueTo="0"
|
||||
android:propertyName="rotationY"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:duration="@integer/card_flip_time_full" />
|
||||
|
||||
<!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="0.0"
|
||||
android:valueTo="1.0"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/card_flip_time_half"
|
||||
android:duration="1" />
|
||||
</set>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Rotate. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="0"
|
||||
android:valueTo="180"
|
||||
android:propertyName="rotationY"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:duration="@integer/card_flip_time_full" />
|
||||
|
||||
<!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/card_flip_time_half"
|
||||
android:duration="1" />
|
||||
</set>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Before rotating, immediately set the alpha to 0. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0"
|
||||
android:propertyName="alpha"
|
||||
android:duration="0" />
|
||||
|
||||
<!-- Rotate. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="180"
|
||||
android:valueTo="0"
|
||||
android:propertyName="rotationY"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:duration="@integer/card_flip_time_full" />
|
||||
|
||||
<!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="0.0"
|
||||
android:valueTo="1.0"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/card_flip_time_half"
|
||||
android:duration="1" />
|
||||
</set>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Rotate. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="0"
|
||||
android:valueTo="-180"
|
||||
android:propertyName="rotationY"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:duration="@integer/card_flip_time_full" />
|
||||
|
||||
<!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
|
||||
<objectAnimator
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/card_flip_time_half"
|
||||
android:duration="1" />
|
||||
</set>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<integer name="card_flip_time_full">400</integer>
|
||||
<integer name="card_flip_time_half">200</integer>
|
||||
</resources>
|
|
@ -45,7 +45,6 @@ project.ext {
|
|||
targetSdkVersion = 28
|
||||
|
||||
supportVersion = "27.1.1"
|
||||
lifecycle_version = "1.1.1"
|
||||
workManagerVersion = "1.0.1"
|
||||
awaitilityVersion = "3.1.2"
|
||||
commonsioVersion = "2.5"
|
||||
|
|
Loading…
Reference in New Issue