Merge branch 'develop' into feat/simple-adjust-volume-per-feed
This commit is contained in:
commit
cbee8c3043
@ -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"
|
||||
|
@ -0,0 +1,52 @@
|
||||
package de.danoeh.antennapod.core.service.download;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import de.danoeh.antennapod.core.util.Consumer;
|
||||
|
||||
public class StubDownloader extends Downloader {
|
||||
|
||||
private final long downloadTime;
|
||||
|
||||
@NonNull
|
||||
private final Consumer<DownloadStatus> onDownloadComplete;
|
||||
|
||||
public StubDownloader(@NonNull DownloadRequest request, long downloadTime, @NonNull Consumer<DownloadStatus> onDownloadComplete) {
|
||||
super(request);
|
||||
this.downloadTime = downloadTime;
|
||||
this.onDownloadComplete = onDownloadComplete;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void download() {
|
||||
try {
|
||||
Thread.sleep(downloadTime);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
onDownloadComplete.accept(result);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DownloadRequest getDownloadRequest() {
|
||||
return super.getDownloadRequest();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DownloadStatus getResult() {
|
||||
return super.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return super.isFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
super.cancel();
|
||||
result.setCancelled();
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package de.test.antennapod.service.download;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.awaitility.core.ConditionTimeoutException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.service.download.StubDownloader;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Consumer;
|
||||
|
||||
import static de.test.antennapod.util.event.FeedItemEventListener.withFeedItemEventListener;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @see HttpDownloaderTest for the test of actual download (and saving the file)
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DownloadServiceTest {
|
||||
|
||||
private CountDownLatch latch = null;
|
||||
private Feed testFeed = null;
|
||||
private FeedMedia testMedia11 = null;
|
||||
|
||||
private DownloadService.DownloaderFactory origFactory = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
origFactory = DownloadService.getDownloaderFactory();
|
||||
testFeed = setUpTestFeeds();
|
||||
testMedia11 = testFeed.getItemAtIndex(0).getMedia();
|
||||
}
|
||||
|
||||
private Feed setUpTestFeeds() throws Exception {
|
||||
Feed feed = new Feed("url", null, "Test Feed title 1");
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
feed.setItems(items);
|
||||
FeedItem item1 = new FeedItem(0, "Item 1-1", "Item 1-1", "url", new Date(), FeedItem.NEW, feed);
|
||||
items.add(item1);
|
||||
FeedMedia media1 = new FeedMedia(0, item1, 123, 1, 1, "audio/mp3", null, "http://example.com/episode.mp3", false, null, 0, 0);
|
||||
item1.setMedia(media1);
|
||||
|
||||
DBWriter.setFeedItem(item1).get();
|
||||
return feed;
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
DownloadService.setDownloaderFactory(origFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventsGeneratedCaseMediaDownloadSuccess() throws Exception {
|
||||
// create a stub download that returns successful
|
||||
//
|
||||
// OPEN: Ideally, I'd like the download time long enough so that multiple in-progress DownloadEvents
|
||||
// are generated (to simulate typical download), but it'll make download time quite long (1-2 seconds)
|
||||
// to do so
|
||||
DownloadService.setDownloaderFactory(new StubDownloaderFactory(50, downloadStatus -> {
|
||||
downloadStatus.setSuccessful();
|
||||
}));
|
||||
|
||||
withFeedItemEventListener(feedItemEventListener -> {
|
||||
try {
|
||||
assertEquals(0, feedItemEventListener.getEvents().size());
|
||||
assertFalse("The media in test should not yet been downloaded",
|
||||
DBReader.getFeedMedia(testMedia11.getId()).isDownloaded());
|
||||
|
||||
DownloadRequester.getInstance().downloadMedia(InstrumentationRegistry.getTargetContext(),
|
||||
testMedia11);
|
||||
Awaitility.await()
|
||||
.atMost(1000, TimeUnit.MILLISECONDS)
|
||||
.until(() -> feedItemEventListener.getEvents().size() > 0);
|
||||
assertTrue("After media download has completed, FeedMedia object in db should indicate so.",
|
||||
DBReader.getFeedMedia(testMedia11.getId()).isDownloaded());
|
||||
} catch (ConditionTimeoutException cte) {
|
||||
fail("The expected FeedItemEvent (for media download complete) has not been posted. "
|
||||
+ cte.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class StubDownloaderFactory implements DownloadService.DownloaderFactory {
|
||||
private final long downloadTime;
|
||||
|
||||
@NonNull
|
||||
private final Consumer<DownloadStatus> onDownloadComplete;
|
||||
|
||||
StubDownloaderFactory(long downloadTime, @NonNull Consumer<DownloadStatus> onDownloadComplete) {
|
||||
this.downloadTime = downloadTime;
|
||||
this.onDownloadComplete = onDownloadComplete;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Downloader create(@NonNull DownloadRequest request) {
|
||||
return new StubDownloader(request, downloadTime, onDownloadComplete);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,12 @@ import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.annotation.UiThreadTest;
|
||||
import android.support.test.filters.LargeTest;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -15,14 +21,14 @@ import de.danoeh.antennapod.core.event.QueueEvent;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static de.test.antennapod.util.event.FeedItemEventListener.withFeedItemEventListener;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@ -123,6 +129,43 @@ public class PlaybackServiceTaskManagerTest {
|
||||
pstm.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueueUpdatedUponDownloadComplete() throws Exception {
|
||||
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
{ // Setup test data
|
||||
List<FeedItem> queue = writeTestQueue("a");
|
||||
FeedItem item = DBReader.getFeedItem(queue.get(0).getId());
|
||||
FeedMedia media = new FeedMedia(item, "http://example.com/episode.mp3", 12345, "audio/mp3");
|
||||
item.setMedia(media);
|
||||
DBWriter.setFeedMedia(media).get();
|
||||
DBWriter.setFeedItem(item).get();
|
||||
}
|
||||
|
||||
PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM);
|
||||
final FeedItem testItem = pstm.getQueue().get(0);
|
||||
assertFalse("The item should not yet be downloaded", testItem.getMedia().isDownloaded());
|
||||
|
||||
withFeedItemEventListener( feedItemEventListener -> {
|
||||
// simulate download complete (in DownloadService.MediaHandlerThread)
|
||||
FeedItem item = DBReader.getFeedItem(testItem.getId());
|
||||
item.getMedia().setDownloaded(true);
|
||||
item.getMedia().setFile_url("file://123");
|
||||
item.setAutoDownload(false);
|
||||
DBWriter.setFeedMedia(item.getMedia()).get();
|
||||
DBWriter.setFeedItem(item).get();
|
||||
|
||||
Awaitility.await()
|
||||
.atMost(1000, TimeUnit.MILLISECONDS)
|
||||
.until(() -> feedItemEventListener.getEvents().size() > 0);
|
||||
|
||||
final FeedItem itemUpdated = pstm.getQueue().get(0);
|
||||
assertTrue("media.isDownloaded() should be true - The queue in PlaybackService should be updated after download is completed",
|
||||
itemUpdated.getMedia().isDownloaded());
|
||||
});
|
||||
|
||||
pstm.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartPositionSaver() throws InterruptedException {
|
||||
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
@ -0,0 +1,46 @@
|
||||
package de.test.antennapod.util.event;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import io.reactivex.functions.Consumer;
|
||||
|
||||
/**
|
||||
* Test helpers to listen {@link FeedItemEvent} and handle them accordingly
|
||||
*
|
||||
*/
|
||||
public class FeedItemEventListener {
|
||||
private final List<FeedItemEvent> events = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Provides an listener subscribing to {@link FeedItemEvent} that the callers can use
|
||||
*
|
||||
* Note: it uses RxJava's version of {@link Consumer} because it allows exceptions to be thrown.
|
||||
*/
|
||||
public static void withFeedItemEventListener(@NonNull Consumer<FeedItemEventListener> consumer)
|
||||
throws Exception {
|
||||
FeedItemEventListener feedItemEventListener = new FeedItemEventListener();
|
||||
try {
|
||||
EventBus.getDefault().register(feedItemEventListener);
|
||||
consumer.accept(feedItemEventListener);
|
||||
} finally {
|
||||
EventBus.getDefault().unregister(feedItemEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(FeedItemEvent event) {
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<? extends FeedItemEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
}
|
@ -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"
|
||||
@ -150,13 +139,6 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.StatisticsActivity"
|
||||
android:label="@string/statistics_label">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.ImportExportActivity"
|
||||
android:label="@string/import_export">
|
||||
|
@ -63,6 +63,8 @@ public class PodcastApp extends Application {
|
||||
EventBus.builder()
|
||||
.addIndex(new ApEventBusIndex())
|
||||
.addIndex(new ApCoreEventBusIndex())
|
||||
.logNoSubscriberMessages(false)
|
||||
.sendNoSubscriberEvent(false)
|
||||
.installDefaultEventBus();
|
||||
}
|
||||
|
||||
|
@ -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,6 +1,5 @@
|
||||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@ -8,7 +7,9 @@ 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;
|
||||
@ -16,27 +17,53 @@ import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.core.feed.VolumeReductionSetting;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||
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();
|
||||
@ -48,7 +75,31 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
|
||||
updateAutoDeleteSummary();
|
||||
updateVolumeReductionValue();
|
||||
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
|
||||
}
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
|
||||
public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat {
|
||||
@ -46,6 +47,12 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat {
|
||||
buildEpisodeCleanupPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.auto_download_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -9,6 +9,7 @@ import android.text.Html;
|
||||
import android.text.format.DateUtils;
|
||||
import android.widget.Toast;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
|
||||
import de.danoeh.antennapod.core.service.GpodnetSyncService;
|
||||
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
||||
@ -29,6 +30,12 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupGpodderScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.gpodnet_main_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -14,6 +14,12 @@ public class IntegrationsPreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupIntegrationsScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.integrations_label);
|
||||
}
|
||||
|
||||
private void setupIntegrationsScreen() {
|
||||
findPreference(PREF_SCREEN_GPODDER).setOnPreferenceClickListener(preference -> {
|
||||
((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_gpodder);
|
||||
|
@ -1,20 +1,15 @@
|
||||
package de.danoeh.antennapod.fragment.preferences;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import com.bytehamster.lib.preferencesearch.SearchConfiguration;
|
||||
import com.bytehamster.lib.preferencesearch.SearchPreference;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.AboutActivity;
|
||||
import de.danoeh.antennapod.activity.BugReportActivity;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.activity.StatisticsActivity;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
|
||||
public class MainPreferencesFragment extends PreferenceFragmentCompat {
|
||||
@ -38,6 +33,12 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupSearch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.settings_label);
|
||||
}
|
||||
|
||||
private void setupMainScreen() {
|
||||
findPreference(PREF_SCREEN_USER_INTERFACE).setOnPreferenceClickListener(preference -> {
|
||||
((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_user_interface);
|
||||
@ -68,7 +69,8 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
|
||||
);
|
||||
findPreference(STATISTICS).setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
startActivity(new Intent(getActivity(), StatisticsActivity.class));
|
||||
getFragmentManager().beginTransaction().replace(R.id.content, new StatisticsFragment())
|
||||
.addToBackStack(getString(R.string.statistics_label)).commit();
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
@ -30,6 +30,12 @@ public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupNetworkScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.network_pref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -8,6 +8,7 @@ import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MediaplayerActivity;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
|
||||
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
|
||||
@ -27,6 +28,12 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat {
|
||||
buildSmartMarkAsPlayedPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.playback_pref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -1,23 +1,27 @@
|
||||
package de.danoeh.antennapod.activity;
|
||||
package de.danoeh.antennapod.fragment.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
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.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.adapter.StatisticsListAdapter;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import io.reactivex.Observable;
|
||||
@ -28,10 +32,8 @@ import io.reactivex.schedulers.Schedulers;
|
||||
/**
|
||||
* Displays the 'statistics' screen
|
||||
*/
|
||||
public class StatisticsActivity extends AppCompatActivity
|
||||
implements AdapterView.OnItemClickListener {
|
||||
|
||||
private static final String TAG = StatisticsActivity.class.getSimpleName();
|
||||
public class StatisticsFragment extends Fragment implements AdapterView.OnItemClickListener {
|
||||
private static final String TAG = StatisticsFragment.class.getSimpleName();
|
||||
private static final String PREF_NAME = "StatisticsActivityPrefs";
|
||||
private static final String PREF_COUNT_ALL = "countAll";
|
||||
|
||||
@ -44,54 +46,51 @@ public class StatisticsActivity extends AppCompatActivity
|
||||
private SharedPreferences prefs;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(UserPreferences.getTheme());
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
setContentView(R.layout.statistics_activity);
|
||||
|
||||
prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
|
||||
prefs = getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
countAll = prefs.getBoolean(PREF_COUNT_ALL, false);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
totalTimeTextView = findViewById(R.id.total_time);
|
||||
feedStatisticsList = findViewById(R.id.statistics_list);
|
||||
progressBar = findViewById(R.id.progressBar);
|
||||
listAdapter = new StatisticsListAdapter(this);
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.statistics_activity, container, false);
|
||||
totalTimeTextView = root.findViewById(R.id.total_time);
|
||||
feedStatisticsList = root.findViewById(R.id.statistics_list);
|
||||
progressBar = root.findViewById(R.id.progressBar);
|
||||
listAdapter = new StatisticsListAdapter(getContext());
|
||||
listAdapter.setCountAll(countAll);
|
||||
feedStatisticsList.setAdapter(listAdapter);
|
||||
feedStatisticsList.setOnItemClickListener(this);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
||||
refreshStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.statistics, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.statistics_mode) {
|
||||
if (item.getItemId() == R.id.statistics_mode) {
|
||||
selectStatisticsMode();
|
||||
return true;
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void selectStatisticsMode() {
|
||||
View contentView = View.inflate(this, R.layout.statistics_mode_select_dialog, null);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
View contentView = View.inflate(getContext(), R.layout.statistics_mode_select_dialog, null);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setView(contentView);
|
||||
builder.setTitle(R.string.statistics_mode);
|
||||
|
||||
@ -126,8 +125,8 @@ public class StatisticsActivity extends AppCompatActivity
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
totalTimeTextView.setText(Converter
|
||||
.shortLocalizedDuration(this, countAll ? result.totalTimeCountAll : result.totalTime));
|
||||
totalTimeTextView.setText(Converter.shortLocalizedDuration(getContext(),
|
||||
countAll ? result.totalTimeCountAll : result.totalTime));
|
||||
listAdapter.update(result.feedTime);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
totalTimeTextView.setVisibility(View.VISIBLE);
|
||||
@ -139,14 +138,13 @@ public class StatisticsActivity extends AppCompatActivity
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
DBReader.StatisticsItem stats = listAdapter.getItem(position);
|
||||
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
|
||||
dialog.setTitle(stats.feed.getTitle());
|
||||
dialog.setMessage(getString(R.string.statistics_details_dialog,
|
||||
countAll ? stats.episodesStartedIncludingMarked : stats.episodesStarted,
|
||||
stats.episodes,
|
||||
Converter.shortLocalizedDuration(this, countAll ?
|
||||
stats.timePlayedCountAll : stats.timePlayed),
|
||||
Converter.shortLocalizedDuration(this, stats.time)));
|
||||
stats.episodes, Converter.shortLocalizedDuration(getContext(),
|
||||
countAll ? stats.timePlayedCountAll : stats.timePlayed),
|
||||
Converter.shortLocalizedDuration(getContext(), stats.time)));
|
||||
dialog.setPositiveButton(android.R.string.ok, null);
|
||||
dialog.show();
|
||||
}
|
@ -23,6 +23,7 @@ import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.DirectoryChooserActivity;
|
||||
import de.danoeh.antennapod.activity.ImportExportActivity;
|
||||
import de.danoeh.antennapod.activity.OpmlImportFromPathActivity;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.asynctask.DocumentFileExportWorker;
|
||||
import de.danoeh.antennapod.asynctask.ExportWorker;
|
||||
import de.danoeh.antennapod.core.export.ExportWriter;
|
||||
@ -63,6 +64,12 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupStorageScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.storage_pref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -11,6 +11,7 @@ import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@ -25,6 +26,12 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat {
|
||||
setupInterfaceScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.user_interface_label);
|
||||
}
|
||||
|
||||
private void setupInterfaceScreen() {
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
25
app/src/main/res/anim/card_flip_left_in.xml
Normal file
25
app/src/main/res/anim/card_flip_left_in.xml
Normal file
@ -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>
|
18
app/src/main/res/anim/card_flip_left_out.xml
Normal file
18
app/src/main/res/anim/card_flip_left_out.xml
Normal file
@ -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>
|
25
app/src/main/res/anim/card_flip_right_in.xml
Normal file
25
app/src/main/res/anim/card_flip_right_in.xml
Normal file
@ -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>
|
18
app/src/main/res/anim/card_flip_right_out.xml
Normal file
18
app/src/main/res/anim/card_flip_right_out.xml
Normal file
@ -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>
|
@ -1,41 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/total_time_listened_to_podcasts"
|
||||
android:gravity="center_horizontal"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_gravity="center_horizontal"
|
||||
style="?android:attr/progressBarStyleLarge"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:text="@string/total_time_listened_to_podcasts"
|
||||
android:gravity="center_horizontal"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/total_time"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="45sp"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/total_time"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="28sp"
|
||||
tools:text="10.0 hours"/>
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_gravity="center_horizontal"
|
||||
style="?android:attr/progressBarStyleSmall"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/dividerVertical"/>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/statistics_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:choiceMode="singleChoice"
|
||||
android:clipToPadding="false"
|
||||
android:divider="@android:color/transparent"
|
||||
android:dividerHeight="0dp"
|
||||
android:paddingBottom="@dimen/list_vertical_padding"
|
||||
android:paddingTop="@dimen/list_vertical_padding"
|
||||
android:scrollbarStyle="outsideOverlay" />
|
||||
android:id="@+id/statistics_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:choiceMode="singleChoice"
|
||||
android:clipToPadding="false"
|
||||
android:divider="@android:color/transparent"
|
||||
android:dividerHeight="0dp"
|
||||
android:paddingBottom="@dimen/list_vertical_padding"
|
||||
android:paddingTop="@dimen/list_vertical_padding"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
tools:listitem="@layout/statistics_listitem"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -3,63 +3,54 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_iconwithtext_height"
|
||||
android:paddingLeft="@dimen/listitem_threeline_verticalpadding"
|
||||
android:paddingStart="@dimen/listitem_threeline_verticalpadding"
|
||||
android:paddingRight="@dimen/listitem_threeline_verticalpadding"
|
||||
android:paddingEnd="@dimen/listitem_threeline_verticalpadding"
|
||||
tools:background="@android:color/darker_gray">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvCover"
|
||||
android:contentDescription="@string/cover_label"
|
||||
android:layout_width="@dimen/thumbnail_length_navlist"
|
||||
android:layout_height="@dimen/thumbnail_length_navlist"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
tools:src="@drawable/ic_antenna"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
android:id="@+id/imgvCover"
|
||||
android:contentDescription="@string/cover_label"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@drawable/ic_antenna"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/list_vertical_padding"
|
||||
android:layout_marginStart="@dimen/list_vertical_padding"
|
||||
android:lines="1"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textSize="@dimen/text_size_navdrawer"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
tools:text="23"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
android:id="@+id/txtvTitle"
|
||||
android:lines="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_toRightOf="@id/imgvCover"
|
||||
android:layout_alignTop="@id/imgvCover"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
tools:text="Feed title"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvTitle"
|
||||
android:lines="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_navdrawer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding"
|
||||
android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding"
|
||||
android:layout_toRightOf="@id/imgvCover"
|
||||
android:layout_toEndOf="@id/imgvCover"
|
||||
android:layout_toLeftOf="@id/txtvTime"
|
||||
android:layout_toStartOf="@id/txtvTime"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
tools:text="Navigation feed item title"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
android:id="@+id/txtvTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textSize="14sp"
|
||||
android:layout_toEndOf="@+id/imgvCover"
|
||||
android:layout_toRightOf="@+id/imgvCover"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_below="@+id/txtvTitle"
|
||||
tools:text="23 hours"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
5
app/src/main/res/values/integers.xml
Normal file
5
app/src/main/res/values/integers.xml
Normal file
@ -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"
|
||||
|
@ -218,6 +218,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, ImageR
|
||||
return itemIdentifier;
|
||||
} else if (title != null && !title.isEmpty()) {
|
||||
return title;
|
||||
} else if (hasMedia() && media.getDownload_url() != null) {
|
||||
return media.getDownload_url();
|
||||
} else {
|
||||
return link;
|
||||
}
|
||||
|
@ -92,11 +92,9 @@ class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(@NonNull String model, int width, int height, @NonNull Options options) {
|
||||
Log.d(TAG, "buildLoadData() called with: " + "model = [" + model + "], width = ["
|
||||
+ width + "], height = [" + height + "]");
|
||||
if(TextUtils.isEmpty(model)) {
|
||||
if (TextUtils.isEmpty(model)) {
|
||||
return null;
|
||||
} else if(model.startsWith("/")) {
|
||||
} else if (model.startsWith("/")) {
|
||||
return new LoadData<>(new ObjectKey(model), new AudioCoverFetcher(model));
|
||||
} else {
|
||||
GlideUrl url = new GlideUrl(model);
|
||||
|
@ -14,6 +14,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@ -435,12 +436,40 @@ public class DownloadService extends Service {
|
||||
queryDownloads();
|
||||
}
|
||||
|
||||
private Downloader getDownloader(DownloadRequest request) {
|
||||
if (!URLUtil.isHttpUrl(request.getSource()) && !URLUtil.isHttpsUrl(request.getSource())) {
|
||||
Log.e(TAG, "Could not find appropriate downloader for " + request.getSource());
|
||||
return null;
|
||||
@VisibleForTesting
|
||||
public interface DownloaderFactory {
|
||||
@Nullable
|
||||
Downloader create(@NonNull DownloadRequest request);
|
||||
}
|
||||
|
||||
private static class DefaultDownloaderFactory implements DownloaderFactory {
|
||||
@Nullable
|
||||
@Override
|
||||
public Downloader create(@NonNull DownloadRequest request) {
|
||||
if (!URLUtil.isHttpUrl(request.getSource()) && !URLUtil.isHttpsUrl(request.getSource())) {
|
||||
Log.e(TAG, "Could not find appropriate downloader for " + request.getSource());
|
||||
return null;
|
||||
}
|
||||
return new HttpDownloader(request);
|
||||
}
|
||||
return new HttpDownloader(request);
|
||||
}
|
||||
|
||||
private static DownloaderFactory downloaderFactory = new DefaultDownloaderFactory();
|
||||
|
||||
@VisibleForTesting
|
||||
public static DownloaderFactory getDownloaderFactory() {
|
||||
return downloaderFactory;
|
||||
}
|
||||
|
||||
// public scope rather than package private,
|
||||
// because androidTest put classes in the non-standard de.test.antennapod hierarchy
|
||||
@VisibleForTesting
|
||||
public static void setDownloaderFactory(DownloaderFactory downloaderFactory) {
|
||||
DownloadService.downloaderFactory = downloaderFactory;
|
||||
}
|
||||
|
||||
private Downloader getDownloader(@NonNull DownloadRequest request) {
|
||||
return downloaderFactory.create(request);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -669,6 +698,7 @@ public class DownloadService extends Service {
|
||||
Log.e(TAG, "FeedSyncThread was interrupted");
|
||||
} catch (ExecutionException e) {
|
||||
Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,6 +733,7 @@ public class DownloadService extends Service {
|
||||
Log.e(TAG, "FeedSyncThread was interrupted");
|
||||
} catch (ExecutionException e) {
|
||||
Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -998,14 +1029,17 @@ public class DownloadService extends Service {
|
||||
final FeedItem item = media.getItem();
|
||||
|
||||
try {
|
||||
DBWriter.setFeedMedia(media).get();
|
||||
|
||||
// we've received the media, we don't want to autodownload it again
|
||||
if (item != null) {
|
||||
item.setAutoDownload(false);
|
||||
// setFeedItem() signals (via EventBus) that the item has been updated,
|
||||
// so we do it after the enclosing media has been updated above,
|
||||
// to ensure subscribers will get the updated FeedMedia as well
|
||||
DBWriter.setFeedItem(item).get();
|
||||
}
|
||||
|
||||
DBWriter.setFeedMedia(media).get();
|
||||
|
||||
if (item != null && UserPreferences.enqueueDownloadedEpisodes() &&
|
||||
!DBTasks.isInQueue(DownloadService.this, item.getId())) {
|
||||
DBWriter.addQueueItem(DownloadService.this, item).get();
|
||||
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.playback;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
@ -36,6 +37,7 @@ import de.danoeh.antennapod.core.util.playback.IPlayer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ExoPlayerWrapper implements IPlayer {
|
||||
private static final String TAG = "ExoPlayerWrapper";
|
||||
private final Context mContext;
|
||||
private final Disposable bufferingUpdateDisposable;
|
||||
private SimpleExoPlayer mExoPlayer;
|
||||
@ -205,6 +207,7 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
|
||||
@Override
|
||||
public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException {
|
||||
Log.d(TAG, "setDataSource: " + s);
|
||||
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
|
||||
Util.getUserAgent(mContext, mContext.getPackageName()), null,
|
||||
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
|
||||
|
@ -592,7 +592,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
||||
}
|
||||
|
||||
playerLock.unlock();
|
||||
Log.d(TAG, "getPosition() -> " + retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,9 @@ import android.os.Vibrator;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
@ -14,13 +17,12 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -102,6 +104,34 @@ public class PlaybackServiceTaskManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(FeedItemEvent event) {
|
||||
// Use case: when an item in the queue has been downloaded,
|
||||
// listening to the event to ensure the downloaded item will be used.
|
||||
Log.d(TAG, "onEvent(FeedItemEvent " + event + ")");
|
||||
|
||||
for (FeedItem item : event.items) {
|
||||
if (isItemInQueue(item.getId())) {
|
||||
Log.d(TAG, "onEvent(FeedItemEvent) - some item (" + item.getId() + ") in the queue has been updated (usually downloaded). Refresh the queue.");
|
||||
cancelQueueLoader();
|
||||
loadQueue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isItemInQueue(long itemId) {
|
||||
List<FeedItem> queue = getQueueIfLoaded();
|
||||
if (queue != null) {
|
||||
for (FeedItem item : queue) {
|
||||
if (item.getId() == itemId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the queue if it is already loaded or null if it hasn't been loaded yet.
|
||||
* In order to wait until the queue has been loaded, use getQueue()
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -440,10 +441,9 @@ public final class DBTasks {
|
||||
/**
|
||||
* Get a FeedItem by its identifying value.
|
||||
*/
|
||||
private static FeedItem searchFeedItemByIdentifyingValue(Feed feed,
|
||||
String identifier) {
|
||||
private static FeedItem searchFeedItemByIdentifyingValue(Feed feed, String identifier) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (item.getIdentifyingValue().equals(identifier)) {
|
||||
if (TextUtils.equals(item.getIdentifyingValue(), identifier)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user