Merge pull request #1826 from TomHennen/subscriptions_view

Subscriptions view
This commit is contained in:
Tom Hennen 2016-03-27 17:38:50 -04:00
commit 365c1082b3
34 changed files with 523 additions and 8 deletions

View File

@ -9,6 +9,7 @@ repositories {
}
dependencies {
compile project(":core")
compile "com.android.support:support-v4:$supportVersion"
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:design:$supportVersion"
@ -19,7 +20,6 @@ dependencies {
compile("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") {
exclude group: "org.json", module: "json"
}
compile "commons-io:commons-io:$commonsioVersion"
compile "org.jsoup:jsoup:$jsoupVersion"
compile "com.github.bumptech.glide:glide:$glideVersion"
@ -41,22 +41,22 @@ dependencies {
exclude module: "support-v4"
}
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
compile 'com.github.shts:TriangleLabelView:1.0.0'
compile project(":core")
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
}
def getMyVersionName() {
def parsedManifestXml = (new XmlSlurper())
.parse("${projectDir}/src/main/AndroidManifest.xml")
.declareNamespace(android:"http://schemas.android.com/apk/res/android")
.declareNamespace(android: "http://schemas.android.com/apk/res/android")
return parsedManifestXml."@android:versionName"
}
def getMyVersionCode() {
def parsedManifestXml = (new XmlSlurper())
.parse("${projectDir}/src/main/AndroidManifest.xml")
.declareNamespace(android:"http://schemas.android.com/apk/res/android")
.declareNamespace(android: "http://schemas.android.com/apk/res/android")
return parsedManifestXml."@android:versionCode".toInteger()
}
@ -150,7 +150,7 @@ task filterAbout {
from "src/main/templates/about.html"
into "src/main/assets"
filter(ReplaceTokens, tokens: [versionname: android.defaultConfig.versionName,
commit: "git rev-parse --short HEAD".execute().text])
commit : "git rev-parse --short HEAD".execute().text])
}
}

View File

@ -110,6 +110,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
solo.waitForView(android.R.id.list);
assertEquals(solo.getString(R.string.episodes_label), getActionbarTitle());
// Subscriptions
openNavDrawer();
solo.clickOnText(solo.getString(R.string.subscriptions_label));
solo.waitForView(R.id.subscriptions_grid);
assertEquals(solo.getString(R.string.subscriptions_label), getActionbarTitle());
// downloads
openNavDrawer();
solo.clickOnText(solo.getString(R.string.downloads_label));

View File

