1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-10-30 14:52:59 +00:00

Merge pull request #612 from coffeemakr/feature-about-activity

Add about activity
This commit is contained in:
Mauricio Colli
2017-07-11 12:49:14 -03:00
committed by GitHub
22 changed files with 2276 additions and 9 deletions

View File

@@ -148,18 +148,15 @@ public class MainActivity extends AppCompatActivity {
return true;
}
case R.id.action_settings: {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
NavigationHelper.openSettings(this);
return true;
}
case R.id.action_show_downloads: {
if (!PermissionHelper.checkStoragePermissions(this)) {
return false;
}
Intent intent = new Intent(this, DownloadActivity.class);
startActivity(intent);
return true;
return NavigationHelper.openDownloads(this);
}
case R.id.action_about:
NavigationHelper.openAbout(this);
return true;
default:
return super.onOptionsItemSelected(item);
}

View File

@@ -0,0 +1,197 @@
package org.schabi.newpipe.about;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ThemeHelper;
public class AboutActivity extends AppCompatActivity {
/**
* List of all software components
*/
private static final SoftwareComponent[] SOFTWARE_COMPONENTS = new SoftwareComponent[]{
new SoftwareComponent("Giga Get", "2014", "Peter Cai", "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL2),
new SoftwareComponent("NewPipe Extractor", "2017", "Christian Schabesberger", "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3),
new SoftwareComponent("Jsoup", "2017", "Jonathan Hedley", "https://github.com/jhy/jsoup", StandardLicenses.MIT),
new SoftwareComponent("Google Gson", "2008", "Google Inc", "https://github.com/google/gson", StandardLicenses.APACHE2),
new SoftwareComponent("Rhino", "2015", "Mozilla", "https://www.mozilla.org/rhino/", StandardLicenses.MPL2),
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),
new SoftwareComponent("Netcipher", "2015", "The Guardian Project", "https://guardianproject.info/code/netcipher/", StandardLicenses.APACHE2),
new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
new SoftwareComponent("ParalaxScrollView", "2014", "Nir Hartmann", "https://github.com/nirhart/ParallaxScroll", StandardLicenses.MIT),
new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2)
};
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeHelper.setTheme(this);
setContentView(R.layout.activity_about);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_about, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
finish();
return true;
case R.id.action_settings:
NavigationHelper.openSettings(this);
return true;
case R.id.action_show_downloads:
return NavigationHelper.openDownloads(this);
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class AboutFragment extends Fragment {
public AboutFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static AboutFragment newInstance() {
return new AboutFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_about, container, false);
TextView version = (TextView) rootView.findViewById(R.id.app_version);
version.setText(BuildConfig.VERSION_NAME);
View githubLink = rootView.findViewById(R.id.github_link);
githubLink.setOnClickListener(new OnGithubLinkClickListener());
View licenseLink = rootView.findViewById(R.id.app_read_license);
licenseLink.setOnClickListener(new OnReadFullLicenseClickListener());
return rootView;
}
private static class OnGithubLinkClickListener implements View.OnClickListener {
@Override
public void onClick(final View view) {
final Context context = view.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.github_url)));
context.startActivity(intent);
}
}
private static class OnReadFullLicenseClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
LicenseFragment.showLicense(v.getContext(), StandardLicenses.GPL3);
}
}
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return AboutFragment.newInstance();
case 1:
return LicenseFragment.newInstance(SOFTWARE_COMPONENTS);
}
return null;
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.tab_about);
case 1:
return getString(R.string.tab_licenses);
}
return null;
}
}
}

View File

