Restructure Echo to be more flexible (#7035)
Each screen is its own file, which makes it easier to add interactive elements.
This commit is contained in:
parent
1dbda2fb8a
commit
13a985ca1e
|
@ -19,6 +19,7 @@ import androidx.core.content.ContextCompat;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentContainerView;
|
||||
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
@ -37,7 +38,6 @@ import de.danoeh.antennapod.event.FeedListUpdateEvent;
|
|||
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
|
||||
import de.danoeh.antennapod.fragment.SearchFragment;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.echo.EchoActivity;
|
||||
import de.danoeh.antennapod.ui.home.sections.AllowNotificationsSection;
|
||||
import de.danoeh.antennapod.ui.home.sections.DownloadsSection;
|
||||
import de.danoeh.antennapod.ui.home.sections.EchoSection;
|
||||
|
@ -98,10 +98,10 @@ public class HomeFragment extends Fragment implements Toolbar.OnMenuItemClickLis
|
|||
addSection(new AllowNotificationsSection());
|
||||
}
|
||||
}
|
||||
if (Calendar.getInstance().get(Calendar.YEAR) == EchoActivity.RELEASE_YEAR
|
||||
if (Calendar.getInstance().get(Calendar.YEAR) == EchoConfig.RELEASE_YEAR
|
||||
&& Calendar.getInstance().get(Calendar.MONTH) == Calendar.DECEMBER
|
||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) >= 10
|
||||
&& prefs.getInt(PREF_HIDE_ECHO, 0) != EchoActivity.RELEASE_YEAR) {
|
||||
&& prefs.getInt(PREF_HIDE_ECHO, 0) != EchoConfig.RELEASE_YEAR) {
|
||||
addSection(new EchoSection());
|
||||
}
|
||||
|
||||
|
|
|
@ -11,18 +11,17 @@ import androidx.annotation.Nullable;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.databinding.HomeSectionEchoBinding;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.database.StatisticsItem;
|
||||
import de.danoeh.antennapod.databinding.HomeSectionEchoBinding;
|
||||
import de.danoeh.antennapod.ui.echo.EchoActivity;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.home.HomeFragment;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class EchoSection extends Fragment {
|
||||
private HomeSectionEchoBinding viewBinding;
|
||||
private Disposable disposable;
|
||||
|
@ -32,32 +31,21 @@ public class EchoSection extends Fragment {
|
|||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
viewBinding = HomeSectionEchoBinding.inflate(inflater);
|
||||
viewBinding.titleLabel.setText(getString(R.string.antennapod_echo_year, EchoActivity.RELEASE_YEAR));
|
||||
viewBinding.titleLabel.setText(getString(R.string.antennapod_echo_year, EchoConfig.RELEASE_YEAR));
|
||||
viewBinding.echoButton.setOnClickListener(v -> startActivity(new Intent(getContext(), EchoActivity.class)));
|
||||
viewBinding.closeButton.setOnClickListener(v -> hideThisYear());
|
||||
updateVisibility();
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
private long jan1() {
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.set(Calendar.HOUR_OF_DAY, 0);
|
||||
date.set(Calendar.MINUTE, 0);
|
||||
date.set(Calendar.SECOND, 0);
|
||||
date.set(Calendar.MILLISECOND, 0);
|
||||
date.set(Calendar.DAY_OF_MONTH, 1);
|
||||
date.set(Calendar.MONTH, 0);
|
||||
date.set(Calendar.YEAR, EchoActivity.RELEASE_YEAR);
|
||||
return date.getTimeInMillis();
|
||||
}
|
||||
|
||||
private void updateVisibility() {
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposable = Observable.fromCallable(
|
||||
() -> {
|
||||
DBReader.StatisticsResult statisticsResult = DBReader.getStatistics(false, jan1(), Long.MAX_VALUE);
|
||||
DBReader.StatisticsResult statisticsResult = DBReader.getStatistics(
|
||||
false, EchoConfig.jan1(), Long.MAX_VALUE);
|
||||
long totalTime = 0;
|
||||
for (StatisticsItem feedTime : statisticsResult.feedTime) {
|
||||
totalTime += feedTime.timePlayed;
|
||||
|
@ -77,7 +65,7 @@ public class EchoSection extends Fragment {
|
|||
|
||||
void hideThisYear() {
|
||||
getContext().getSharedPreferences(HomeFragment.PREF_NAME, Context.MODE_PRIVATE)
|
||||
.edit().putInt(HomeFragment.PREF_HIDE_ECHO, EchoActivity.RELEASE_YEAR).apply();
|
||||
.edit().putInt(HomeFragment.PREF_HIDE_ECHO, EchoConfig.RELEASE_YEAR).apply();
|
||||
((MainActivity) getActivity()).loadFragment(HomeFragment.TAG, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="ICAST_IDIV_CAST_TO_DOUBLE"/>
|
||||
<Class name="de.danoeh.antennapod.ui.echo.screens.RotatingSquaresScreen"/>
|
||||
<Class name="de.danoeh.antennapod.ui.echo.background.RotatingSquaresBackground"/>
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="MS_CANNOT_BE_FINAL"/>
|
||||
|
|
|
@ -1,97 +1,60 @@
|
|||
package de.danoeh.antennapod.ui.echo;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ShareCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.database.StatisticsItem;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.common.Converter;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.EchoActivityBinding;
|
||||
import de.danoeh.antennapod.ui.echo.screens.BubbleScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screens.FinalShareScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screens.RotatingSquaresScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screens.StripesScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screens.WaveformScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screens.WavesScreen;
|
||||
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
|
||||
import de.danoeh.antennapod.ui.echo.screen.EchoScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.FinalShareScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.HoarderScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.HoursPlayedScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.IntroScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.QueueScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.ThanksScreen;
|
||||
import de.danoeh.antennapod.ui.echo.screen.TimeReleasePlayScreen;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class EchoActivity extends AppCompatActivity {
|
||||
public static final int RELEASE_YEAR = 2023;
|
||||
private static final String TAG = "EchoActivity";
|
||||
private static final int NUM_SCREENS = 7;
|
||||
private static final int SHARE_SIZE = 1000;
|
||||
|
||||
private EchoActivityBinding viewBinding;
|
||||
private int currentScreen = -1;
|
||||
private int currentScreenIdx = -1;
|
||||
private boolean progressPaused = false;
|
||||
private float progress = 0;
|
||||
private Drawable currentDrawable;
|
||||
private EchoProgress echoProgress;
|
||||
private Disposable redrawTimer;
|
||||
private long timeTouchDown;
|
||||
private long timeLastFrame;
|
||||
private Disposable disposable;
|
||||
private Disposable disposableFavorite;
|
||||
|
||||
private long totalTime = 0;
|
||||
private int totalActivePodcasts = 0;
|
||||
private int playedPodcasts = 0;
|
||||
private int playedActivePodcasts = 0;
|
||||
private String randomUnplayedActivePodcast = "";
|
||||
private int queueNumEpisodes = 0;
|
||||
private long queueSecondsLeft = 0;
|
||||
private long timeBetweenReleaseAndPlay = 0;
|
||||
private long oldestDate = 0;
|
||||
private final ArrayList<String> favoritePodNames = new ArrayList<>();
|
||||
private final ArrayList<Drawable> favoritePodImages = new ArrayList<>();
|
||||
private List<EchoScreen> screens;
|
||||
private EchoScreen currentScreen;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
super.onCreate(savedInstanceState);
|
||||
screens = List.of(new IntroScreen(this, getLayoutInflater()),
|
||||
new HoursPlayedScreen(this, getLayoutInflater()), new QueueScreen(this, getLayoutInflater()),
|
||||
new TimeReleasePlayScreen(this, getLayoutInflater()), new HoarderScreen(this, getLayoutInflater()),
|
||||
new ThanksScreen(this, getLayoutInflater()), new FinalShareScreen(this, getLayoutInflater()));
|
||||
viewBinding = EchoActivityBinding.inflate(getLayoutInflater());
|
||||
viewBinding.closeButton.setOnClickListener(v -> finish());
|
||||
viewBinding.shareButton.setOnClickListener(v -> share());
|
||||
viewBinding.echoImage.setOnTouchListener((v, event) -> {
|
||||
viewBinding.screenContainer.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
progressPaused = true;
|
||||
timeTouchDown = System.currentTimeMillis();
|
||||
|
@ -99,11 +62,11 @@ public class EchoActivity extends AppCompatActivity {
|
|||
progressPaused = false;
|
||||
if (timeTouchDown + 500 > System.currentTimeMillis()) {
|
||||
int newScreen;
|
||||
if (event.getX() < 0.5f * viewBinding.echoImage.getMeasuredWidth()) {
|
||||
newScreen = Math.max(currentScreen - 1, 0);
|
||||
if (event.getX() < 0.5f * viewBinding.screenContainer.getMeasuredWidth()) {
|
||||
newScreen = Math.max(currentScreenIdx - 1, 0);
|
||||
} else {
|
||||
newScreen = Math.min(currentScreen + 1, NUM_SCREENS - 1);
|
||||
if (currentScreen == NUM_SCREENS - 1) {
|
||||
newScreen = Math.min(currentScreenIdx + 1, NUM_SCREENS - 1);
|
||||
if (currentScreenIdx == NUM_SCREENS - 1) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
@ -121,35 +84,9 @@ public class EchoActivity extends AppCompatActivity {
|
|||
loadStatistics();
|
||||
}
|
||||
|
||||
private void share() {
|
||||
try {
|
||||
Bitmap bitmap = Bitmap.createBitmap(SHARE_SIZE, SHARE_SIZE, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
currentDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
currentDrawable.draw(canvas);
|
||||
viewBinding.echoImage.setImageDrawable(null);
|
||||
viewBinding.echoImage.setImageDrawable(currentDrawable);
|
||||
File file = new File(UserPreferences.getDataFolder(null), "AntennaPodEcho.png");
|
||||
FileOutputStream stream = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
|
||||
stream.close();
|
||||
|
||||
Uri fileUri = FileProvider.getUriForFile(this, getString(R.string.provider_authority), file);
|
||||
new ShareCompat.IntentBuilder(this)
|
||||
.setType("image/png")
|
||||
.addStream(fileUri)
|
||||
.setText(getString(R.string.echo_share, RELEASE_YEAR))
|
||||
.setChooserTitle(R.string.share_file_label)
|
||||
.startChooser();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
redrawTimer = Flowable.timer(20, TimeUnit.MILLISECONDS)
|
||||
.observeOn(Schedulers.io())
|
||||
.repeat()
|
||||
|
@ -157,7 +94,7 @@ public class EchoActivity extends AppCompatActivity {
|
|||
if (progressPaused) {
|
||||
return;
|
||||
}
|
||||
viewBinding.echoImage.postInvalidate();
|
||||
currentScreen.postInvalidate();
|
||||
if (progress >= NUM_SCREENS - 0.001f) {
|
||||
return;
|
||||
}
|
||||
|
@ -180,254 +117,38 @@ public class EchoActivity extends AppCompatActivity {
|
|||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
if (disposableFavorite != null) {
|
||||
disposableFavorite.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadScreen(int screen, boolean force) {
|
||||
if (screen == currentScreen && !force) {
|
||||
if (screen == currentScreenIdx && !force) {
|
||||
return;
|
||||
}
|
||||
currentScreen = screen;
|
||||
currentScreenIdx = screen;
|
||||
currentScreen = screens.get(currentScreenIdx);
|
||||
runOnUiThread(() -> {
|
||||
viewBinding.echoLogo.setVisibility(currentScreen == 0 ? View.VISIBLE : View.GONE);
|
||||
viewBinding.shareButton.setVisibility(currentScreen == 6 ? View.VISIBLE : View.GONE);
|
||||
|
||||
switch (currentScreen) {
|
||||
case 0:
|
||||
viewBinding.aboveLabel.setText(R.string.echo_intro_your_year);
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", RELEASE_YEAR));
|
||||
viewBinding.belowLabel.setText(R.string.echo_intro_in_podcasts);
|
||||
viewBinding.smallLabel.setText(R.string.echo_intro_locally);
|
||||
currentDrawable = new BubbleScreen(this);
|
||||
break;
|
||||
case 1:
|
||||
viewBinding.aboveLabel.setText(R.string.echo_hours_this_year);
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", totalTime / 3600));
|
||||
viewBinding.belowLabel.setText(getResources()
|
||||
.getQuantityString(R.plurals.echo_hours_podcasts, playedPodcasts, playedPodcasts));
|
||||
viewBinding.smallLabel.setText("");
|
||||
currentDrawable = new WaveformScreen(this);
|
||||
break;
|
||||
case 2:
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", queueSecondsLeft / 3600));
|
||||
viewBinding.belowLabel.setText(getResources().getQuantityString(
|
||||
R.plurals.echo_queue_hours_waiting, queueNumEpisodes, queueNumEpisodes));
|
||||
Calendar dec31 = Calendar.getInstance();
|
||||
dec31.set(Calendar.DAY_OF_MONTH, 31);
|
||||
dec31.set(Calendar.MONTH, Calendar.DECEMBER);
|
||||
int daysUntilNextYear = Math.max(1,
|
||||
dec31.get(Calendar.DAY_OF_YEAR) - Calendar.getInstance().get(Calendar.DAY_OF_YEAR) + 1);
|
||||
long secondsPerDay = queueSecondsLeft / daysUntilNextYear;
|
||||
String timePerDay = Converter.getDurationStringLocalized(
|
||||
getLocalizedResources(this, getEchoLanguage()), secondsPerDay * 1000, true);
|
||||
double hoursPerDay = secondsPerDay / 3600.0;
|
||||
int nextYear = RELEASE_YEAR + 1;
|
||||
if (hoursPerDay < 1.5) {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_clean);
|
||||
viewBinding.smallLabel.setText(
|
||||
getString(R.string.echo_queue_hours_clean, timePerDay, nextYear));
|
||||
} else if (hoursPerDay <= 24) {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_many);
|
||||
viewBinding.smallLabel.setText(
|
||||
getString(R.string.echo_queue_hours_normal, timePerDay, nextYear));
|
||||
} else {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_many);
|
||||
viewBinding.smallLabel.setText(getString(R.string.echo_queue_hours_much, timePerDay, nextYear));
|
||||
}
|
||||
currentDrawable = new StripesScreen(this);
|
||||
break;
|
||||
case 3:
|
||||
viewBinding.aboveLabel.setText(R.string.echo_listened_after_title);
|
||||
if (timeBetweenReleaseAndPlay <= 1000L * 3600 * 24 * 2.5) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_listened_after_emoji_run);
|
||||
viewBinding.belowLabel.setText(R.string.echo_listened_after_comment_addict);
|
||||
} else {
|
||||
viewBinding.largeLabel.setText(R.string.echo_listened_after_emoji_yoga);
|
||||
viewBinding.belowLabel.setText(R.string.echo_listened_after_comment_easy);
|
||||
}
|
||||
viewBinding.smallLabel.setText(getString(R.string.echo_listened_after_time,
|
||||
Converter.getDurationStringLocalized(
|
||||
getLocalizedResources(this, getEchoLanguage()), timeBetweenReleaseAndPlay, true)));
|
||||
currentDrawable = new RotatingSquaresScreen(this);
|
||||
break;
|
||||
case 4:
|
||||
viewBinding.aboveLabel.setText(R.string.echo_hoarder_title);
|
||||
int percentagePlayed = (int) (100.0 * playedActivePodcasts / totalActivePodcasts);
|
||||
if (percentagePlayed < 25) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_cabinet);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_hoarder);
|
||||
viewBinding.smallLabel.setText(getString(R.string.echo_hoarder_comment_hoarder,
|
||||
percentagePlayed, totalActivePodcasts));
|
||||
} else if (percentagePlayed < 75) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_check);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_medium);
|
||||
viewBinding.smallLabel.setText(getString(R.string.echo_hoarder_comment_medium,
|
||||
percentagePlayed, totalActivePodcasts, randomUnplayedActivePodcast));
|
||||
} else {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_clean);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_clean);
|
||||
viewBinding.smallLabel.setText(getString(R.string.echo_hoarder_comment_clean,
|
||||
percentagePlayed, totalActivePodcasts));
|
||||
}
|
||||
currentDrawable = new WavesScreen(this);
|
||||
break;
|
||||
case 5:
|
||||
viewBinding.aboveLabel.setText("");
|
||||
viewBinding.largeLabel.setText(R.string.echo_thanks_large);
|
||||
if (oldestDate < jan1()) {
|
||||
String skeleton = DateFormat.getBestDateTimePattern(getEchoLanguage(), "MMMM yyyy");
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(skeleton, getEchoLanguage());
|
||||
String dateFrom = dateFormat.format(new Date(oldestDate));
|
||||
viewBinding.belowLabel.setText(getString(R.string.echo_thanks_we_are_glad_old, dateFrom));
|
||||
} else {
|
||||
viewBinding.belowLabel.setText(R.string.echo_thanks_we_are_glad_new);
|
||||
}
|
||||
viewBinding.smallLabel.setText(R.string.echo_thanks_now_favorite);
|
||||
currentDrawable = new RotatingSquaresScreen(this);
|
||||
break;
|
||||
case 6:
|
||||
viewBinding.aboveLabel.setText("");
|
||||
viewBinding.largeLabel.setText("");
|
||||
viewBinding.belowLabel.setText("");
|
||||
viewBinding.smallLabel.setText("");
|
||||
currentDrawable = new FinalShareScreen(this, favoritePodNames, favoritePodImages);
|
||||
break;
|
||||
default: // Keep
|
||||
}
|
||||
viewBinding.echoImage.setImageDrawable(currentDrawable);
|
||||
viewBinding.screenContainer.removeAllViews();
|
||||
viewBinding.screenContainer.addView(currentScreen.getView());
|
||||
});
|
||||
}
|
||||
|
||||
private Locale getEchoLanguage() {
|
||||
boolean hasTranslation = !getString(R.string.echo_listened_after_title)
|
||||
.equals(getLocalizedResources(this, Locale.US).getString(R.string.echo_listened_after_title));
|
||||
if (hasTranslation) {
|
||||
return Locale.getDefault();
|
||||
} else {
|
||||
return Locale.US;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Resources getLocalizedResources(Context context, Locale desiredLocale) {
|
||||
Configuration conf = context.getResources().getConfiguration();
|
||||
conf = new Configuration(conf);
|
||||
conf.setLocale(desiredLocale);
|
||||
Context localizedContext = context.createConfigurationContext(conf);
|
||||
return localizedContext.getResources();
|
||||
}
|
||||
|
||||
private long jan1() {
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.set(Calendar.HOUR_OF_DAY, 0);
|
||||
date.set(Calendar.MINUTE, 0);
|
||||
date.set(Calendar.SECOND, 0);
|
||||
date.set(Calendar.MILLISECOND, 0);
|
||||
date.set(Calendar.DAY_OF_MONTH, 1);
|
||||
date.set(Calendar.MONTH, 0);
|
||||
date.set(Calendar.YEAR, RELEASE_YEAR);
|
||||
return date.getTimeInMillis();
|
||||
}
|
||||
|
||||
private void loadStatistics() {
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
long timeFilterFrom = jan1();
|
||||
long timeFilterTo = Long.MAX_VALUE;
|
||||
disposable = Observable.fromCallable(
|
||||
() -> {
|
||||
DBReader.StatisticsResult statisticsData = DBReader.getStatistics(
|
||||
false, timeFilterFrom, timeFilterTo);
|
||||
false, EchoConfig.jan1(), Long.MAX_VALUE);
|
||||
Collections.sort(statisticsData.feedTime, (item1, item2) ->
|
||||
Long.compare(item2.timePlayed, item1.timePlayed));
|
||||
|
||||
favoritePodNames.clear();
|
||||
for (int i = 0; i < 5 && i < statisticsData.feedTime.size(); i++) {
|
||||
favoritePodNames.add(statisticsData.feedTime.get(i).feed.getTitle());
|
||||
}
|
||||
loadFavoritePodImages(statisticsData);
|
||||
|
||||
totalActivePodcasts = 0;
|
||||
playedActivePodcasts = 0;
|
||||
playedPodcasts = 0;
|
||||
totalTime = 0;
|
||||
ArrayList<String> unplayedActive = new ArrayList<>();
|
||||
for (StatisticsItem item : statisticsData.feedTime) {
|
||||
totalTime += item.timePlayed;
|
||||
if (item.timePlayed > 0) {
|
||||
playedPodcasts++;
|
||||
}
|
||||
if (item.feed.getPreferences().getKeepUpdated()) {
|
||||
totalActivePodcasts++;
|
||||
if (item.timePlayed > 0) {
|
||||
playedActivePodcasts++;
|
||||
} else {
|
||||
unplayedActive.add(item.feed.getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!unplayedActive.isEmpty()) {
|
||||
randomUnplayedActivePodcast = unplayedActive.get((int) (Math.random() * unplayedActive.size()));
|
||||
}
|
||||
|
||||
List<FeedItem> queue = DBReader.getQueue();
|
||||
queueNumEpisodes = queue.size();
|
||||
queueSecondsLeft = 0;
|
||||
for (FeedItem item : queue) {
|
||||
float playbackSpeed = 1;
|
||||
if (UserPreferences.timeRespectsSpeed()) {
|
||||
playbackSpeed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(item.getMedia());
|
||||
}
|
||||
if (item.getMedia() != null) {
|
||||
long itemTimeLeft = item.getMedia().getDuration() - item.getMedia().getPosition();
|
||||
queueSecondsLeft += itemTimeLeft / playbackSpeed;
|
||||
}
|
||||
}
|
||||
queueSecondsLeft /= 1000;
|
||||
|
||||
timeBetweenReleaseAndPlay = DBReader.getTimeBetweenReleaseAndPlayback(timeFilterFrom, timeFilterTo);
|
||||
oldestDate = statisticsData.oldestDate;
|
||||
return statisticsData;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> loadScreen(currentScreen, true),
|
||||
error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
.subscribe(result -> {
|
||||
for (EchoScreen screen : screens) {
|
||||
screen.startLoading(result);
|
||||
}
|
||||
|
||||
void loadFavoritePodImages(DBReader.StatisticsResult statisticsData) {
|
||||
if (disposableFavorite != null) {
|
||||
disposableFavorite.dispose();
|
||||
}
|
||||
disposableFavorite = Observable.fromCallable(
|
||||
() -> {
|
||||
favoritePodImages.clear();
|
||||
for (int i = 0; i < 5 && i < statisticsData.feedTime.size(); i++) {
|
||||
BitmapDrawable cover = new BitmapDrawable(getResources(), (Bitmap) null);
|
||||
try {
|
||||
final int size = SHARE_SIZE / 3;
|
||||
final int radius = (i == 0) ? (size / 16) : (size / 8);
|
||||
cover = new BitmapDrawable(getResources(), Glide.with(this)
|
||||
.asBitmap()
|
||||
.load(statisticsData.feedTime.get(i).feed.getImageUrl())
|
||||
.apply(new RequestOptions()
|
||||
.fitCenter()
|
||||
.transform(new RoundedCorners(radius)))
|
||||
.submit(size, size)
|
||||
.get(5, TimeUnit.SECONDS));
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Loading cover: " + e.getMessage());
|
||||
}
|
||||
favoritePodImages.add(cover);
|
||||
}
|
||||
return statisticsData;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> { },
|
||||
error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package de.danoeh.antennapod.ui.echo;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class EchoConfig {
|
||||
public static final int RELEASE_YEAR = 2023;
|
||||
|
||||
public static long jan1() {
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.set(Calendar.HOUR_OF_DAY, 0);
|
||||
date.set(Calendar.MINUTE, 0);
|
||||
date.set(Calendar.SECOND, 0);
|
||||
date.set(Calendar.MILLISECOND, 0);
|
||||
date.set(Calendar.DAY_OF_MONTH, 1);
|
||||
date.set(Calendar.MONTH, 0);
|
||||
date.set(Calendar.YEAR, RELEASE_YEAR);
|
||||
return date.getTimeInMillis();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -14,7 +14,7 @@ import androidx.core.content.ContextCompat;
|
|||
import java.util.ArrayList;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
|
||||
public abstract class BaseScreen extends Drawable {
|
||||
public abstract class BaseBackground extends Drawable {
|
||||
private final Paint paintBackground;
|
||||
protected final Paint paintParticles;
|
||||
protected final ArrayList<Particle> particles = new ArrayList<>();
|
||||
|
@ -22,7 +22,7 @@ public abstract class BaseScreen extends Drawable {
|
|||
private final int colorBackgroundTo;
|
||||
private long lastFrame = 0;
|
||||
|
||||
public BaseScreen(Context context) {
|
||||
public BaseBackground(Context context) {
|
||||
colorBackgroundFrom = ContextCompat.getColor(context, R.color.gradient_000);
|
||||
colorBackgroundTo = ContextCompat.getColor(context, R.color.gradient_100);
|
||||
paintBackground = new Paint();
|
|
@ -1,14 +1,14 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class BubbleScreen extends BaseScreen {
|
||||
public class BubbleBackground extends BaseBackground {
|
||||
protected static final double PARTICLE_SPEED = 0.00002;
|
||||
protected static final int NUM_PARTICLES = 15;
|
||||
|
||||
public BubbleScreen(Context context) {
|
||||
public BubbleBackground(Context context) {
|
||||
super(context);
|
||||
for (int i = 0; i < NUM_PARTICLES; i++) {
|
||||
particles.add(new Particle(Math.random(), 2.0 * Math.random() - 0.5, // Could already be off-screen
|
|
@ -1,4 +1,4 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -9,11 +9,11 @@ import android.graphics.Typeface;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import de.danoeh.antennapod.ui.echo.EchoActivity;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FinalShareScreen extends BubbleScreen {
|
||||
public class FinalShareBackground extends BubbleBackground {
|
||||
private static final float[][] COVER_POSITIONS = new float[][]{ new float[] {0.0f, 0.0f},
|
||||
new float[] {0.4f, 0.0f}, new float[] {0.4f, 0.2f}, new float[] {0.6f, 0.2f}, new float[] {0.8f, 0.2f}};
|
||||
private final Paint paintTextMain;
|
||||
|
@ -26,14 +26,14 @@ public class FinalShareScreen extends BubbleScreen {
|
|||
private final Typeface typefaceNormal;
|
||||
private final Typeface typefaceBold;
|
||||
|
||||
public FinalShareScreen(Context context,
|
||||
public FinalShareBackground(Context context,
|
||||
ArrayList<String> favoritePodNames, ArrayList<Drawable> favoritePodImages) {
|
||||
super(context);
|
||||
this.heading = context.getString(R.string.echo_share_heading);
|
||||
this.logo = AppCompatResources.getDrawable(context, R.drawable.echo);
|
||||
this.favoritePodNames = favoritePodNames;
|
||||
this.favoritePodImages = favoritePodImages;
|
||||
this.year = String.valueOf(EchoActivity.RELEASE_YEAR);
|
||||
this.year = String.valueOf(EchoConfig.RELEASE_YEAR);
|
||||
typefaceNormal = ResourcesCompat.getFont(context, R.font.sarabun_regular);
|
||||
typefaceBold = ResourcesCompat.getFont(context, R.font.sarabun_semi_bold);
|
||||
paintTextMain = new Paint();
|
|
@ -1,11 +1,11 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class RotatingSquaresScreen extends BaseScreen {
|
||||
public RotatingSquaresScreen(Context context) {
|
||||
public class RotatingSquaresBackground extends BaseBackground {
|
||||
public RotatingSquaresBackground(Context context) {
|
||||
super(context);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
particles.add(new Particle(
|
|
@ -1,13 +1,13 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class StripesScreen extends BaseScreen {
|
||||
public class StripesBackground extends BaseBackground {
|
||||
protected static final int NUM_PARTICLES = 15;
|
||||
|
||||
public StripesScreen(Context context) {
|
||||
public StripesBackground(Context context) {
|
||||
super(context);
|
||||
for (int i = 0; i < NUM_PARTICLES; i++) {
|
||||
particles.add(new Particle(2f * i / NUM_PARTICLES - 1f, 0, 0, 0));
|
|
@ -1,13 +1,13 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class WaveformScreen extends BaseScreen {
|
||||
public class WaveformBackground extends BaseBackground {
|
||||
protected static final int NUM_PARTICLES = 40;
|
||||
|
||||
public WaveformScreen(Context context) {
|
||||
public WaveformBackground(Context context) {
|
||||
super(context);
|
||||
for (int i = 0; i < NUM_PARTICLES; i++) {
|
||||
particles.add(new Particle(1.1f + 1.1f * i / NUM_PARTICLES - 0.05f, 0, 0, 0));
|
|
@ -1,14 +1,14 @@
|
|||
package de.danoeh.antennapod.ui.echo.screens;
|
||||
package de.danoeh.antennapod.ui.echo.background;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class WavesScreen extends BaseScreen {
|
||||
public class WavesBackground extends BaseBackground {
|
||||
protected static final int NUM_PARTICLES = 10;
|
||||
|
||||
public WavesScreen(Context context) {
|
||||
public WavesBackground(Context context) {
|
||||
super(context);
|
||||
paintParticles.setStyle(Paint.Style.STROKE);
|
||||
for (int i = 0; i < NUM_PARTICLES; i++) {
|
|
@ -0,0 +1,48 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class EchoScreen {
|
||||
protected final Context context;
|
||||
|
||||
public EchoScreen(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected final Locale getEchoLanguage() {
|
||||
boolean hasTranslation = !context.getString(R.string.echo_listened_after_title)
|
||||
.equals(getLocalizedResources(Locale.US).getString(R.string.echo_listened_after_title));
|
||||
if (hasTranslation) {
|
||||
return Locale.getDefault();
|
||||
} else {
|
||||
return Locale.US;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected Resources getLocalizedResources(Locale desiredLocale) {
|
||||
Configuration conf = context.getResources().getConfiguration();
|
||||
conf = new Configuration(conf);
|
||||
conf.setLocale(desiredLocale);
|
||||
Context localizedContext = context.createConfigurationContext(conf);
|
||||
return localizedContext.getResources();
|
||||
}
|
||||
|
||||
public void postInvalidate() {
|
||||
// Do nothing by default
|
||||
}
|
||||
|
||||
public abstract View getView();
|
||||
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
// Do nothing by default
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import androidx.core.app.ShareCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.FinalShareBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FinalShareScreen extends EchoScreen {
|
||||
private static final int SHARE_SIZE = 1000;
|
||||
private static final String TAG = "FinalShareScreen";
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
private final ArrayList<String> favoritePodNames = new ArrayList<>();
|
||||
private final ArrayList<Drawable> favoritePodImages = new ArrayList<>();
|
||||
private final FinalShareBackground background;
|
||||
private Disposable disposable;
|
||||
|
||||
public FinalShareScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.actionButton.setOnClickListener(v -> share());
|
||||
viewBinding.actionButton.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(
|
||||
context.getResources(), R.drawable.ic_share, context.getTheme()), null, null, null);
|
||||
viewBinding.actionButton.setVisibility(View.VISIBLE);
|
||||
viewBinding.actionButton.setText(R.string.share_label);
|
||||
background = new FinalShareBackground(context, favoritePodNames, favoritePodImages);
|
||||
viewBinding.backgroundImage.setImageDrawable(background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
private void share() {
|
||||
try {
|
||||
Bitmap bitmap = Bitmap.createBitmap(SHARE_SIZE, SHARE_SIZE, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
background.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
background.draw(canvas);
|
||||
viewBinding.backgroundImage.setImageDrawable(null);
|
||||
viewBinding.backgroundImage.setImageDrawable(background);
|
||||
File file = new File(UserPreferences.getDataFolder(null), "AntennaPodEcho.png");
|
||||
FileOutputStream stream = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
|
||||
stream.close();
|
||||
|
||||
Uri fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority), file);
|
||||
new ShareCompat.IntentBuilder(context)
|
||||
.setType("image/png")
|
||||
.addStream(fileUri)
|
||||
.setText(context.getString(R.string.echo_share, EchoConfig.RELEASE_YEAR))
|
||||
.setChooserTitle(R.string.share_file_label)
|
||||
.startChooser();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsData) {
|
||||
favoritePodNames.clear();
|
||||
for (int i = 0; i < 5 && i < statisticsData.feedTime.size(); i++) {
|
||||
favoritePodNames.add(statisticsData.feedTime.get(i).feed.getTitle());
|
||||
}
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposable = Observable.fromCallable(
|
||||
() -> {
|
||||
favoritePodImages.clear();
|
||||
for (int i = 0; i < 5 && i < statisticsData.feedTime.size(); i++) {
|
||||
BitmapDrawable cover = new BitmapDrawable(context.getResources(), (Bitmap) null);
|
||||
try {
|
||||
final int size = SHARE_SIZE / 3;
|
||||
final int radius = (i == 0) ? (size / 16) : (size / 8);
|
||||
cover = new BitmapDrawable(context.getResources(), Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(statisticsData.feedTime.get(i).feed.getImageUrl())
|
||||
.apply(new RequestOptions()
|
||||
.fitCenter()
|
||||
.transform(new RoundedCorners(radius)))
|
||||
.submit(size, size)
|
||||
.get(5, TimeUnit.SECONDS));
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Loading cover: " + e.getMessage());
|
||||
}
|
||||
favoritePodImages.add(cover);
|
||||
}
|
||||
return statisticsData;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> { },
|
||||
error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.database.StatisticsItem;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.WavesBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HoarderScreen extends EchoScreen {
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
|
||||
public HoarderScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.aboveLabel.setText(R.string.echo_hoarder_title);
|
||||
viewBinding.backgroundImage.setImageDrawable(new WavesBackground(context));
|
||||
}
|
||||
|
||||
private void display(int playedActivePodcasts, int totalActivePodcasts, String randomUnplayedActivePodcast) {
|
||||
int percentagePlayed = (int) (100.0 * playedActivePodcasts / totalActivePodcasts);
|
||||
if (percentagePlayed < 25) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_cabinet);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_hoarder);
|
||||
viewBinding.smallLabel.setText(context.getString(R.string.echo_hoarder_comment_hoarder,
|
||||
percentagePlayed, totalActivePodcasts));
|
||||
} else if (percentagePlayed < 75) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_check);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_medium);
|
||||
viewBinding.smallLabel.setText(context.getString(R.string.echo_hoarder_comment_medium,
|
||||
percentagePlayed, totalActivePodcasts, randomUnplayedActivePodcast));
|
||||
} else {
|
||||
viewBinding.largeLabel.setText(R.string.echo_hoarder_emoji_clean);
|
||||
viewBinding.belowLabel.setText(R.string.echo_hoarder_subtitle_clean);
|
||||
viewBinding.smallLabel.setText(context.getString(R.string.echo_hoarder_comment_clean,
|
||||
percentagePlayed, totalActivePodcasts));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
int totalActivePodcasts = 0;
|
||||
int playedActivePodcasts = 0;
|
||||
String randomUnplayedActivePodcast = "";
|
||||
ArrayList<String> unplayedActive = new ArrayList<>();
|
||||
for (StatisticsItem item : statisticsResult.feedTime) {
|
||||
if (item.feed.getPreferences().getKeepUpdated()) {
|
||||
totalActivePodcasts++;
|
||||
if (item.timePlayed > 0) {
|
||||
playedActivePodcasts++;
|
||||
} else {
|
||||
unplayedActive.add(item.feed.getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!unplayedActive.isEmpty()) {
|
||||
randomUnplayedActivePodcast = unplayedActive.get((int) (Math.random() * unplayedActive.size()));
|
||||
}
|
||||
display(playedActivePodcasts, totalActivePodcasts, randomUnplayedActivePodcast);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.database.StatisticsItem;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.WaveformBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
|
||||
public class HoursPlayedScreen extends EchoScreen {
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
|
||||
public HoursPlayedScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.aboveLabel.setText(R.string.echo_hours_this_year);
|
||||
viewBinding.backgroundImage.setImageDrawable(new WaveformBackground(context));
|
||||
}
|
||||
|
||||
private void display(long totalTime, int playedPodcasts) {
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", totalTime / 3600));
|
||||
viewBinding.belowLabel.setText(context.getResources()
|
||||
.getQuantityString(R.plurals.echo_hours_podcasts, playedPodcasts, playedPodcasts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
int playedPodcasts = 0;
|
||||
long totalTime = 0;
|
||||
for (StatisticsItem item : statisticsResult.feedTime) {
|
||||
totalTime += item.timePlayed;
|
||||
if (item.timePlayed > 0) {
|
||||
playedPodcasts++;
|
||||
}
|
||||
}
|
||||
display(totalTime, playedPodcasts);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.BubbleBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
|
||||
public class IntroScreen extends EchoScreen {
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
|
||||
public IntroScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.echoLogo.setVisibility(View.VISIBLE);
|
||||
viewBinding.aboveLabel.setText(R.string.echo_intro_your_year);
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", EchoConfig.RELEASE_YEAR));
|
||||
viewBinding.belowLabel.setText(R.string.echo_intro_in_podcasts);
|
||||
viewBinding.smallLabel.setText(R.string.echo_intro_locally);
|
||||
viewBinding.backgroundImage.setImageDrawable(new BubbleBackground(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.common.Converter;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.StripesBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class QueueScreen extends EchoScreen {
|
||||
private static final String TAG = "QueueScreen";
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
private Disposable disposable;
|
||||
|
||||
public QueueScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.backgroundImage.setImageDrawable(new StripesBackground(context));
|
||||
}
|
||||
|
||||
private void display(int queueNumEpisodes, long queueSecondsLeft) {
|
||||
viewBinding.largeLabel.setText(String.format(getEchoLanguage(), "%d", queueSecondsLeft / 3600));
|
||||
viewBinding.belowLabel.setText(context.getResources().getQuantityString(
|
||||
R.plurals.echo_queue_hours_waiting, queueNumEpisodes, queueNumEpisodes));
|
||||
|
||||
Calendar dec31 = Calendar.getInstance();
|
||||
dec31.set(Calendar.DAY_OF_MONTH, 31);
|
||||
dec31.set(Calendar.MONTH, Calendar.DECEMBER);
|
||||
int daysUntilNextYear = Math.max(1,
|
||||
dec31.get(Calendar.DAY_OF_YEAR) - Calendar.getInstance().get(Calendar.DAY_OF_YEAR) + 1);
|
||||
long secondsPerDay = queueSecondsLeft / daysUntilNextYear;
|
||||
String timePerDay = Converter.getDurationStringLocalized(
|
||||
getLocalizedResources(getEchoLanguage()), secondsPerDay * 1000, true);
|
||||
double hoursPerDay = secondsPerDay / 3600.0;
|
||||
int nextYear = EchoConfig.RELEASE_YEAR + 1;
|
||||
if (hoursPerDay < 1.5) {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_clean);
|
||||
viewBinding.smallLabel.setText(
|
||||
context.getString(R.string.echo_queue_hours_clean, timePerDay, nextYear));
|
||||
} else if (hoursPerDay <= 24) {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_many);
|
||||
viewBinding.smallLabel.setText(
|
||||
context.getString(R.string.echo_queue_hours_normal, timePerDay, nextYear));
|
||||
} else {
|
||||
viewBinding.aboveLabel.setText(R.string.echo_queue_title_many);
|
||||
viewBinding.smallLabel.setText(context.getString(R.string.echo_queue_hours_much, timePerDay, nextYear));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposable = Observable.fromCallable(DBReader::getQueue)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(queue -> {
|
||||
long queueSecondsLeft = 0;
|
||||
for (FeedItem item : queue) {
|
||||
float playbackSpeed = 1;
|
||||
if (UserPreferences.timeRespectsSpeed()) {
|
||||
playbackSpeed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(item.getMedia());
|
||||
}
|
||||
if (item.getMedia() != null) {
|
||||
long itemTimeLeft = item.getMedia().getDuration() - item.getMedia().getPosition();
|
||||
queueSecondsLeft += itemTimeLeft / playbackSpeed;
|
||||
}
|
||||
}
|
||||
queueSecondsLeft /= 1000;
|
||||
display(queue.size(), queueSecondsLeft);
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.RotatingSquaresBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class ThanksScreen extends EchoScreen {
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
|
||||
public ThanksScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.aboveLabel.setText("");
|
||||
viewBinding.largeLabel.setText(R.string.echo_thanks_large);
|
||||
|
||||
viewBinding.smallLabel.setText(R.string.echo_thanks_now_favorite);
|
||||
viewBinding.backgroundImage.setImageDrawable(new RotatingSquaresBackground(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
if (statisticsResult.oldestDate < EchoConfig.jan1()) {
|
||||
String skeleton = DateFormat.getBestDateTimePattern(getEchoLanguage(), "MMMM yyyy");
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(skeleton, getEchoLanguage());
|
||||
String dateFrom = dateFormat.format(new Date(statisticsResult.oldestDate));
|
||||
viewBinding.belowLabel.setText(context.getString(R.string.echo_thanks_we_are_glad_old, dateFrom));
|
||||
} else {
|
||||
viewBinding.belowLabel.setText(R.string.echo_thanks_we_are_glad_new);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package de.danoeh.antennapod.ui.echo.screen;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.ui.common.Converter;
|
||||
import de.danoeh.antennapod.ui.echo.EchoConfig;
|
||||
import de.danoeh.antennapod.ui.echo.R;
|
||||
import de.danoeh.antennapod.ui.echo.background.RotatingSquaresBackground;
|
||||
import de.danoeh.antennapod.ui.echo.databinding.SimpleEchoScreenBinding;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class TimeReleasePlayScreen extends EchoScreen {
|
||||
private static final String TAG = "TimeReleasePlayScreen";
|
||||
private final SimpleEchoScreenBinding viewBinding;
|
||||
private Disposable disposable;
|
||||
|
||||
public TimeReleasePlayScreen(Context context, LayoutInflater layoutInflater) {
|
||||
super(context);
|
||||
viewBinding = SimpleEchoScreenBinding.inflate(layoutInflater);
|
||||
viewBinding.aboveLabel.setText(R.string.echo_listened_after_title);
|
||||
viewBinding.backgroundImage.setImageDrawable(new RotatingSquaresBackground(context));
|
||||
}
|
||||
|
||||
private void display(long timeBetweenReleaseAndPlay) {
|
||||
if (timeBetweenReleaseAndPlay <= 1000L * 3600 * 24 * 2.5) {
|
||||
viewBinding.largeLabel.setText(R.string.echo_listened_after_emoji_run);
|
||||
viewBinding.belowLabel.setText(R.string.echo_listened_after_comment_addict);
|
||||
} else {
|
||||
viewBinding.largeLabel.setText(R.string.echo_listened_after_emoji_yoga);
|
||||
viewBinding.belowLabel.setText(R.string.echo_listened_after_comment_easy);
|
||||
}
|
||||
viewBinding.smallLabel.setText(context.getString(R.string.echo_listened_after_time,
|
||||
Converter.getDurationStringLocalized(
|
||||
getLocalizedResources(getEchoLanguage()), timeBetweenReleaseAndPlay, true)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInvalidate() {
|
||||
viewBinding.backgroundImage.postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading(DBReader.StatisticsResult statisticsResult) {
|
||||
super.startLoading(statisticsResult);
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposable = Observable.fromCallable(() ->
|
||||
DBReader.getTimeBetweenReleaseAndPlayback(EchoConfig.jan1(), Long.MAX_VALUE))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::display, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
}
|
|
@ -1,16 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/echoImage"
|
||||
<FrameLayout
|
||||
android:id="@+id/screenContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -49,87 +46,6 @@
|
|||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/echoProgressImage" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:padding="32dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aboveLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="text above"
|
||||
style="@style/TextAppearance.Material3.TitleLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/largeLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:fontFamily="@font/sarabun_semi_bold"
|
||||
app:fontFamily="@font/sarabun_semi_bold"
|
||||
tools:text="large"
|
||||
style="@style/TextAppearance.Material3.DisplayLarge"
|
||||
tools:targetApi="p" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/belowLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="text below"
|
||||
style="@style/TextAppearance.Material3.TitleLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/smallLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/echoLogo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_margin="32dp"
|
||||
android:src="@drawable/echo"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/shareButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="56dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_margin="32dp"
|
||||
android:text="@string/share_label"
|
||||
android:drawableLeft="@drawable/ic_share"
|
||||
android:textColor="#fff"
|
||||
android:contentDescription="@string/share_label"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
app:strokeColor="#fff"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/backgroundImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:padding="32dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aboveLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="text above"
|
||||
style="@style/TextAppearance.Material3.TitleLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/largeLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:fontFamily="@font/sarabun_semi_bold"
|
||||
app:fontFamily="@font/sarabun_semi_bold"
|
||||
tools:text="large"
|
||||
style="@style/TextAppearance.Material3.DisplayLarge"
|
||||
tools:targetApi="p" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/belowLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="text below"
|
||||
style="@style/TextAppearance.Material3.TitleLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/smallLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:fontFamily="@font/sarabun_regular"
|
||||
app:fontFamily="@font/sarabun_regular"
|
||||
tools:text="small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/echoLogo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/echo"
|
||||
android:layout_margin="32dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/actionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="56dp"
|
||||
android:visibility="gone"
|
||||
android:layout_margin="32dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:textColor="#fff"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
app:strokeColor="#fff"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation,PluralsCandidate">
|
||||
<string name="debug_echo" translatable="false">[Debug] Echo</string>
|
||||
<string name="echo_home_header">Review the year</string>
|
||||
<string name="echo_home_subtitle">Your top podcasts and stats from the past year. Exclusively on your phone.</string>
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ dependencies {
|
|||
implementation project(':storage:database')
|
||||
implementation project(":ui:app-start-intent")
|
||||
implementation project(":ui:common")
|
||||
implementation project(":ui:echo")
|
||||
|
||||
annotationProcessor "androidx.annotation:annotation:$annotationVersion"
|
||||
implementation "androidx.appcompat:appcompat:$appcompatVersion"
|
||||
|
|
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.ui.statistics;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
|
@ -21,6 +22,7 @@ import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
|||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.event.StatisticsEvent;
|
||||
import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
|
||||
import de.danoeh.antennapod.ui.echo.EchoActivity;
|
||||
import de.danoeh.antennapod.ui.statistics.downloads.DownloadStatisticsFragment;
|
||||
import de.danoeh.antennapod.ui.statistics.subscriptions.SubscriptionStatisticsFragment;
|
||||
import de.danoeh.antennapod.ui.statistics.years.YearsStatisticsFragment;
|
||||
|
@ -61,6 +63,9 @@ public class StatisticsFragment extends PagedToolbarFragment {
|
|||
toolbar = rootView.findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(getString(R.string.statistics_label));
|
||||
toolbar.inflateMenu(R.menu.statistics);
|
||||
if (BuildConfig.DEBUG) {
|
||||
toolbar.getMenu().findItem(R.id.debug_echo).setVisible(true);
|
||||
}
|
||||
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
|
||||
viewPager.setAdapter(new StatisticsPagerAdapter(this));
|
||||
// Give the TabLayout the ViewPager
|
||||
|
@ -89,6 +94,8 @@ public class StatisticsFragment extends PagedToolbarFragment {
|
|||
if (item.getItemId() == R.id.statistics_reset) {
|
||||
confirmResetStatistics();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.debug_echo) {
|
||||
startActivity(new Intent(getContext(), EchoActivity.class));
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
android:id="@+id/statistics_filter"
|
||||
android:icon="@drawable/ic_filter"
|
||||
android:title="@string/filter"
|
||||
custom:showAsAction="ifRoom">
|
||||
</item>
|
||||
custom:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/debug_echo"
|
||||
android:title="@string/debug_echo"
|
||||
custom:showAsAction="never"
|
||||
android:visible="false" />
|
||||
|
||||
</menu>
|
||||
|
|
Loading…
Reference in New Issue