Merge branch 'develop' into develop

This commit is contained in:
H. Lehmann 2020-05-04 10:11:12 +02:00 committed by GitHub
commit 4a81dc29f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 296 additions and 206 deletions

View File

@ -1,3 +1,7 @@
#!/bin/zsh
set -o pipefail
runTests() {
./gradlew connectedPlayDebugAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.notAnnotation=de.test.antennapod.IgnoreOnCi \

View File

@ -118,7 +118,7 @@ public class FeedHandlerTest {
assertEquals(media.getMime_type(), parsedMedia.getMime_type());
}
assertEquals(item.getImageUrl(), parsedFeed.getImageUrl());
assertEquals(feed.getImageUrl(), item.getImageLocation());
if (item.getChapters() != null) {
assertNotNull(parsedItem.getChapters());

View File

@ -12,6 +12,12 @@
website="https://github.com/AntennaPod/AntennaPod-AudioPlayer/"
license="Apache 2.0"
licenseText="LICENSE_APACHE-2.0.txt" />
<library
name="Android Jetpack"
author="Google"
website="https://developer.android.com/jetpack"
license="Apache 2.0"
licenseText="LICENSE_APACHE-2.0.txt" />
<library
name="Apache Commons"
author="The Apache Software Foundation"
@ -66,6 +72,12 @@
website="https://github.com/Templarian/MaterialDesign"
license="SIL Open Font, Version 1.1"
licenseText="LICENSE_SIL.txt" />
<library
name="Material Components"
author="Google"
website="https://github.com/material-components/material-components-android"
license="Apache 2.0"
licenseText="LICENSE_APACHE-2.0.txt" />
<library
name="OkHttp"
author="Square"

View File

@ -415,12 +415,17 @@ public class MainActivity extends CastEnabledActivity {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(MessageEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
View parentLayout = findViewById(R.id.drawer_layout);
Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
Snackbar snackbar;
if (getBottomSheet().getState() == BottomSheetBehavior.STATE_COLLAPSED) {
snackbar = showSnackbarAbovePlayer(event.message, Snackbar.LENGTH_SHORT);
} else {
snackbar = Snackbar.make(findViewById(android.R.id.content), event.message, Snackbar.LENGTH_SHORT);
snackbar.show();
}
if (event.action != null) {
snackbar.setAction(getString(R.string.undo), v -> event.action.run());
}
snackbar.show();
}
private void handleNavIntent() {
@ -454,4 +459,22 @@ public class MainActivity extends CastEnabledActivity {
super.onNewIntent(intent);
setIntent(intent);
}
public Snackbar showSnackbarAbovePlayer(int text, int duration) {
Snackbar s = Snackbar.make(findViewById(R.id.main_view), text, duration);
if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
s.setAnchorView(findViewById(R.id.audioplayerFragment));
}
s.show();
return s;
}
public Snackbar showSnackbarAbovePlayer(String text, int duration) {
Snackbar s = Snackbar.make(findViewById(R.id.main_view), text, duration);
if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
s.setAnchorView(findViewById(R.id.audioplayerFragment));
}
s.show();
return s;
}
}

View File

@ -62,6 +62,8 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.text.NumberFormat;
/**
* Provides general features which are both needed for playing audio and video
@ -364,8 +366,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
DBWriter.addFavoriteItem(feedItem);
isFavorite = true;
invalidateOptionsMenu();
Toast.makeText(this, R.string.added_to_favorites, Toast.LENGTH_SHORT)
.show();
}
break;
case R.id.remove_from_favorites_item:
@ -373,8 +373,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
DBWriter.removeFavoriteItem(feedItem);
isFavorite = false;
invalidateOptionsMenu();
Toast.makeText(this, R.string.removed_from_favorites, Toast.LENGTH_SHORT)
.show();
}
break;
case R.id.disable_sleeptimer_item: // Fall-through
@ -555,13 +553,13 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
butRev = findViewById(R.id.butRev);
txtvRev = findViewById(R.id.txtvRev);
if (txtvRev != null) {
txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs()));
txtvRev.setText(NumberFormat.getInstance().format(UserPreferences.getRewindSecs()));
}
butPlay = findViewById(R.id.butPlay);
butFF = findViewById(R.id.butFF);
txtvFF = findViewById(R.id.txtvFF);
if (txtvFF != null) {
txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs()));
txtvFF.setText(NumberFormat.getInstance().format(UserPreferences.getFastForwardSecs()));
}
butSkip = findViewById(R.id.butSkip);

View File

@ -1,5 +1,6 @@
package de.danoeh.antennapod.adapter;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.text.Layout;
@ -18,6 +19,7 @@ import com.joanzapata.iconify.widget.IconButton;
import com.joanzapata.iconify.widget.IconTextView;
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.feed.FeedMedia;
@ -35,10 +37,10 @@ import de.danoeh.antennapod.view.viewholder.DownloadItemViewHolder;
public class DownloadLogAdapter extends BaseAdapter {
private static final String TAG = "DownloadLogAdapter";
private final Context context;
private final Activity context;
private final ItemAccess itemAccess;
public DownloadLogAdapter(Context context, ItemAccess itemAccess) {
public DownloadLogAdapter(Activity context, ItemAccess itemAccess) {
super();
this.itemAccess = itemAccess;
this.context = context;
@ -116,7 +118,8 @@ public class DownloadLogAdapter extends BaseAdapter {
}
try {
DownloadRequester.getInstance().downloadMedia(context, true, media.getItem());
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
((MainActivity) context).showSnackbarAbovePlayer(
R.string.status_downloading_label, Toast.LENGTH_SHORT);
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());

View File

@ -33,11 +33,11 @@ import de.danoeh.antennapod.fragment.SubscriptionFragment;
import org.apache.commons.lang3.ArrayUtils;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* BaseAdapter for the navigation drawer
@ -247,19 +247,19 @@ public class NavListAdapter extends BaseAdapter
if (tag.equals(QueueFragment.TAG)) {
int queueSize = itemAccess.getQueueSize();
if (queueSize > 0) {
holder.count.setText(String.format(Locale.getDefault(), "%d", queueSize));
holder.count.setText(NumberFormat.getInstance().format(queueSize));
holder.count.setVisibility(View.VISIBLE);
}
} else if (tag.equals(EpisodesFragment.TAG)) {
int unreadItems = itemAccess.getNumberOfNewItems();
if (unreadItems > 0) {
holder.count.setText(String.format(Locale.getDefault(), "%d", unreadItems));
holder.count.setText(NumberFormat.getInstance().format(unreadItems));
holder.count.setVisibility(View.VISIBLE);
}
} else if (tag.equals(SubscriptionFragment.TAG)) {
int sum = itemAccess.getFeedCounterSum();
if (sum > 0) {
holder.count.setText(String.format(Locale.getDefault(), "%d", sum));
holder.count.setText(NumberFormat.getInstance().format(sum));
holder.count.setVisibility(View.VISIBLE);
}
} else if(tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
@ -352,7 +352,7 @@ public class NavListAdapter extends BaseAdapter
int counter = itemAccess.getFeedCounter(feed.getId());
if(counter > 0) {
holder.count.setVisibility(View.VISIBLE);
holder.count.setText(String.format(Locale.getDefault(), "%d", counter));
holder.count.setText(NumberFormat.getInstance().format(counter));
} else {
holder.count.setVisibility(View.GONE);
}

View File

@ -16,6 +16,7 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.Locale;
import de.danoeh.antennapod.R;
@ -99,8 +100,8 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
int count = itemAccess.getFeedCounter(feed.getId());
if(count > 0) {
holder.count.setPrimaryText(String.format(Locale.getDefault(), "%d",
itemAccess.getFeedCounter(feed.getId())));
holder.count.setPrimaryText(
NumberFormat.getInstance().format(itemAccess.getFeedCounter(feed.getId())));
holder.count.setVisibility(View.VISIBLE);
} else {
holder.count.setVisibility(View.GONE);

View File

@ -37,8 +37,6 @@ public class CancelDownloadActionButton extends ItemActionButton {
if (UserPreferences.isEnableAutodownload()) {
DBWriter.setFeedItemAutoDownload(media.getItem(), false);
Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
}
}
}

View File

@ -1,7 +1,6 @@
package de.danoeh.antennapod.adapter.actionbutton;
import android.content.Context;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import de.danoeh.antennapod.R;
@ -42,14 +41,12 @@ class MobileDownloadHelper {
private static void addToQueue(Context context, FeedItem item) {
addToQueueTimestamp = System.currentTimeMillis();
DBWriter.addQueueItem(context, item);
Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
}
private static void downloadFeedItems(Context context, FeedItem item) {
allowMobileDownloadTimestamp = System.currentTimeMillis();
try {
DownloadRequester.getInstance().downloadMedia(context, true, item);
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());

View File

@ -46,7 +46,7 @@ public class PlayActionButton extends ItemActionButton {
.start();
if (media.getMediaType() == MediaType.VIDEO) {
context.startActivity(PlaybackService.getPlayerActivityIntent(context));
context.startActivity(PlaybackService.getPlayerActivityIntent(context, media));
}
}
}

View File

@ -49,7 +49,7 @@ public class StreamActionButton extends ItemActionButton {
.start();
if (media.getMediaType() == MediaType.VIDEO) {
context.startActivity(PlaybackService.getPlayerActivityIntent(context));
context.startActivity(PlaybackService.getPlayerActivityIntent(context, media));
}
}
}

View File

@ -1,9 +1,9 @@
package de.danoeh.antennapod.dialog;
import android.app.AlertDialog;
import android.content.Context;
import android.view.View;
import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import de.danoeh.antennapod.R;
/**

View File

@ -1,6 +1,5 @@
package de.danoeh.antennapod.dialog;
import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -17,6 +16,7 @@ import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.collection.ArrayMap;
@ -25,6 +25,7 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBWriter;
@ -313,8 +314,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
}
if (resId != 0) {
Snackbar.make(getActivity().findViewById(android.R.id.content), resId, Snackbar.LENGTH_SHORT)
.show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(resId, Snackbar.LENGTH_SHORT);
return true;
} else {
return false;
@ -470,12 +470,8 @@ public class EpisodesApplyActionFragment extends Fragment {
private void close(@PluralsRes int msgId, int numItems) {
if (numItems > 0) {
Snackbar.make(getActivity().findViewById(android.R.id.content),
getResources().getQuantityString(msgId, numItems, numItems),
Snackbar.LENGTH_LONG
)
.setAction(android.R.string.ok, v -> { })
.show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG);
}
getActivity().getSupportFragmentManager().popBackStack();
}

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import java.text.NumberFormat;
import java.util.Locale;
import de.danoeh.antennapod.R;
@ -29,7 +30,8 @@ public class SkipPreferenceDialog {
if (skipSecs == values[i]) {
checked = i;
}
choices[i] = values[i] + " " + context.getString(R.string.time_seconds);
choices[i] = String.format(Locale.getDefault(),
"%d %s", values[i], context.getString(R.string.time_seconds));
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
@ -48,7 +50,7 @@ public class SkipPreferenceDialog {
UserPreferences.setRewindSecs(seconds);
}
if (textView != null) {
textView.setText(String.format(Locale.getDefault(), "%d", seconds));
textView.setText(NumberFormat.getInstance().format(seconds));
}
}
});

View File

@ -18,6 +18,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
@ -141,7 +142,7 @@ public class SleepTimerDialog extends DialogFragment {
Button setButton = content.findViewById(R.id.setSleeptimerButton);
setButton.setOnClickListener(v -> {
if (!PlaybackService.isRunning) {
Toast.makeText(getContext(), R.string.no_media_playing_label, Toast.LENGTH_LONG).show();
Snackbar.make(content, R.string.no_media_playing_label, Snackbar.LENGTH_LONG).show();
}
try {
savePreferences();

View File

@ -29,6 +29,7 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.CastEnabledActivity;
@ -124,8 +125,8 @@ public class AudioPlayerFragment extends Fragment implements
setupLengthTextView();
setupControlButtons();
setupPlaybackSpeedButton();
txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs()));
txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs()));
txtvRev.setText(NumberFormat.getInstance().format(UserPreferences.getRewindSecs()));
txtvFF.setText(NumberFormat.getInstance().format(UserPreferences.getFastForwardSecs()));
sbPosition.setOnSeekBarChangeListener(this);
pager = root.findViewById(R.id.pager);

View File

@ -1,9 +1,9 @@
package de.danoeh.antennapod.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.res.TypedArray;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.ListFragment;
import androidx.core.view.MenuItemCompat;
import android.util.Log;

View File

@ -146,7 +146,8 @@ public abstract class EpisodesListFragment extends Fragment {
public void onConfirmButtonPressed(DialogInterface dialog) {
dialog.dismiss();
DBWriter.markAllItemsRead();
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.mark_all_read_msg, Toast.LENGTH_SHORT);
}
};
markAllReadConfirmationDialog.createNewDialog().show();
@ -160,7 +161,8 @@ public abstract class EpisodesListFragment extends Fragment {
public void onConfirmButtonPressed(DialogInterface dialog) {
dialog.dismiss();
DBWriter.removeAllNewFlags();
Toast.makeText(getActivity(), R.string.removed_all_new_flags_msg, Toast.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.removed_all_new_flags_msg, Toast.LENGTH_SHORT);
}
};
removeAllNewFlagsConfirmationDialog.createNewDialog().show();

View File

@ -10,6 +10,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
import org.greenrobot.eventbus.Subscribe;
@ -68,9 +69,8 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
if (item != null) {
DBWriter.removeFavoriteItem(item);
Snackbar snackbar = Snackbar.make(root, getString(R.string.removed_item), Snackbar.LENGTH_LONG);
snackbar.setAction(getString(R.string.undo), v -> DBWriter.addFavoriteItem(item));
snackbar.show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.removed_item, Snackbar.LENGTH_LONG)
.setAction(getString(R.string.undo), v -> DBWriter.addFavoriteItem(item));
}
}
};

View File

@ -91,7 +91,7 @@ public class FeedInfoFragment extends Fragment {
android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext()
.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(clipData);
Snackbar.make(getView(), R.string.copied_url_msg, Snackbar.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.copied_url_msg, Snackbar.LENGTH_SHORT);
}
}
};
@ -234,7 +234,8 @@ public class FeedInfoFragment extends Fragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (feed == null) {
Toast.makeText(getContext(), R.string.please_wait_for_data, Toast.LENGTH_LONG).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.please_wait_for_data, Toast.LENGTH_LONG);
return super.onOptionsItemSelected(item);
}
boolean handled = false;

View File

@ -249,7 +249,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
if (feed == null) {
Toast.makeText(getContext(), R.string.please_wait_for_data, Toast.LENGTH_LONG).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.please_wait_for_data, Toast.LENGTH_LONG);
return true;
}
try {

View File

@ -142,7 +142,8 @@ public class ItemFragment extends Fragment {
&& ObjectsCompat.equals(item.getMedia().getIdentifier(), controller.getMedia().getIdentifier())) {
controller.seekTo(time);
} else {
Snackbar.make(getView(), R.string.play_this_to_seek_position, Snackbar.LENGTH_LONG).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.play_this_to_seek_position,
Snackbar.LENGTH_LONG);
}
});
registerForContextMenu(webvDescription);

View File

@ -86,6 +86,7 @@ public class ItemPagerFragment extends Fragment {
pager.setId(newId);
pager.setAdapter(new ItemPagerAdapter(this));
pager.setCurrentItem(feedItemPos, false);
pager.setOffscreenPageLimit(1);
loadItem(feedItems[feedItemPos]);
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override

View File

@ -16,6 +16,7 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
@ -388,11 +389,9 @@ public class QueueFragment extends Fragment {
recyclerAdapter.setLocked(locked);
}
if (locked) {
Snackbar.make(getActivity().findViewById(android.R.id.content),
R.string.queue_locked, Snackbar.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_locked, Snackbar.LENGTH_SHORT);
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content),
R.string.queue_unlocked, Snackbar.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_unlocked, Snackbar.LENGTH_SHORT);
}
}
@ -497,16 +496,16 @@ public class QueueFragment extends Fragment {
final boolean isRead = item.isPlayed();
DBWriter.markItemPlayed(FeedItem.PLAYED, false, item.getId());
DBWriter.removeQueueItem(getActivity(), true, item);
Snackbar snackbar = Snackbar.make(root, getString(item.hasMedia()
? R.string.marked_as_read_label : R.string.marked_as_read_no_media_label),
Snackbar.LENGTH_LONG);
snackbar.setAction(getString(R.string.undo), v -> {
DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
if(!isRead) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
}
});
snackbar.show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
item.hasMedia() ? R.string.marked_as_read_label : R.string.marked_as_read_no_media_label,
Snackbar.LENGTH_LONG)
.setAction(getString(R.string.undo), v -> {
DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
if (!isRead) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
}
});
}
@Override

View File

@ -7,6 +7,7 @@ import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import de.danoeh.antennapod.activity.MainActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@ -108,10 +109,9 @@ public class RunningDownloadsFragment extends ListFragment {
&& UserPreferences.isEnableAutodownload()) {
FeedMedia media = DBReader.getFeedMedia(downloadRequest.getFeedfileId());
DBWriter.setFeedItemAutoDownload(media.getItem(), false);
Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg,
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), R.string.download_canceled_msg, Toast.LENGTH_SHORT).show();
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_SHORT);
}
}
};

View File

@ -8,6 +8,7 @@ import androidx.preference.PreferenceFragmentCompat;
import android.text.Html;
import android.text.format.DateUtils;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.core.event.SyncServiceEvent;
@ -91,8 +92,7 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
});
findPreference(PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(preference -> {
GpodnetPreferences.logout();
Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT);
toast.show();
Snackbar.make(getView(), R.string.pref_gpodnet_logout_toast, Snackbar.LENGTH_LONG).show();
updateGpodnetPreferenceScreen();
return true;
});

View File

@ -10,6 +10,7 @@ import android.view.Menu;
import android.view.MenuItem;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
@ -290,14 +291,14 @@ public class FeedItemMenuHandler {
}
};
Snackbar snackbar = Snackbar.make(fragment.getView(), fragment.getString(R.string.removed_new_flag_label),
Snackbar.LENGTH_LONG);
snackbar.setAction(fragment.getString(R.string.undo), v -> {
DBWriter.markItemPlayed(FeedItem.NEW, item.getId());
// don't forget to cancel the thing that's going to remove the media
h.removeCallbacks(r);
});
snackbar.show();
Snackbar snackbar = ((MainActivity) fragment.getActivity()).showSnackbarAbovePlayer(
R.string.removed_new_flag_label, Snackbar.LENGTH_LONG)
.setAction(fragment.getString(R.string.undo), v -> {
DBWriter.markItemPlayed(FeedItem.NEW, item.getId());
// don't forget to cancel the thing that's going to remove the media
h.removeCallbacks(r);
});
h.postDelayed(r, (int) Math.ceil(snackbar.getDuration() * 1.05f));
}

View File

@ -1,7 +1,7 @@
package de.danoeh.antennapod.preferences;
import android.app.AlertDialog;
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import android.text.InputFilter;
import android.util.AttributeSet;

View File

@ -23,6 +23,7 @@ public class PagerIndicatorView extends View {
private int disabledPage = -1;
private int circleColor = 0;
private int circleColorHighlight = -1;
private boolean isLocaleRtl = false;
public PagerIndicatorView(Context context) {
super(context);
@ -40,6 +41,9 @@ public class PagerIndicatorView extends View {
}
private void setup() {
isLocaleRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
== ViewCompat.LAYOUT_DIRECTION_RTL;
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
@ -50,6 +54,14 @@ public class PagerIndicatorView extends View {
a.recycle();
}
/**
* Visual and logical position distinction only happens in RTL locales (e.g. Persian)
* where pages positions are flipped thus it does nothing in LTR locales (e.g. English)
*/
private float logicalPositionToVisual(float position) {
return isLocaleRtl ? numPages - 1 - position : position;
}
public void setViewPager(ViewPager2 pager) {
numPages = pager.getAdapter().getItemCount();
pager.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@ -59,22 +71,18 @@ public class PagerIndicatorView extends View {
invalidate();
}
});
boolean isLocaleRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
== ViewCompat.LAYOUT_DIRECTION_RTL;
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
PagerIndicatorView.this.position = position + positionOffset;
if (isLocaleRtl) {
PagerIndicatorView.this.position = numPages - 1 - PagerIndicatorView.this.position;
}
PagerIndicatorView.this.position = logicalPositionToVisual(
position + positionOffset);
invalidate();
}
});
}
public void setDisabledPage(int disabledPage) {
this.disabledPage = disabledPage;
this.disabledPage = (int) logicalPositionToVisual(disabledPage);
invalidate();
}