@ -0,0 +1,13 @@
Copyright (C) 2016 Shota Saito
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -55,6 +55,7 @@ import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.ItemDescriptionFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
import rx.Observable;
@ -79,6 +80,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
public static final String[] NAV_DRAWER_TAGS = {
QueueFragment.TAG,
EpisodesFragment.TAG,
SubscriptionFragment.TAG,
DownloadsFragment.TAG,
PlaybackHistoryFragment.TAG,
AddFeedFragment.TAG

View File

@ -58,6 +58,7 @@ import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
import de.danoeh.antennapod.fragment.ItemlistFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
import de.greenrobot.event.EventBus;
@ -92,6 +93,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
public static final String[] NAV_DRAWER_TAGS = {
QueueFragment.TAG,
EpisodesFragment.TAG,
SubscriptionFragment.TAG,
DownloadsFragment.TAG,
PlaybackHistoryFragment.TAG,
AddFeedFragment.TAG
@ -269,7 +271,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
}
public void loadFragment(int index, Bundle args) {
Log.d(TAG, "loadFragment(index: " + index + ", args: " + args +")");
Log.d(TAG, "loadFragment(index: " + index + ", args: " + args + ")");
if (index < navAdapter.getSubscriptionOffset()) {
String tag = navAdapter.getTags().get(index);
loadFragment(tag, args);
@ -298,6 +300,11 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
case AddFeedFragment.TAG:
fragment = new AddFeedFragment();
break;
case SubscriptionFragment.TAG:
SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
subscriptionFragment.setItemAccess(itemAccess);
fragment = subscriptionFragment;
break;
default:
// default to the queue
tag = QueueFragment.TAG;
@ -646,6 +653,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
public int getFeedCounter(long feedId) {
return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
}
};
private void loadData() {

View File

@ -19,6 +19,7 @@ import com.bumptech.glide.Glide;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconTextView;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import org.apache.commons.lang3.ArrayUtils;
import java.util.ArrayList;
@ -108,6 +109,9 @@ public class NavListAdapter extends BaseAdapter
case PlaybackHistoryFragment.TAG:
icon = R.attr.ic_history;
break;
case SubscriptionFragment.TAG:
icon = R.attr.ic_folder;
break;
case AddFeedFragment.TAG:
icon = R.attr.content_new;
break;
@ -127,7 +131,11 @@ public class NavListAdapter extends BaseAdapter
@Override
public int getCount() {
return getSubscriptionOffset() + itemAccess.getCount();
int baseCount = getSubscriptionOffset();
if (UserPreferences.showSubscriptionsInDrawer()) {
baseCount += itemAccess.getCount();
}
return baseCount;
}
@Override

View File

@ -0,0 +1,153 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import java.lang.ref.WeakReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.ItemlistFragment;
import jp.shts.android.library.TriangleLabelView;
/**
* Adapter for subscriptions
*/
public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
/** placeholder object that indicates item should be added */
public static final Object ADD_ITEM_OBJ = new Object();
/** the position in the view that holds the add item */
private static final int ADD_POSITION = 0;
private NavListAdapter.ItemAccess itemAccess;
private final WeakReference<MainActivity> mainActivityRef;
public SubscriptionsAdapter(MainActivity mainActivity, NavListAdapter.ItemAccess itemAccess) {
this.itemAccess = itemAccess;
this.mainActivityRef = new WeakReference<>(mainActivity);
}
public void setItemAccess(NavListAdapter.ItemAccess itemAccess) {
this.itemAccess = itemAccess;
}
private int getAdjustedPosition(int origPosition) {
return origPosition - 1;
}
@Override
public int getCount() {
return 1 + itemAccess.getCount();
}
@Override
public Object getItem(int position) {
if (position == ADD_POSITION) {
return ADD_ITEM_OBJ;
}
return itemAccess.getItem(getAdjustedPosition(position));
}
@Override
public long getItemId(int position) {
if (position == ADD_POSITION) {
return 0;
}
return itemAccess.getItem(getAdjustedPosition(position)).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
holder = new Holder();
LayoutInflater layoutInflater =
(LayoutInflater) mainActivityRef.get().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.subscription_item, parent, false);
holder.feedTitle = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvCover);
holder.count = (TriangleLabelView) convertView.findViewById(R.id.triangleCountView);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
if (position == ADD_POSITION) {
holder.feedTitle.setText(R.string.add_feed_label);
holder.count.setVisibility(View.INVISIBLE);
Glide.with(mainActivityRef.get())
.load(R.drawable.ic_add_grey_600_48dp)
.dontAnimate()
.into(holder.imageView);
return convertView;
}
final Feed feed = (Feed) getItem(position);
if (feed == null) return null;
holder.feedTitle.setText(feed.getTitle());
holder.count.setVisibility(View.VISIBLE);
holder.count.setPrimaryText(String.valueOf(itemAccess.getFeedCounter(feed.getId())));
Glide.with(mainActivityRef.get())
.load(feed.getImageUri())
.placeholder(R.color.light_gray)
.error(R.color.light_gray)
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.fitCenter()
.dontAnimate()
.listener(new RequestListener<Uri, GlideDrawable>() {
@Override
public boolean onException(Exception e, Uri model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, Uri model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
holder.feedTitle.setVisibility(View.INVISIBLE);
return false;
}
})
.into(holder.imageView);
return convertView;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == ADD_POSITION) {
mainActivityRef.get().loadChildFragment(new AddFeedFragment());
} else {
Fragment fragment = ItemlistFragment.newInstance(getItemId(position));
mainActivityRef.get().loadChildFragment(fragment);
}
}
static class Holder {
public TextView feedTitle;
public ImageView imageView;
public TriangleLabelView count;
}
}

View File