@@ -0,0 +1,72 @@
package org.schabi.newpipe.about;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.net.URLEncoder;
/**
* A software license
*/
public class License implements Parcelable {
public static final Creator<License> CREATOR = new Creator<License>() {
@Override
public License createFromParcel(Parcel source) {
return new License(source);
}
@Override
public License[] newArray(int size) {
return new License[size];
}
};
private final String abbreviation;
private final String name;
private String filename;
public License(String name, String abbreviation, String filename) {
if(name == null) throw new NullPointerException("name is null");
if(abbreviation == null) throw new NullPointerException("abbreviation is null");
if(filename == null) throw new NullPointerException("filename is null");
this.name = name;
this.filename = filename;
this.abbreviation = abbreviation;
}
protected License(Parcel in) {
this.filename = in.readString();
this.abbreviation = in.readString();
this.name = in.readString();
}
public Uri getContentUri() {
return new Uri.Builder()
.scheme("file")
.path("/android_asset")
.appendPath(filename)
.build();
}
public String getAbbreviation() {
return abbreviation;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.filename);
dest.writeString(this.abbreviation);
dest.writeString(this.name);
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,150 @@
package org.schabi.newpipe.about;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.TextView;
import org.schabi.newpipe.R;
import java.util.Arrays;
import java.util.Comparator;
/**
* Fragment containing the software licenses
*/
public class LicenseFragment extends Fragment {
private static final String ARG_COMPONENTS = "components";
private SoftwareComponent[] softwareComponents;
private SoftwareComponent mComponentForContextMenu;
public static LicenseFragment newInstance(SoftwareComponent[] softwareComponents) {
if(softwareComponents == null) {
throw new NullPointerException("softwareComponents is null");
}
LicenseFragment fragment = new LicenseFragment();
Bundle bundle = new Bundle();
bundle.putParcelableArray(ARG_COMPONENTS, softwareComponents);
fragment.setArguments(bundle);
return fragment;
}
/**
* Shows a popup containing the license
* @param context the context to use
* @param license the license to show
*/
public static void showLicense(Context context, License license) {
if(context == null) {
throw new NullPointerException("context is null");
}
if(license == null) {
throw new NullPointerException("license is null");
}
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle(license.getName());
WebView wv = new WebView(context);
wv.loadUrl(license.getContentUri().toString());
alert.setView(wv);
alert.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
softwareComponents = (SoftwareComponent[]) getArguments().getParcelableArray(ARG_COMPONENTS);
// Sort components by name
Arrays.sort(softwareComponents, new Comparator<SoftwareComponent>() {
@Override
public int compare(SoftwareComponent o1, SoftwareComponent o2) {
return o1.getName().compareTo(o2.getName());
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_licenses, container, false);
ViewGroup softwareComponentsView = (ViewGroup) rootView.findViewById(R.id.software_components);
for (final SoftwareComponent component : softwareComponents) {
View componentView = inflater.inflate(R.layout.item_software_component, container, false);
TextView softwareName = (TextView) componentView.findViewById(R.id.name);
TextView copyright = (TextView) componentView.findViewById(R.id.copyright);
softwareName.setText(component.getName());
copyright.setText(getContext().getString(R.string.copyright,
component.getYears(),
component.getCopyrightOwner(),
component.getLicense().getAbbreviation()));
componentView.setTag(component);
componentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
if (context != null) {
showLicense(context, component.getLicense());
}
}
});
softwareComponentsView.addView(componentView);
registerForContextMenu(componentView);
}
return rootView;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getActivity().getMenuInflater();
SoftwareComponent component = (SoftwareComponent) v.getTag();
menu.setHeaderTitle(component.getName());
inflater.inflate(R.menu.software_component, menu);
super.onCreateContextMenu(menu, v, menuInfo);
mComponentForContextMenu = (SoftwareComponent) v.getTag();
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// item.getMenuInfo() is null so we use the tag of the view
final SoftwareComponent component = mComponentForContextMenu;
if (component == null) {
return false;
}
switch (item.getItemId()) {
case R.id.action_website:
openWebsite(component.getLink());
return true;
case R.id.action_show_license:
showLicense(getContext(), component.getLicense());
}
return false;
}
private void openWebsite(String componentLink) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(componentLink));
startActivity(browserIntent);
}
}

View File

@@ -0,0 +1,83 @@
package org.schabi.newpipe.about;
import android.os.Parcel;
import android.os.Parcelable;
public class SoftwareComponent implements Parcelable {
public static final Creator<SoftwareComponent> CREATOR = new Creator<SoftwareComponent>() {
@Override
public SoftwareComponent createFromParcel(Parcel source) {
return new SoftwareComponent(source);
}
@Override
public SoftwareComponent[] newArray(int size) {
return new SoftwareComponent[size];
}
};
public String getName() {
return name;
}
public String getYears() {
return years;
}
public String getCopyrightOwner() {
return copyrightOwner;
}
public String getLink() {
return link;
}
public String getVersion() {
return version;
}
private final License license;
private final String name;
private final String years;
private final String copyrightOwner;
private final String link;
private final String version;
public SoftwareComponent(String name, String years, String copyrightOwner, String link, License license) {
this.name = name;
this.years = years;
this.copyrightOwner = copyrightOwner;
this.link = link;
this.license = license;
this.version = null;
}
protected SoftwareComponent(Parcel in) {
this.name = in.readString();
this.license = in.readParcelable(License.class.getClassLoader());
this.copyrightOwner = in.readString();
this.link = in.readString();
this.years = in.readString();
this.version = in.readString();
}
public License getLicense() {
return license;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeParcelable(license, flags);
dest.writeString(copyrightOwner);
dest.writeString(link);
dest.writeString(years);
dest.writeString(version);
}
}

View File

@@ -0,0 +1,12 @@
package org.schabi.newpipe.about;
/**
* Standard software licenses
*/
public final class StandardLicenses {
public static final License GPL2 = new License("GNU General Public License, Version 2.0", "GPLv2", "gpl_2.html");
public static final License GPL3 = new License("GNU General Public License, Version 3.0", "GPLv3", "gpl_3.html");
public static final License APACHE2 = new License("Apache License, Version 2.0", "ALv2", "apache2.html");
public static final License MPL2 = new License("Mozilla Public License, Version 2.0", "MPL 2.0", "mpl2.html");
public static final License MIT = new License("MIT License", "MIT", "mit.html");
}

View File

@@ -1,15 +1,19 @@
package org.schabi.newpipe.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.support.annotation.CheckResult;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import com.nostra13.universalimageloader.core.ImageLoader;
import org.schabi.newpipe.about.AboutActivity;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.download.DownloadActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.stream_info.AudioStream;
@@ -21,6 +25,7 @@ import org.schabi.newpipe.fragments.search.SearchFragment;
import org.schabi.newpipe.player.BackgroundPlayer;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.player.VideoPlayer;
import org.schabi.newpipe.settings.SettingsActivity;
@SuppressWarnings({"unused", "WeakerAccess"})
public class NavigationHelper {
@@ -204,4 +209,23 @@ public class NavigationHelper {
}
return null;
}
public static void openAbout(Context context) {
Intent intent = new Intent(context, AboutActivity.class);
context.startActivity(intent);
}
public static void openSettings(Context context) {
Intent intent = new Intent(context, SettingsActivity.class);
context.startActivity(intent);
}
public static boolean openDownloads(Activity activity) {
if (!PermissionHelper.checkStoragePermissions(activity)) {
return false;
}
Intent intent = new Intent(activity, DownloadActivity.class);
activity.startActivity(intent);
return true;
}
}