View File

@ -16,6 +16,7 @@ import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.core.util.Consumer;
import androidx.core.view.ViewCompat;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.util.Converter;
@ -115,7 +116,9 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene
android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext()
.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(clipData);
Snackbar.make(this, R.string.copied_url_msg, Snackbar.LENGTH_LONG).show();
Snackbar s = Snackbar.make(this, R.string.copied_url_msg, Snackbar.LENGTH_LONG);
ViewCompat.setElevation(s.getView(), 100);
s.show();
break;
case R.id.go_to_position_item:
if (Timeline.isTimecodeLink(selectedUrl) && timecodeSelectedListener != null) {

View File

@ -2,7 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="@android:integer/config_mediumAnimTime"
android:duration="@integer/fragment_transition_duration"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />

View File

@ -2,7 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="@android:integer/config_mediumAnimTime"
android:duration="@integer/fragment_transition_duration"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="0.0" />

View File

@ -4,5 +4,6 @@
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_mediumAnimTime"/>
android:duration="@integer/fragment_transition_duration"
android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
</set>

View File

@ -4,5 +4,6 @@
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_mediumAnimTime" />
android:duration="@integer/fragment_transition_duration"
android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
</set>

View File

@ -4,5 +4,6 @@
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_mediumAnimTime"/>
android:duration="@integer/fragment_transition_duration"
android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
</set>

View File

@ -4,5 +4,6 @@
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_mediumAnimTime" />
android:duration="@integer/fragment_transition_duration"
android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
</set>

View File

@ -14,7 +14,8 @@
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
android:background="?android:attr/windowBackground"
app:contentScrim="?android:attr/windowBackground"
app:scrimAnimationDuration="200"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

View File

@ -14,7 +14,8 @@
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
android:background="?android:attr/windowBackground"
app:contentScrim="?android:attr/windowBackground"
app:scrimAnimationDuration="200"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

View File

@ -25,8 +25,8 @@
android:minHeight="0dp"
android:minWidth="0dp"
android:text="@string/discover_more"
android:id="@+id/discover_more"
style="?android:attr/buttonBarButtonStyle"/>
style="@style/Widget.MaterialComponents.Button.TextButton"
android:id="@+id/discover_more"/>
</LinearLayout>
<RelativeLayout

View File

@ -14,6 +14,7 @@
android:elevation="4dp"
android:outlineProvider="bounds"
android:foreground="?android:attr/selectableItemBackground"
android:background="?android:attr/windowBackground"
squareImageView:direction="height" />
</LinearLayout>

View File

@ -11,7 +11,7 @@
android:id="@+id/imgvCover"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:scaleType="fitCenter"
tools:src="@mipmap/ic_launcher_round"
squareImageView:direction="width"/>
@ -37,9 +37,9 @@
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
app:backgroundColor="?attr/colorAccent"
app:backgroundColor="?attr/colorSecondary"
app:corner="rightTop"
app:primaryText="Test"
app:primaryTextColor="@color/white"
app:primaryTextColor="?attr/colorOnSecondary"
app:primaryTextSize="12sp" />
</RelativeLayout>

View File

@ -75,19 +75,19 @@
<CheckBox
android:id="@+id/cbShakeToReset"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shake_to_reset_label"/>
<CheckBox
android:id="@+id/cbVibrate"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/timer_vibration_label"/>
<CheckBox
android:id="@+id/chAutoEnable"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/auto_enable_label"/>

View File

@ -22,7 +22,7 @@
android:summary="@string/pref_feed_playback_speed_sum"/>
<Preference
android:key="skipping"
android:key="feedAutoSkip"
android:summary="@string/pref_feed_skip_sum"
android:title="@string/pref_feed_skip" />

View File

@ -60,6 +60,7 @@ dependencies {
implementation 'androidx.media:media:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation "androidx.work:work-runtime:$workManagerVersion"
implementation 'com.google.android.material:material:1.1.0'
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation "commons-io:commons-io:$commonsioVersion"
@ -85,12 +86,13 @@ dependencies {
api 'androidx.mediarouter:mediarouter:1.0.0'
playApi "com.google.android.gms:play-services-cast:$playServicesVersion"
api "com.google.android.support:wearable:$wearableSupportVersion"
compileOnly "com.google.android.wearable:wearable:$wearableSupportVersion"
} else {
System.out.println("core: free build hack, skipping some dependencies")
}
testImplementation "org.awaitility:awaitility:$awaitilityVersion"
testImplementation 'junit:junit:4.12'
testImplementation 'junit:junit:4.13'
testImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"

View File

@ -41,6 +41,8 @@ import de.danoeh.antennapod.core.sync.model.SyncServiceException;
import de.danoeh.antennapod.core.sync.model.UploadChangesResponse;
import de.danoeh.antennapod.core.util.URLChecker;
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
import io.reactivex.Completable;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
@ -50,6 +52,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class SyncService extends Worker {
private static final String PREF_NAME = "SyncService";
@ -62,7 +65,7 @@ public class SyncService extends Worker {
private static final String PREF_LAST_SYNC_ATTEMPT_SUCCESS = "last_sync_attempt_success";
private static final String TAG = "SyncService";
private static final String WORK_ID_SYNC = "SyncServiceWorkId";
private static final Object lock = new Object();
private static final ReentrantLock lock = new ReentrantLock();
private ISyncService syncServiceImpl;
@ -100,23 +103,22 @@ public class SyncService extends Worker {
}
public static void clearQueue(Context context) {
synchronized (lock) {
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
executeLockedAsync(() ->
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
.putLong(PREF_LAST_SUBSCRIPTION_SYNC_TIMESTAMP, 0)
.putLong(PREF_LAST_EPISODE_ACTIONS_SYNC_TIMESTAMP, 0)
.putLong(PREF_LAST_SYNC_ATTEMPT_TIMESTAMP, 0)
.putString(PREF_QUEUED_EPISODE_ACTIONS, "[]")
.putString(PREF_QUEUED_FEEDS_ADDED, "[]")
.putString(PREF_QUEUED_FEEDS_REMOVED, "[]")
.apply();
}
.apply());
}
public static void enqueueFeedAdded(Context context, String downloadUrl) {
if (!GpodnetPreferences.loggedIn()) {
return;
}
synchronized (lock) {
executeLockedAsync(() -> {
try {
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
String json = prefs.getString(PREF_QUEUED_FEEDS_ADDED, "[]");
@ -126,15 +128,15 @@ public class SyncService extends Worker {
} catch (JSONException e) {
e.printStackTrace();
}
}
sync(context);
sync(context);
});
}
public static void enqueueFeedRemoved(Context context, String downloadUrl) {
if (!GpodnetPreferences.loggedIn()) {
return;
}
synchronized (lock) {
executeLockedAsync(() -> {
try {
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
String json = prefs.getString(PREF_QUEUED_FEEDS_REMOVED, "[]");
@ -144,15 +146,15 @@ public class SyncService extends Worker {
} catch (JSONException e) {
e.printStackTrace();
}
}
sync(context);
sync(context);
});
}
public static void enqueueEpisodeAction(Context context, EpisodeAction action) {
if (!GpodnetPreferences.loggedIn()) {
return;
}
synchronized (lock) {
executeLockedAsync(() -> {
try {
SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
String json = prefs.getString(PREF_QUEUED_EPISODE_ACTIONS, "[]");
@ -162,8 +164,8 @@ public class SyncService extends Worker {
} catch (JSONException e) {
e.printStackTrace();
}
}
sync(context);
sync(context);
});
}
public static void sync(Context context) {
@ -181,19 +183,20 @@ public class SyncService extends Worker {
}
public static void fullSync(Context context) {
synchronized (lock) {
executeLockedAsync(() -> {
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
.putLong(PREF_LAST_SUBSCRIPTION_SYNC_TIMESTAMP, 0)
.putLong(PREF_LAST_EPISODE_ACTIONS_SYNC_TIMESTAMP, 0)
.putLong(PREF_LAST_SYNC_ATTEMPT_TIMESTAMP, 0)
.apply();
}
OneTimeWorkRequest workRequest = getWorkRequest()
.setInitialDelay(0L, TimeUnit.SECONDS)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
OneTimeWorkRequest workRequest = getWorkRequest()
.setInitialDelay(0L, TimeUnit.SECONDS)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
});
}
private static OneTimeWorkRequest.Builder getWorkRequest() {
@ -209,6 +212,30 @@ public class SyncService extends Worker {
.setInitialDelay(5L, TimeUnit.SECONDS); // Give it some time, so other actions can be queued
}
/**
* Take the lock and execute runnable (to prevent changes to preferences being lost when enqueueing while sync is
* in progress). If the lock is free, the runnable is directly executed in the calling thread to prevent overhead.
*/
private static void executeLockedAsync(Runnable runnable) {
if (lock.tryLock()) {
try {
runnable.run();
} finally {
lock.unlock();
}
} else {
Completable.fromRunnable(() -> {
lock.lock();
try {
runnable.run();
} finally {
lock.unlock();
}
}).subscribeOn(Schedulers.io())
.subscribe();
}
}
public static boolean isLastSyncSuccessful(Context context) {
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.getBoolean(PREF_LAST_SYNC_ATTEMPT_SUCCESS, false);
@ -304,7 +331,8 @@ public class SyncService extends Worker {
Log.d(TAG, "Added: " + StringUtils.join(queuedAddedFeeds, ", "));
Log.d(TAG, "Removed: " + StringUtils.join(queuedRemovedFeeds, ", "));
synchronized (lock) {
lock.lock();
try {
UploadChangesResponse uploadResponse = syncServiceImpl
.uploadSubscriptionChanges(queuedAddedFeeds, queuedRemovedFeeds);
getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
@ -312,6 +340,8 @@ public class SyncService extends Worker {
getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
.putString(PREF_QUEUED_FEEDS_REMOVED, "[]").apply();
newTimeStamp = uploadResponse.timestamp;
} finally {
lock.unlock();
}
}
getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
@ -349,7 +379,8 @@ public class SyncService extends Worker {
}
}
if (queuedEpisodeActions.size() > 0) {
synchronized (lock) {
lock.lock();
try {
Log.d(TAG, "Uploading " + queuedEpisodeActions.size() + " actions: "
+ StringUtils.join(queuedEpisodeActions, ", "));
UploadChangesResponse postResponse = syncServiceImpl.uploadEpisodeActions(queuedEpisodeActions);
@ -357,6 +388,8 @@ public class SyncService extends Worker {
Log.d(TAG, "Upload episode response: " + postResponse);
getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()
.putString(PREF_QUEUED_EPISODE_ACTIONS, "[]").apply();
} finally {
lock.unlock();
}
}
getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit()

View File

@ -2,25 +2,16 @@
<resources>
<style name="Theme.AntennaPod.Light" parent="Theme.Base.AntennaPod.Light">
<item name="android:windowContentTransitions">true</item>
<!-- To make icons visible -->
<item name="android:statusBarColor">@color/grey600</item>
</style>
<style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark">
<item name="android:windowContentTransitions">true</item>
<item name="android:statusBarColor">@color/background_darktheme</item>
</style>
<style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack">
<item name="android:windowContentTransitions">true</item>
<item name="android:navigationBarColor">@color/black</item>
<item name="android:colorAccent">@color/white</item>
<item name="android:colorPrimary">@color/black</item>
<item name="android:colorPrimaryDark">@color/black</item>
<item name="android:statusBarColor">@color/black</item>
</style>
<style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle">
<item name="android:navigationBarColor">@color/black</item>
<item name="android:colorAccent">@color/white</item>
<item name="android:colorPrimary">@color/black</item>
<item name="android:colorPrimaryDark">@color/black</item>
</style>
</resources>

View File

@ -1,13 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light.NoTitle">
<item name="android:windowLightStatusBar">true</item>
<item name="colorPrimaryDark">@color/primary_light</item>
</style>
<style name="Theme.AntennaPod.Light" parent="Theme.Base.AntennaPod.Light">
<item name="android:windowContentTransitions">true</item>
<item name="android:statusBarColor">@color/background_light</item>
<item name="android:windowLightStatusBar">true</item>
<item name="colorPrimaryDark">@color/primary_light</item>
</style>
</resources>
<style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark">
<item name="android:windowContentTransitions">true</item>
<item name="android:statusBarColor">@color/background_darktheme</item>
<item name="android:windowLightStatusBar">false</item>
</style>
<style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack">
<item name="android:statusBarColor">@color/black</item>
</style>
</resources>

View File

@ -12,8 +12,8 @@
<color name="feed_image_bg">#50000000</color>
<!-- Theme colors -->
<color name="primary_light">#FFFFFF</color>
<color name="primary_darktheme">#303030</color>
<color name="background_light">#FFFFFF</color>
<color name="background_darktheme">#303030</color>
<color name="highlight_light">#DDDDDD</color>
<color name="highlight_dark">#414141</color>
<color name="highlight_trueblack">#414141</color>

View File

@ -1,3 +1,4 @@
<resources>
<integer name="episode_cache_size_unlimited">-1</integer>
<integer name="fragment_transition_duration">300</integer>
</resources>

View File

@ -5,12 +5,22 @@
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.Light" parent="Theme.AppCompat.Light">
<item name="colorPrimary">@color/primary_light</item>
<style name="Theme.Base.AntennaPod.Light" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">@color/accent_light</item>
<item name="colorAccent">@color/accent_light</item>
<item name="colorSecondary">@color/accent_light</item>
<item name="colorOnSecondary">@color/white</item>
<item name="progressBarTheme">@style/ProgressBarLight</item>
<item name="buttonStyle">@style/Widget.AntennaPod.Button</item>
<item name="android:windowBackground">@color/primary_light</item>
<item name="colorPrimaryDark">@color/accent_light</item>
<item name="android:windowBackground">@color/background_light</item>
<item name="tabBackground">@color/background_light</item>
<item name="actionBarStyle">@style/Widget.AntennaPod.ActionBar.Light</item>
<item name="master_switch_background">@color/master_switch_background_light</item>
<item name="currently_playing_background">@color/highlight_light</item>
<item name="action_icon_color">@color/black</item>
<item name="drawer_activated_color">@color/highlight_light</item>
<item name="android:textAllCaps">false</item>
<item name="storage">@drawable/ic_storage_black</item>
<item name="ic_network">@drawable/ic_network_black</item>
<item name="statistics">@drawable/ic_statistics_black</item>
@ -38,7 +48,6 @@
<item name="stat_playlist">@drawable/ic_playlist_black</item>
<item name="type_video">@drawable/ic_videocam_black_24dp</item>
<item name="dragview_background">@drawable/ic_drag_lighttheme</item>
<item name="drawer_activated_color">@color/highlight_light</item>
<item name="ic_history">@drawable/ic_history_black</item>
<item name="ic_folder">@drawable/ic_folder_black</item>
<item name="ic_settings_playback">@drawable/ic_av_play_black_24dp</item>
@ -62,10 +71,6 @@
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
<item name="ic_key">@drawable/ic_key_black</item>
<item name="ic_volume_adaption">@drawable/ic_volume_adaption_black</item>
<item name="master_switch_background">@color/master_switch_background_light</item>
<item name="currently_playing_background">@color/highlight_light</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="action_icon_color">@color/black</item>
<item name="scrollbar_thumb">@drawable/scrollbar_thumb_light</item>
</style>
@ -73,14 +78,23 @@
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.Dark" parent="Theme.AppCompat">
<style name="Theme.Base.AntennaPod.Dark" parent="Theme.MaterialComponents">
<item name="colorAccent">@color/accent_dark</item>
<item name="colorPrimary">@color/primary_darktheme</item>
<item name="colorPrimaryDark">@color/primary_darktheme</item>
<item name="android:windowBackground">@color/primary_darktheme</item>
<item name="colorSecondary">@color/accent_dark</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorPrimary">@color/accent_dark</item>
<item name="colorPrimaryDark">@color/background_darktheme</item>
<item name="android:windowBackground">@color/background_darktheme</item>
<item name="tabBackground">@color/background_darktheme</item>
<item name="actionBarStyle">@style/Widget.AntennaPod.ActionBar.Dark</item>
<item name="colorControlNormal">@color/white</item>
<item name="buttonStyle">@style/Widget.AntennaPod.Button</item>
<item name="progressBarTheme">@style/ProgressBarDark</item>
<item name="drawer_activated_color">@color/highlight_dark</item>
<item name="master_switch_background">@color/master_switch_background_dark</item>
<item name="currently_playing_background">@color/highlight_dark</item>
<item name="action_icon_color">@color/white</item>
<item name="android:textAllCaps">false</item>
<item name="storage">@drawable/ic_storage_white</item>
<item name="ic_network">@drawable/ic_network_white</item>
<item name="statistics">@drawable/ic_statistics_white</item>
@ -108,7 +122,6 @@
<item name="stat_playlist">@drawable/ic_playlist_white</item>
<item name="type_video">@drawable/ic_videocam_white_24dp</item>
<item name="dragview_background">@drawable/ic_drag_darktheme</item>
<item name="drawer_activated_color">@color/highlight_dark</item>
<item name="ic_history">@drawable/ic_history_white</item>
<item name="ic_folder">@drawable/ic_folder_white</item>
<item name="ic_settings_playback">@drawable/ic_av_play_white_24dp</item>
@ -132,10 +145,6 @@
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
<item name="ic_key">@drawable/ic_key_white</item>
<item name="ic_volume_adaption">@drawable/ic_volume_adaption_white</item>
<item name="master_switch_background">@color/master_switch_background_dark</item>
<item name="currently_playing_background">@color/highlight_dark</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="action_icon_color">@color/white</item>
<item name="scrollbar_thumb">@drawable/scrollbar_thumb_dark</item>
</style>
@ -143,44 +152,31 @@
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.Dark">
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_black</item>
<style name="Theme.Base.AntennaPod.TrueBlack" parent="Theme.AntennaPod.Dark">
<item name="colorPrimaryDark">@color/black</item>
<item name="actionBarStyle">@style/Widget.AntennaPod.ActionBar.Black</item>
<item name="drawer_activated_color">@color/highlight_trueblack</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="android:color">@color/white</item>
<item name="android:colorBackground">@color/black</item>
<item name="tabBackground">@color/black</item>
<item name="android:windowBackground">@color/black</item>
<item name="android:actionBarStyle">@color/black</item>
<item name="colorPrimary">@color/black</item>
<item name="colorPrimaryDark">@color/black</item>
</style>
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light.NoTitle">
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light">
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.AntennaPod.Light">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="Theme.AntennaPod.Dark.NoTitle" parent="Theme.Base.AntennaPod.Dark.NoTitle">
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.Dark.NoTitle" parent="Theme.Base.AntennaPod.Dark">
<style name="Theme.AntennaPod.Dark.NoTitle" parent="Theme.AntennaPod.Dark">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle">
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack">
<style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.AntennaPod.TrueBlack">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
@ -208,7 +204,7 @@
<item name="android:fitsSystemWindows">true</item>
</style>
<style name="Theme.AntennaPod.TrueBlack.Translucent" parent="Theme.Base.AntennaPod.TrueBlack">
<style name="Theme.AntennaPod.TrueBlack.Translucent" parent="Theme.AntennaPod.TrueBlack">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:background">@android:color/transparent</item>
@ -224,11 +220,7 @@
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style>
<style name="Theme.AntennaPod.Splash" parent="Theme.Base.AntennaPod.Splash">
<!-- Room for API dependent attributes -->
</style>
<style name="Theme.Base.AntennaPod.Splash" parent="Theme.AppCompat.NoActionBar">
<style name="Theme.AntennaPod.Splash" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:windowBackground">@drawable/bg_splash</item>
<item name="colorPrimary">@color/ic_launcher_background</item>
<item name="colorPrimaryDark">@color/ic_launcher_background</item>
@ -271,11 +263,6 @@
<item name="android:textAllCaps">true</item>
</style>
<style name="Widget.AntennaPod.Button" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">?attr/colorAccent</item>
<item name="textAllCaps">false</item>
</style>
<style name="BigBlurryBackground">
<item name="android:scaleType">centerCrop</item>
<!-- <item name="android:tint">@color/image_readability_tint</item> -->
@ -303,4 +290,15 @@
<item name="fastScrollVerticalTrackDrawable">@drawable/scrollbar_track</item>
</style>
<style name="Widget.AntennaPod.ActionBar.Light" parent="Widget.MaterialComponents.Light.ActionBar.Solid">
<item name="background">@color/background_light</item>
</style>
<style name="Widget.AntennaPod.ActionBar.Dark" parent="Widget.MaterialComponents.Light.ActionBar.Solid">
<item name="background">@color/background_darktheme</item>
</style>
<style name="Widget.AntennaPod.ActionBar.Black" parent="Widget.MaterialComponents.Light.ActionBar.Solid">
<item name="background">@color/black</item>
</style>
</resources>

View File

@ -100,8 +100,8 @@ public class CastUtils {
metadata.putString(MediaMetadata.KEY_SUBTITLE, subtitle);
}
if (!TextUtils.isEmpty(feedItem.getImageUrl())) {
metadata.addImage(new WebImage(Uri.parse(feedItem.getImageUrl())));
if (!TextUtils.isEmpty(feedItem.getImageLocation())) {
metadata.addImage(new WebImage(Uri.parse(feedItem.getImageLocation())));
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(media.getItem().getPubDate());