@ -0,0 +1,205 @@
package de.danoeh.antennapod.fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import java.util.ArrayList;
import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.NavListAdapter;
import de.danoeh.antennapod.adapter.SubscriptionsAdapter;
import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
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.core.util.FeedItemUtil;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Fragment for displaying feed subscriptions
*/
public class SubscriptionFragment extends Fragment {
public static final String TAG = "SubscriptionFragment";
private GridView mSubscriptionGridLayout;
private DBReader.NavDrawerData mDrawerData;
private SubscriptionsAdapter mSubscriptionAdapter;
private NavListAdapter.ItemAccess mItemAccess;
private List<Feed> mSubscriptionList = new ArrayList<>();
private int mPosition = -1;
public SubscriptionFragment() {
}
public void setItemAccess(NavListAdapter.ItemAccess itemAccess) {
mItemAccess = itemAccess;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_subscriptions, container, false);
mSubscriptionGridLayout = (GridView) root.findViewById(R.id.subscriptions_grid);
registerForContextMenu(mSubscriptionGridLayout);
return root;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mSubscriptionAdapter = new SubscriptionsAdapter((MainActivity)getActivity(), mItemAccess);
mSubscriptionGridLayout.setAdapter(mSubscriptionAdapter);
loadSubscriptions();
mSubscriptionGridLayout.setOnItemClickListener(mSubscriptionAdapter);
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.subscriptions_label);
}
}
private void loadSubscriptions() {
Observable.fromCallable(() -> DBReader.getNavDrawerData())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
mDrawerData = result;
mSubscriptionList = mDrawerData.feeds;
mSubscriptionAdapter.setItemAccess(mItemAccess);
mSubscriptionAdapter.notifyDataSetChanged();
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
int position = adapterInfo.position;
Object selectedObject = mSubscriptionAdapter.getItem(position);
if (selectedObject.equals(SubscriptionsAdapter.ADD_ITEM_OBJ)) {
mPosition = position;
return;
}
Feed feed = (Feed)selectedObject;
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.nav_feed_context, menu);
menu.setHeaderTitle(feed.getTitle());
mPosition = position;
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final int position = mPosition;
mPosition = -1; // reset
if(position < 0) {
return false;
}
Object selectedObject = mSubscriptionAdapter.getItem(position);
if (selectedObject.equals(SubscriptionsAdapter.ADD_ITEM_OBJ)) {
// this is the add object, do nothing
return false;
}
Feed feed = (Feed)selectedObject;
switch(item.getItemId()) {
case R.id.mark_all_seen_item:
Observable.fromCallable(() -> DBWriter.markFeedSeen(feed.getId()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
loadSubscriptions();
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
});
return true;
case R.id.mark_all_read_item:
Observable.fromCallable(() -> DBWriter.markFeedRead(feed.getId()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
loadSubscriptions();
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
});
return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(getContext(), feed) {
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
loadSubscriptions();
}
};
ConfirmationDialog conDialog = new ConfirmationDialog(getContext(),
R.string.remove_feed_label,
R.string.feed_delete_confirmation_msg) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
dialog.dismiss();
long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
if (mediaId > 0 &&
FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
remover.skipOnCompletion = true;
int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
getActivity().sendBroadcast(new Intent(
PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
}
}
remover.executeAsync();
}
};
conDialog.createNewDialog().show();
return true;
default:
return super.onContextItemSelected(item);
}
}
@Override
public void onResume() {
super.onResume();
}
}

View File

@ -0,0 +1,32 @@
package de.danoeh.antennapod.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* From http://stackoverflow.com/a/19449488/6839
*/
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/subscriptions_grid"
android:layout_width="match_parent"
android:numColumns="3"
android:horizontalSpacing="2dp"
android:verticalSpacing="2dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal">
</GridView>
</LinearLayout>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<de.danoeh.antennapod.view.SquareImageView
android:id="@+id/imgvCover"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="centerCrop"
tools:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/txtvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="@dimen/widget_margin"
android:ellipsize="end"
android:padding="@dimen/widget_margin"
style="@style/AntennaPod.TextView.Heading"
android:textSize="15sp"
android:textStyle="bold"
android:layout_gravity="bottom"
android:textColor="@android:color/white"
android:background="#55000000"
tools:text="@string/app_name" />
<jp.shts.android.library.TriangleLabelView
android:id="@+id/triangleCountView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
app:backgroundColor="#bbbfbfbf"
app:corner="rightTop"
app:primaryText="Test"
app:primaryTextColor="@color/grey600"
app:primaryTextSize="12sp"
android:layout_gravity="right|top"/>
</FrameLayout>

View File

@ -36,6 +36,12 @@
android:summary="@string/pref_nav_drawer_feed_counter_sum"
android:defaultValue="0"
app:useStockLayout="true"/>
<de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="true"
android:enabled="true"
android:key="prefShowSubscriptionsInDrawer"
android:summary="@string/pref_show_subscriptions_in_drawer_sum"
android:title="@string/pref_show_subscriptions_in_drawer_title"/>
</PreferenceScreen>
<de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="false"

View File

@ -100,6 +100,9 @@ licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a
<h2>StackBlur <a href="https://github.com/kikoso/android-stackblur">(Link)</a></h2>
by Enrique L&oacute;pez Ma&ntilde;as, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a>
<h2>Triangle Label View <a href="https://github.com/shts/TriangleLabelView">(Link)</a></h2>
by Shota Saito, licensed under the Apache 2.0 license <a href="LICENSE_TRIANGLE_LABEL_VIEW.txt">(View)</a>
<h2>AntennaPod-AudioPlayer <a href="https://github.com/AntennaPod/AntennaPod-AudioPlayer/">(Link)</a></h2>
by the AntennaPod team, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a>

View File

