From d38c7a442aa9e1b6d69146f2647dba24f56dacf4 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 30 Aug 2020 09:17:24 +0200 Subject: Added 'special thanks' screen --- app/src/main/assets/special_thanks.csv | 3 + .../preferences/AboutDevelopersFragment.java | 65 ----------- .../fragment/preferences/AboutFragment.java | 56 --------- .../preferences/AboutLicensesFragment.java | 126 --------------------- .../preferences/AboutTranslatorsFragment.java | 64 ----------- .../preferences/MainPreferencesFragment.java | 1 + .../fragment/preferences/about/AboutFragment.java | 51 +++++++++ .../about/ContributorsPagerFragment.java | 95 ++++++++++++++++ .../preferences/about/DevelopersFragment.java | 59 ++++++++++ .../preferences/about/LicensesFragment.java | 126 +++++++++++++++++++++ .../preferences/about/SpecialThanksFragment.java | 58 ++++++++++ .../preferences/about/TranslatorsFragment.java | 58 ++++++++++ app/src/main/res/xml/preferences_about.xml | 11 +- 13 files changed, 454 insertions(+), 319 deletions(-) create mode 100644 app/src/main/assets/special_thanks.csv delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutDevelopersFragment.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutFragment.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutLicensesFragment.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutTranslatorsFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/LicensesFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java (limited to 'app/src') diff --git a/app/src/main/assets/special_thanks.csv b/app/src/main/assets/special_thanks.csv new file mode 100644 index 000000000..348e3208e --- /dev/null +++ b/app/src/main/assets/special_thanks.csv @@ -0,0 +1,3 @@ +221 Pixels;Logo design;https://avatars2.githubusercontent.com/u/58243143?s=60&v=4 +ByteHamster;Forum admin;https://avatars2.githubusercontent.com/u/5811634?s=60&v=4 +Keunes;Communications;https://avatars2.githubusercontent.com/u/11229646?s=60&v=4 diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutDevelopersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutDevelopersFragment.java deleted file mode 100644 index 62a5eb306..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutDevelopersFragment.java +++ /dev/null @@ -1,65 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.os.Bundle; -import android.view.View; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.ListFragment; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.adapter.SimpleIconListAdapter; -import io.reactivex.Single; -import io.reactivex.SingleOnSubscribe; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.ArrayList; - -public class AboutDevelopersFragment extends ListFragment { - private Disposable developersLoader; - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getListView().setDivider(null); - getListView().setSelector(android.R.color.transparent); - - developersLoader = Single.create((SingleOnSubscribe>) emitter -> { - ArrayList developers = new ArrayList<>(); - BufferedReader reader = new BufferedReader(new InputStreamReader( - getContext().getAssets().open("developers.csv"))); - String line; - while ((line = reader.readLine()) != null) { - String[] info = line.split(";"); - developers.add(new SimpleIconListAdapter.ListItem(info[0], info[2], - "https://avatars2.githubusercontent.com/u/" + info[1] + "?s=60&v=4")); - } - emitter.onSuccess(developers); - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - developers -> setListAdapter(new SimpleIconListAdapter<>(getContext(), developers)), - error -> Toast.makeText(getContext(), "Error while loading developers", Toast.LENGTH_LONG).show() - ); - - } - - @Override - public void onStop() { - super.onStop(); - if (developersLoader != null) { - developersLoader.dispose(); - } - } - - @Override - public void onStart() { - super.onStart(); - ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.developers); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutFragment.java deleted file mode 100644 index 0fa7bd4bb..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutFragment.java +++ /dev/null @@ -1,56 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.os.Bundle; -import androidx.preference.PreferenceFragmentCompat; -import com.google.android.material.snackbar.Snackbar; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.core.util.IntentUtils; - -public class AboutFragment extends PreferenceFragmentCompat { - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - addPreferencesFromResource(R.xml.preferences_about); - - findPreference("about_version").setSummary(String.format( - "%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.COMMIT_HASH)); - findPreference("about_version").setOnPreferenceClickListener((preference) -> { - ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText(getString(R.string.bug_report_title), - findPreference("about_version").getSummary()); - clipboard.setPrimaryClip(clip); - Snackbar.make(getView(), R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show(); - return true; - }); - findPreference("about_developers").setOnPreferenceClickListener((preference) -> { - getFragmentManager().beginTransaction().replace(R.id.content, new AboutDevelopersFragment()) - .addToBackStack(getString(R.string.developers)).commit(); - return true; - }); - findPreference("about_translators").setOnPreferenceClickListener((preference) -> { - getFragmentManager().beginTransaction().replace(R.id.content, new AboutTranslatorsFragment()) - .addToBackStack(getString(R.string.translators)).commit(); - return true; - }); - findPreference("about_privacy_policy").setOnPreferenceClickListener((preference) -> { - IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy.html"); - return true; - }); - findPreference("about_licenses").setOnPreferenceClickListener((preference) -> { - getFragmentManager().beginTransaction().replace(R.id.content, new AboutLicensesFragment()) - .addToBackStack(getString(R.string.translators)).commit(); - return true; - }); - } - - @Override - public void onStart() { - super.onStart(); - ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.about_pref); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutLicensesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutLicensesFragment.java deleted file mode 100644 index 536d11e01..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutLicensesFragment.java +++ /dev/null @@ -1,126 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.os.Bundle; -import android.view.View; -import android.widget.ListView; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.ListFragment; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.adapter.SimpleIconListAdapter; -import de.danoeh.antennapod.core.util.IntentUtils; -import io.reactivex.Single; -import io.reactivex.SingleOnSubscribe; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.NodeList; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; - -public class AboutLicensesFragment extends ListFragment { - private Disposable licensesLoader; - private final ArrayList licenses = new ArrayList<>(); - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getListView().setDivider(null); - - licensesLoader = Single.create((SingleOnSubscribe>) emitter -> { - licenses.clear(); - InputStream stream = getContext().getAssets().open("licenses.xml"); - DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - NodeList libraryList = docBuilder.parse(stream).getElementsByTagName("library"); - for (int i = 0; i < libraryList.getLength(); i++) { - NamedNodeMap lib = libraryList.item(i).getAttributes(); - licenses.add(new LicenseItem( - lib.getNamedItem("name").getTextContent(), - String.format("By %s, %s license", - lib.getNamedItem("author").getTextContent(), - lib.getNamedItem("license").getTextContent()), - null, - lib.getNamedItem("website").getTextContent(), - lib.getNamedItem("licenseText").getTextContent())); - } - emitter.onSuccess(licenses); - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - developers -> setListAdapter(new SimpleIconListAdapter(getContext(), developers)), - error -> Toast.makeText(getContext(), "Error while loading licenses", Toast.LENGTH_LONG).show() - ); - - } - - private static class LicenseItem extends SimpleIconListAdapter.ListItem { - final String licenseUrl; - final String licenseTextFile; - - LicenseItem(String title, String subtitle, String imageUrl, String licenseUrl, String licenseTextFile) { - super(title, subtitle, imageUrl); - this.licenseUrl = licenseUrl; - this.licenseTextFile = licenseTextFile; - } - } - - @Override - public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) { - super.onListItemClick(l, v, position, id); - - LicenseItem item = licenses.get(position); - CharSequence[] items = {"View website", "View license"}; - new AlertDialog.Builder(getContext()) - .setTitle(item.title) - .setItems(items, (dialog, which) -> { - if (which == 0) { - IntentUtils.openInBrowser(getContext(), item.licenseUrl); - } else if (which == 1) { - showLicenseText(item.licenseTextFile); - } - }).show(); - } - - private void showLicenseText(String licenseTextFile) { - try { - BufferedReader reader = new BufferedReader(new InputStreamReader( - getContext().getAssets().open(licenseTextFile))); - StringBuilder licenseText = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - licenseText.append(line).append("\n"); - } - - new AlertDialog.Builder(getContext()) - .setMessage(licenseText) - .show(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void onStop() { - super.onStop(); - if (licensesLoader != null) { - licensesLoader.dispose(); - } - } - - @Override - public void onStart() { - super.onStart(); - ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.licenses); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutTranslatorsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutTranslatorsFragment.java deleted file mode 100644 index 914dbb9a2..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AboutTranslatorsFragment.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.os.Bundle; -import android.view.View; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.ListFragment; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.adapter.SimpleIconListAdapter; -import io.reactivex.Single; -import io.reactivex.SingleOnSubscribe; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.ArrayList; - -public class AboutTranslatorsFragment extends ListFragment { - private Disposable translatorsLoader; - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getListView().setDivider(null); - getListView().setSelector(android.R.color.transparent); - - translatorsLoader = Single.create((SingleOnSubscribe>) emitter -> { - ArrayList translators = new ArrayList<>(); - BufferedReader reader = new BufferedReader(new InputStreamReader( - getContext().getAssets().open("translators.csv"))); - String line; - while ((line = reader.readLine()) != null) { - String[] info = line.split(";"); - translators.add(new SimpleIconListAdapter.ListItem(info[0], info[1], null)); - } - emitter.onSuccess(translators); - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - translators -> setListAdapter(new SimpleIconListAdapter<>(getContext(), translators)), - error -> Toast.makeText(getContext(), "Error while loading translators", Toast.LENGTH_LONG).show() - ); - - } - - @Override - public void onStop() { - super.onStop(); - if (translatorsLoader != null) { - translatorsLoader.dispose(); - } - } - - @Override - public void onStart() { - super.onStart(); - ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.translators); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java index 406585808..05ea521a9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java @@ -10,6 +10,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.BugReportActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.util.IntentUtils; +import de.danoeh.antennapod.fragment.preferences.about.AboutFragment; public class MainPreferencesFragment extends PreferenceFragmentCompat { private static final String TAG = "MainPreferencesFragment"; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java new file mode 100644 index 000000000..b440d053b --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java @@ -0,0 +1,51 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Bundle; +import androidx.preference.PreferenceFragmentCompat; +import com.google.android.material.snackbar.Snackbar; +import de.danoeh.antennapod.BuildConfig; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.core.util.IntentUtils; + +public class AboutFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.preferences_about); + + findPreference("about_version").setSummary(String.format( + "%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.COMMIT_HASH)); + findPreference("about_version").setOnPreferenceClickListener((preference) -> { + ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText(getString(R.string.bug_report_title), + findPreference("about_version").getSummary()); + clipboard.setPrimaryClip(clip); + Snackbar.make(getView(), R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show(); + return true; + }); + findPreference("about_contributors").setOnPreferenceClickListener((preference) -> { + getParentFragmentManager().beginTransaction().replace(R.id.content, new ContributorsPagerFragment()) + .addToBackStack(getString(R.string.contributors)).commit(); + return true; + }); + findPreference("about_privacy_policy").setOnPreferenceClickListener((preference) -> { + IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy.html"); + return true; + }); + findPreference("about_licenses").setOnPreferenceClickListener((preference) -> { + getParentFragmentManager().beginTransaction().replace(R.id.content, new LicensesFragment()) + .addToBackStack(getString(R.string.translators)).commit(); + return true; + }); + } + + @Override + public void onStart() { + super.onStart(); + ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.about_pref); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java new file mode 100644 index 000000000..20cef1313 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java @@ -0,0 +1,95 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; + +/** + * Displays the 'about->Contributors' pager screen. + */ +public class ContributorsPagerFragment extends Fragment { + + public static final String TAG = "StatisticsFragment"; + + private static final int POS_DEVELOPERS = 0; + private static final int POS_TRANSLATORS = 1; + private static final int POS_SPECIAL_THANKS = 2; + private static final int TOTAL_COUNT = 3; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + setHasOptionsMenu(true); + + View rootView = inflater.inflate(R.layout.pager_fragment, container, false); + ViewPager2 viewPager = rootView.findViewById(R.id.viewpager); + viewPager.setAdapter(new StatisticsPagerAdapter(this)); + // Give the TabLayout the ViewPager + TabLayout tabLayout = rootView.findViewById(R.id.sliding_tabs); + new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { + switch (position) { + case POS_DEVELOPERS: + tab.setText(R.string.developers); + break; + case POS_TRANSLATORS: + tab.setText(R.string.translators); + break; + case POS_SPECIAL_THANKS: + tab.setText(R.string.special_thanks); + break; + default: + break; + } + }).attach(); + + rootView.findViewById(R.id.toolbar).setVisibility(View.GONE); + + return rootView; + } + + @Override + public void onStart() { + super.onStart(); + ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.contributors); + } + + public static class StatisticsPagerAdapter extends FragmentStateAdapter { + + StatisticsPagerAdapter(@NonNull Fragment fragment) { + super(fragment); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + switch (position) { + case POS_TRANSLATORS: + return new TranslatorsFragment(); + case POS_SPECIAL_THANKS: + return new SpecialThanksFragment(); + default: + case POS_DEVELOPERS: + return new DevelopersFragment(); + } + } + + @Override + public int getItemCount() { + return TOTAL_COUNT; + } + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java new file mode 100644 index 000000000..60d9f95dd --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java @@ -0,0 +1,59 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.ListFragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.adapter.SimpleIconListAdapter; +import io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +public class DevelopersFragment extends ListFragment { + private Disposable developersLoader; + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setDivider(null); + getListView().setSelector(android.R.color.transparent); + + developersLoader = Single.create((SingleOnSubscribe>) emitter -> { + ArrayList developers = new ArrayList<>(); + BufferedReader reader = new BufferedReader(new InputStreamReader( + getContext().getAssets().open("developers.csv"))); + String line; + while ((line = reader.readLine()) != null) { + String[] info = line.split(";"); + developers.add(new SimpleIconListAdapter.ListItem(info[0], info[2], + "https://avatars2.githubusercontent.com/u/" + info[1] + "?s=60&v=4")); + } + emitter.onSuccess(developers); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + developers -> setListAdapter(new SimpleIconListAdapter<>(getContext(), developers)), + error -> Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show() + ); + + } + + @Override + public void onStop() { + super.onStop(); + if (developersLoader != null) { + developersLoader.dispose(); + } + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/LicensesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/LicensesFragment.java new file mode 100644 index 000000000..97565a613 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/LicensesFragment.java @@ -0,0 +1,126 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.os.Bundle; +import android.view.View; +import android.widget.ListView; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.ListFragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.adapter.SimpleIconListAdapter; +import de.danoeh.antennapod.core.util.IntentUtils; +import io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; + +public class LicensesFragment extends ListFragment { + private Disposable licensesLoader; + private final ArrayList licenses = new ArrayList<>(); + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setDivider(null); + + licensesLoader = Single.create((SingleOnSubscribe>) emitter -> { + licenses.clear(); + InputStream stream = getContext().getAssets().open("licenses.xml"); + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + NodeList libraryList = docBuilder.parse(stream).getElementsByTagName("library"); + for (int i = 0; i < libraryList.getLength(); i++) { + NamedNodeMap lib = libraryList.item(i).getAttributes(); + licenses.add(new LicenseItem( + lib.getNamedItem("name").getTextContent(), + String.format("By %s, %s license", + lib.getNamedItem("author").getTextContent(), + lib.getNamedItem("license").getTextContent()), + null, + lib.getNamedItem("website").getTextContent(), + lib.getNamedItem("licenseText").getTextContent())); + } + emitter.onSuccess(licenses); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + developers -> setListAdapter(new SimpleIconListAdapter(getContext(), developers)), + error -> Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show() + ); + + } + + private static class LicenseItem extends SimpleIconListAdapter.ListItem { + final String licenseUrl; + final String licenseTextFile; + + LicenseItem(String title, String subtitle, String imageUrl, String licenseUrl, String licenseTextFile) { + super(title, subtitle, imageUrl); + this.licenseUrl = licenseUrl; + this.licenseTextFile = licenseTextFile; + } + } + + @Override + public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) { + super.onListItemClick(l, v, position, id); + + LicenseItem item = licenses.get(position); + CharSequence[] items = {"View website", "View license"}; + new AlertDialog.Builder(getContext()) + .setTitle(item.title) + .setItems(items, (dialog, which) -> { + if (which == 0) { + IntentUtils.openInBrowser(getContext(), item.licenseUrl); + } else if (which == 1) { + showLicenseText(item.licenseTextFile); + } + }).show(); + } + + private void showLicenseText(String licenseTextFile) { + try { + BufferedReader reader = new BufferedReader(new InputStreamReader( + getContext().getAssets().open(licenseTextFile))); + StringBuilder licenseText = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + licenseText.append(line).append("\n"); + } + + new AlertDialog.Builder(getContext()) + .setMessage(licenseText) + .show(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onStop() { + super.onStop(); + if (licensesLoader != null) { + licensesLoader.dispose(); + } + } + + @Override + public void onStart() { + super.onStart(); + ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.licenses); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java new file mode 100644 index 000000000..6db1389ea --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java @@ -0,0 +1,58 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.ListFragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.adapter.SimpleIconListAdapter; +import io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +public class SpecialThanksFragment extends ListFragment { + private Disposable translatorsLoader; + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setDivider(null); + getListView().setSelector(android.R.color.transparent); + + translatorsLoader = Single.create((SingleOnSubscribe>) emitter -> { + ArrayList translators = new ArrayList<>(); + BufferedReader reader = new BufferedReader(new InputStreamReader( + getContext().getAssets().open("special_thanks.csv"))); + String line; + while ((line = reader.readLine()) != null) { + String[] info = line.split(";"); + translators.add(new SimpleIconListAdapter.ListItem(info[0], info[1], info[2])); + } + emitter.onSuccess(translators); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + translators -> setListAdapter(new SimpleIconListAdapter<>(getContext(), translators)), + error -> Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show() + ); + + } + + @Override + public void onStop() { + super.onStop(); + if (translatorsLoader != null) { + translatorsLoader.dispose(); + } + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java new file mode 100644 index 000000000..e8d8e113b --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java @@ -0,0 +1,58 @@ +package de.danoeh.antennapod.fragment.preferences.about; + +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.ListFragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.adapter.SimpleIconListAdapter; +import io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +public class TranslatorsFragment extends ListFragment { + private Disposable translatorsLoader; + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getListView().setDivider(null); + getListView().setSelector(android.R.color.transparent); + + translatorsLoader = Single.create((SingleOnSubscribe>) emitter -> { + ArrayList translators = new ArrayList<>(); + BufferedReader reader = new BufferedReader(new InputStreamReader( + getContext().getAssets().open("translators.csv"))); + String line; + while ((line = reader.readLine()) != null) { + String[] info = line.split(";"); + translators.add(new SimpleIconListAdapter.ListItem(info[0], info[1], null)); + } + emitter.onSuccess(translators); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + translators -> setListAdapter(new SimpleIconListAdapter<>(getContext(), translators)), + error -> Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show() + ); + + } + + @Override + public void onStop() { + super.onStop(); + if (translatorsLoader != null) { + translatorsLoader.dispose(); + } + } +} diff --git a/app/src/main/res/xml/preferences_about.xml b/app/src/main/res/xml/preferences_about.xml index 9b8d744e1..475a1152f 100644 --- a/app/src/main/res/xml/preferences_about.xml +++ b/app/src/main/res/xml/preferences_about.xml @@ -10,15 +10,10 @@ android:icon="?attr/ic_unfav" android:summary="1.7.2 (asd8qs)"/> - + android:summary="@string/contributors_summary" + android:title="@string/contributors"/>