@ -54,6 +54,8 @@ public class UserPreferences {
public static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify";
public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground";
public static final String PREF_SHOW_DOWNLOAD_REPORT = "prefShowDownloadReport";
public static final String PREF_SHOW_SUBSCRIPTIONS_IN_DRAWER = "prefShowSubscriptionsInDrawer";
// Queue
public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront";
@ -174,6 +176,10 @@ public class UserPreferences {
return Integer.parseInt(value);
}
public static boolean showSubscriptionsInDrawer() {
return prefs.getBoolean(PREF_SHOW_SUBSCRIPTIONS_IN_DRAWER, true);
}
/**
* Returns notification priority.
*

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

View File

@ -146,6 +146,7 @@
<string-array name="nav_drawer_titles">
<item>@string/queue_label</item>
<item>@string/episodes_label</item>
<item>@string/subscriptions_label</item>
<item>@string/downloads_label</item>
<item>@string/playback_history_label</item>
<item>@string/add_feed_label</item>

View File

@ -21,6 +21,7 @@
<attr name="navigation_up" format="reference"/>
<attr name="social_share" format="reference"/>
<attr name="stat_playlist" format="reference"/>
<attr name="ic_folder" format="reference"/>
<attr name="type_audio" format="reference"/>
<attr name="type_video" format="reference"/>
<attr name="borderless_button" format="reference"/>

View File

@ -30,6 +30,7 @@
<dimen name="listitem_threeline_horizontalpadding">16dp</dimen>
<dimen name="list_vertical_padding">8dp</dimen>
<dimen name="minimum_text_margin">8dp</dimen>
<dimen name="listitem_icon_leftpadding">16dp</dimen>
<dimen name="listitem_icon_rightpadding">16dp</dimen>

View File

@ -22,6 +22,7 @@
<string name="downloads_running_label">Running</string>
<string name="downloads_completed_label">Completed</string>
<string name="downloads_log_label">Log</string>
<string name="subscriptions_label">Subscriptions</string>
<string name="cancel_download_label">Cancel\nDownload</string>
<string name="playback_history_label">Playback History</string>
<string name="gpodnet_main_label">gpodder.net</string>
@ -383,6 +384,8 @@
<string name="pref_expandNotify_sum">Always expand the notification to show playback buttons.</string>
<string name="pref_persistNotify_title">Persistent Playback Controls</string>
<string name="pref_persistNotify_sum">Keep notification and lockscreen controls when playback is paused.</string>
<string name="pref_show_subscriptions_in_drawer_title">Show Subscriptions</string>
<string name="pref_show_subscriptions_in_drawer_sum">Show subscription list directly in navigation drawer</string>
<string name="pref_lockscreen_background_title">Set Lockscreen Background</string>
<string name="pref_lockscreen_background_sum">Set the lockscreen background to the current episode\'s image. As a side effect, this will also show the image in third party apps.</string>
<string name="pref_showDownloadReport_title">Show Download Report</string>

View File

@ -37,6 +37,7 @@
<item name="attr/nav_drawer_background">@color/white</item>
<item name="attr/ic_new">@drawable/ic_new_releases_grey600_24dp</item>
<item name="attr/ic_history">@drawable/ic_history_grey600_24dp</item>
<item name="attr/ic_folder">@drawable/ic_folder_grey600_24dp</item>
<item name="attr/av_play_big">@drawable/ic_play_arrow_grey600_36dp</item>
<item name="attr/av_pause_big">@drawable/ic_pause_grey600_36dp</item>
<item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item>
@ -94,6 +95,7 @@
<item name="attr/nav_drawer_background">#3B3B3B</item>
<item name="attr/ic_new">@drawable/ic_new_releases_white_24dp</item>
<item name="attr/ic_history">@drawable/ic_history_white_24dp</item>
<item name="attr/ic_folder">@drawable/ic_folder_white_24dp</item>
<item name="attr/av_play_big">@drawable/ic_play_arrow_white_36dp</item>
<item name="attr/av_pause_big">@drawable/ic_pause_white_36dp</item>
<item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item>
@ -152,6 +154,7 @@
<item name="attr/nav_drawer_background">@color/white</item>
<item name="attr/ic_new">@drawable/ic_new_releases_grey600_24dp</item>
<item name="attr/ic_history">@drawable/ic_history_grey600_24dp</item>
<item name="attr/ic_folder">@drawable/ic_folder_grey600_24dp</item>
<item name="attr/av_play_big">@drawable/ic_play_arrow_grey600_36dp</item>
<item name="attr/av_pause_big">@drawable/ic_pause_grey600_36dp</item>
<item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item>
@ -210,6 +213,7 @@
<item name="attr/nav_drawer_background">#3B3B3B</item>
<item name="attr/ic_new">@drawable/ic_new_releases_white_24dp</item>
<item name="attr/ic_history">@drawable/ic_history_white_24dp</item>
<item name="attr/ic_folder">@drawable/ic_folder_white_24dp</item>
<item name="attr/av_play_big">@drawable/ic_play_arrow_white_36dp</item>
<item name="attr/av_pause_big">@drawable/ic_pause_white_36dp</item>
<item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item>