mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Improve backstack and theme change
This commit is contained in:
		| @@ -1,12 +1,13 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest | ||||||
|  |     xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     xmlns:tools="http://schemas.android.com/tools" |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|     package="org.schabi.newpipe"> |     package="org.schabi.newpipe"> | ||||||
|  |  | ||||||
|     <uses-permission android:name="android.permission.INTERNET" /> |     <uses-permission android:name="android.permission.INTERNET"/> | ||||||
|     <uses-permission android:name="android.permission.WAKE_LOCK" /> |     <uses-permission android:name="android.permission.WAKE_LOCK"/> | ||||||
|     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> | ||||||
|     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | ||||||
|     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> |     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> | ||||||
|  |  | ||||||
|     <application |     <application | ||||||
| @@ -19,12 +20,10 @@ | |||||||
|         tools:ignore="AllowBackup"> |         tools:ignore="AllowBackup"> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".MainActivity" |             android:name=".MainActivity" | ||||||
|             android:label="@string/app_name" |             android:label="@string/app_name"> | ||||||
|             android:launchMode="singleTask"> |  | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.MAIN" /> |                 <action android:name="android.intent.action.MAIN"/> | ||||||
|  |                 <category android:name="android.intent.category.LAUNCHER"/> | ||||||
|                 <category android:name="android.intent.category.LAUNCHER" /> |  | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|  |  | ||||||
| @@ -32,12 +31,16 @@ | |||||||
|             android:name=".player.PlayVideoActivity" |             android:name=".player.PlayVideoActivity" | ||||||
|             android:configChanges="orientation|keyboardHidden|screenSize" |             android:configChanges="orientation|keyboardHidden|screenSize" | ||||||
|             android:theme="@style/VideoPlayerTheme" |             android:theme="@style/VideoPlayerTheme" | ||||||
|             tools:ignore="UnusedAttribute" /> |             tools:ignore="UnusedAttribute"/> | ||||||
|  |  | ||||||
|         <service |         <service | ||||||
|             android:name=".player.BackgroundPlayer" |             android:name=".player.BackgroundPlayer" | ||||||
|             android:exported="false"/> |             android:exported="false"/> | ||||||
|  |  | ||||||
|  |         <service | ||||||
|  |             android:name=".player.PopupVideoPlayer" | ||||||
|  |             android:exported="false"/> | ||||||
|  |  | ||||||
|         <activity |         <activity | ||||||
|             android:name=".player.MainVideoPlayer" |             android:name=".player.MainVideoPlayer" | ||||||
|             android:configChanges="keyboard|keyboardHidden|orientation|screenSize" |             android:configChanges="keyboard|keyboardHidden|orientation|screenSize" | ||||||
| @@ -47,32 +50,32 @@ | |||||||
|  |  | ||||||
|         <activity |         <activity | ||||||
|             android:name=".settings.SettingsActivity" |             android:name=".settings.SettingsActivity" | ||||||
|             android:label="@string/settings" /> |             android:label="@string/settings"/> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".PanicResponderActivity" |             android:name=".PanicResponderActivity" | ||||||
|             android:launchMode="singleInstance" |             android:launchMode="singleInstance" | ||||||
|             android:noHistory="true" |             android:noHistory="true" | ||||||
|             android:theme="@android:style/Theme.NoDisplay"> |             android:theme="@android:style/Theme.NoDisplay"> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="info.guardianproject.panic.action.TRIGGER" /> |                 <action android:name="info.guardianproject.panic.action.TRIGGER"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".ExitActivity" |             android:name=".ExitActivity" | ||||||
|             android:label="@string/general_error" |             android:label="@string/general_error" | ||||||
|             android:theme="@android:style/Theme.NoDisplay" /> |             android:theme="@android:style/Theme.NoDisplay"/> | ||||||
|         <activity android:name=".report.ErrorActivity" /> |         <activity android:name=".report.ErrorActivity"/> | ||||||
|  |  | ||||||
|         <!-- giga get related --> |         <!-- giga get related --> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".download.DownloadActivity" |             android:name=".download.DownloadActivity" | ||||||
|             android:label="@string/app_name" |             android:label="@string/app_name" | ||||||
|             android:launchMode="singleTask" |             android:launchMode="singleTask" | ||||||
|             android:theme="@style/AppTheme" /> |             android:theme="@style/AppTheme"/> | ||||||
|  |  | ||||||
|         <service android:name="us.shandian.giga.service.DownloadManagerService" /> |         <service android:name="us.shandian.giga.service.DownloadManagerService"/> | ||||||
|  |  | ||||||
|         <activity |         <activity | ||||||
|             android:name="com.nononsenseapps.filepicker.FilePickerActivity" |             android:name="com.nononsenseapps.filepicker.FilePickerActivity" | ||||||
| @@ -81,7 +84,7 @@ | |||||||
|             android:theme="@style/FilePickerTheme"/> |             android:theme="@style/FilePickerTheme"/> | ||||||
|         <activity |         <activity | ||||||
|             android:name=".ReCaptchaActivity" |             android:name=".ReCaptchaActivity" | ||||||
|             android:label="@string/reCaptchaActivity" /> |             android:label="@string/reCaptchaActivity"/> | ||||||
|  |  | ||||||
|         <provider |         <provider | ||||||
|             android:name="android.support.v4.content.FileProvider" |             android:name="android.support.v4.content.FileProvider" | ||||||
| @@ -90,7 +93,7 @@ | |||||||
|             android:grantUriPermissions="true"> |             android:grantUriPermissions="true"> | ||||||
|             <meta-data |             <meta-data | ||||||
|                 android:name="android.support.FILE_PROVIDER_PATHS" |                 android:name="android.support.FILE_PROVIDER_PATHS" | ||||||
|                 android:resource="@xml/provider_paths" /> |                 android:resource="@xml/provider_paths"/> | ||||||
|         </provider> |         </provider> | ||||||
|  |  | ||||||
|         <activity |         <activity | ||||||
| @@ -98,57 +101,57 @@ | |||||||
|             android:taskAffinity="" |             android:taskAffinity="" | ||||||
|             android:theme="@android:style/Theme.NoDisplay"> |             android:theme="@android:style/Theme.NoDisplay"> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="http" /> |                 <data android:scheme="http"/> | ||||||
|                 <data android:scheme="https" /> |                 <data android:scheme="https"/> | ||||||
|                 <data android:host="youtube.com" /> |                 <data android:host="youtube.com"/> | ||||||
|                 <data android:host="m.youtube.com" /> |                 <data android:host="m.youtube.com"/> | ||||||
|                 <data android:host="www.youtube.com" /> |                 <data android:host="www.youtube.com"/> | ||||||
|                 <!-- video prefix --> |                 <!-- video prefix --> | ||||||
|                 <data android:pathPrefix="/v/" /> |                 <data android:pathPrefix="/v/"/> | ||||||
|                 <data android:pathPrefix="/embed/" /> |                 <data android:pathPrefix="/embed/"/> | ||||||
|                 <data android:pathPrefix="/watch" /> |                 <data android:pathPrefix="/watch"/> | ||||||
|                 <data android:pathPrefix="/attribution_link" /> |                 <data android:pathPrefix="/attribution_link"/> | ||||||
|                 <!-- channel prefix --> |                 <!-- channel prefix --> | ||||||
|                 <data android:pathPrefix="/channel/"/> |                 <data android:pathPrefix="/channel/"/> | ||||||
|                 <data android:pathPrefix="/user/"/> |                 <data android:pathPrefix="/user/"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="http" /> |                 <data android:scheme="http"/> | ||||||
|                 <data android:scheme="https" /> |                 <data android:scheme="https"/> | ||||||
|                 <data android:host="youtu.be" /> |                 <data android:host="youtu.be"/> | ||||||
|                 <data android:pathPrefix="/" /> |                 <data android:pathPrefix="/"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="vnd.youtube" /> |                 <data android:scheme="vnd.youtube"/> | ||||||
|                 <data android:scheme="vnd.youtube.launch" /> |                 <data android:scheme="vnd.youtube.launch"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.SEND" /> |                 <action android:name="android.intent.action.SEND"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|  |  | ||||||
|                 <data android:mimeType="text/plain" /> |                 <data android:mimeType="text/plain"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|  |  | ||||||
| @@ -158,57 +161,55 @@ | |||||||
|             android:theme="@android:style/Theme.NoDisplay" |             android:theme="@android:style/Theme.NoDisplay" | ||||||
|             android:label="@string/popup_mode_share_menu_title"> |             android:label="@string/popup_mode_share_menu_title"> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="http" /> |                 <data android:scheme="http"/> | ||||||
|                 <data android:scheme="https" /> |                 <data android:scheme="https"/> | ||||||
|                 <data android:host="youtube.com" /> |                 <data android:host="youtube.com"/> | ||||||
|                 <data android:host="m.youtube.com" /> |                 <data android:host="m.youtube.com"/> | ||||||
|                 <data android:host="www.youtube.com" /> |                 <data android:host="www.youtube.com"/> | ||||||
|                 <!-- video prefix --> |                 <!-- video prefix --> | ||||||
|                 <data android:pathPrefix="/v/" /> |                 <data android:pathPrefix="/v/"/> | ||||||
|                 <data android:pathPrefix="/embed/" /> |                 <data android:pathPrefix="/embed/"/> | ||||||
|                 <data android:pathPrefix="/watch" /> |                 <data android:pathPrefix="/watch"/> | ||||||
|                 <data android:pathPrefix="/attribution_link" /> |                 <data android:pathPrefix="/attribution_link"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="http" /> |                 <data android:scheme="http"/> | ||||||
|                 <data android:scheme="https" /> |                 <data android:scheme="https"/> | ||||||
|                 <data android:host="youtu.be" /> |                 <data android:host="youtu.be"/> | ||||||
|                 <data android:pathPrefix="/" /> |                 <data android:pathPrefix="/"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.VIEW" /> |                 <action android:name="android.intent.action.VIEW"/> | ||||||
|                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> |                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/> | ||||||
|                 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> |                 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE"/> | ||||||
|  |  | ||||||
|                 <data android:scheme="vnd.youtube" /> |                 <data android:scheme="vnd.youtube"/> | ||||||
|                 <data android:scheme="vnd.youtube.launch" /> |                 <data android:scheme="vnd.youtube.launch"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.SEND" /> |                 <action android:name="android.intent.action.SEND"/> | ||||||
|                 <category android:name="android.intent.category.DEFAULT" /> |                 <category android:name="android.intent.category.DEFAULT"/> | ||||||
|                 <data android:mimeType="text/plain" /> |                 <data android:mimeType="text/plain"/> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|  |  | ||||||
|         <service android:name=".player.PopupVideoPlayer"/> |  | ||||||
|  |  | ||||||
|     </application> |     </application> | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
|   | |||||||
| @@ -21,7 +21,9 @@ | |||||||
| package org.schabi.newpipe; | package org.schabi.newpipe; | ||||||
|  |  | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
|  | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
|  | import android.preference.PreferenceManager; | ||||||
| import android.support.v4.app.Fragment; | import android.support.v4.app.Fragment; | ||||||
| import android.support.v4.app.FragmentManager; | import android.support.v4.app.FragmentManager; | ||||||
| import android.support.v7.app.ActionBar; | import android.support.v7.app.ActionBar; | ||||||
| @@ -33,13 +35,9 @@ import android.view.MenuInflater; | |||||||
| import android.view.MenuItem; | import android.view.MenuItem; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  |  | ||||||
| import com.nostra13.universalimageloader.core.ImageLoader; |  | ||||||
|  |  | ||||||
| import org.schabi.newpipe.download.DownloadActivity; | import org.schabi.newpipe.download.DownloadActivity; | ||||||
| import org.schabi.newpipe.extractor.StreamingService; | import org.schabi.newpipe.extractor.StreamingService; | ||||||
| import org.schabi.newpipe.fragments.MainFragment; | import org.schabi.newpipe.fragments.MainFragment; | ||||||
| import org.schabi.newpipe.fragments.OnItemSelectedListener; |  | ||||||
| import org.schabi.newpipe.fragments.channel.ChannelFragment; |  | ||||||
| import org.schabi.newpipe.fragments.detail.VideoDetailFragment; | import org.schabi.newpipe.fragments.detail.VideoDetailFragment; | ||||||
| import org.schabi.newpipe.fragments.search.SearchFragment; | import org.schabi.newpipe.fragments.search.SearchFragment; | ||||||
| import org.schabi.newpipe.settings.SettingsActivity; | import org.schabi.newpipe.settings.SettingsActivity; | ||||||
| @@ -48,7 +46,7 @@ import org.schabi.newpipe.util.NavigationHelper; | |||||||
| import org.schabi.newpipe.util.PermissionHelper; | import org.schabi.newpipe.util.PermissionHelper; | ||||||
| import org.schabi.newpipe.util.ThemeHelper; | import org.schabi.newpipe.util.ThemeHelper; | ||||||
|  |  | ||||||
| public class MainActivity extends AppCompatActivity implements OnItemSelectedListener { | public class MainActivity extends AppCompatActivity { | ||||||
|     private static final String TAG = "MainActivity"; |     private static final String TAG = "MainActivity"; | ||||||
|     public static final boolean DEBUG = false; |     public static final boolean DEBUG = false; | ||||||
|  |  | ||||||
| @@ -71,6 +69,19 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis | |||||||
|         setSupportActionBar(toolbar); |         setSupportActionBar(toolbar); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected void onResume() { | ||||||
|  |         super.onResume(); | ||||||
|  |  | ||||||
|  |         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); | ||||||
|  |         if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) { | ||||||
|  |             if (DEBUG) Log.d(TAG, "Theme has changed, recreating activity..."); | ||||||
|  |             sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply(); | ||||||
|  |             this.recreate(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected void onNewIntent(Intent intent) { |     protected void onNewIntent(Intent intent) { | ||||||
|         if (DEBUG) Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]"); |         if (DEBUG) Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]"); | ||||||
| @@ -89,10 +100,16 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis | |||||||
|     @Override |     @Override | ||||||
|     public void onBackPressed() { |     public void onBackPressed() { | ||||||
|         if (DEBUG) Log.d(TAG, "onBackPressed() called"); |         if (DEBUG) Log.d(TAG, "onBackPressed() called"); | ||||||
|  |  | ||||||
|         Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); |         Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); | ||||||
|         if (fragment instanceof VideoDetailFragment) if (((VideoDetailFragment) fragment).onActivityBackPressed()) return; |         if (fragment instanceof VideoDetailFragment) if (((VideoDetailFragment) fragment).onActivityBackPressed()) return; | ||||||
|  |  | ||||||
|         super.onBackPressed(); |         super.onBackPressed(); | ||||||
|  |  | ||||||
|  |         fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); | ||||||
|  |         if (getSupportFragmentManager().getBackStackEntryCount() == 0 && !(fragment instanceof MainFragment)) { | ||||||
|  |             super.onBackPressed(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /*////////////////////////////////////////////////////////////////////////// |     /*////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -134,7 +151,8 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis | |||||||
|                 Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); |                 Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); | ||||||
|                 if (fragment instanceof VideoDetailFragment) ((VideoDetailFragment) fragment).clearHistory(); |                 if (fragment instanceof VideoDetailFragment) ((VideoDetailFragment) fragment).clearHistory(); | ||||||
|  |  | ||||||
|                 NavigationHelper.openMainActivity(this); |                 getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); | ||||||
|  |                 NavigationHelper.openMainFragment(getSupportFragmentManager()); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|             case R.id.action_settings: { |             case R.id.action_settings: { | ||||||
| @@ -160,26 +178,9 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis | |||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     private void initFragments() { |     private void initFragments() { | ||||||
|         openMainFragment(); |  | ||||||
|         if (getIntent() != null && getIntent().hasExtra(Constants.KEY_URL)) { |         if (getIntent() != null && getIntent().hasExtra(Constants.KEY_URL)) { | ||||||
|             handleIntent(getIntent()); |             handleIntent(getIntent()); | ||||||
|         } |         } else NavigationHelper.openMainFragment(getSupportFragmentManager()); | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /*////////////////////////////////////////////////////////////////////////// |  | ||||||
|     // OnItemSelectedListener |  | ||||||
|     //////////////////////////////////////////////////////////////////////////*/ |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onItemSelected(StreamingService.LinkType linkType, int serviceId, String url, String name) { |  | ||||||
|         switch (linkType) { |  | ||||||
|             case STREAM: |  | ||||||
|                 openVideoDetailFragment(serviceId, url, name, false); |  | ||||||
|                 break; |  | ||||||
|             case CHANNEL: |  | ||||||
|                 openChannelFragment(serviceId, url, name); |  | ||||||
|                 break; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /*////////////////////////////////////////////////////////////////////////// |     /*////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -187,96 +188,32 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis | |||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     private void handleIntent(Intent intent) { |     private void handleIntent(Intent intent) { | ||||||
|         if (intent.hasExtra(Constants.KEY_THEME_CHANGE) && intent.getBooleanExtra(Constants.KEY_THEME_CHANGE, false)) { |         if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]"); | ||||||
|             this.recreate(); |         if (intent.getBooleanExtra(Constants.KEY_THEME_CHANGE, false)) { | ||||||
|             Intent setI = new Intent(this, SettingsActivity.class); |  | ||||||
|             startActivity(setI); |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (intent.hasExtra(Constants.KEY_LINK_TYPE)) { |         if (intent.hasExtra(Constants.KEY_LINK_TYPE)) { | ||||||
|             String url = intent.getStringExtra(Constants.KEY_URL); |             String url = intent.getStringExtra(Constants.KEY_URL); | ||||||
|             int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0); |             int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0); | ||||||
|             try { |             String title = intent.getStringExtra(Constants.KEY_TITLE); | ||||||
|                 switch (((StreamingService.LinkType) intent.getSerializableExtra(Constants.KEY_LINK_TYPE))) { |             switch (((StreamingService.LinkType) intent.getSerializableExtra(Constants.KEY_LINK_TYPE))) { | ||||||
|                     case STREAM: |                 case STREAM: | ||||||
|                         handleVideoDetailIntent(serviceId, url, intent); |                     boolean autoPlay = intent.getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false); | ||||||
|                         break; |                     NavigationHelper.openVideoDetailFragment(getSupportFragmentManager(), serviceId, url, title, autoPlay); | ||||||
|                     case CHANNEL: |                     break; | ||||||
|                         handleChannelIntent(serviceId, url, intent); |                 case CHANNEL: | ||||||
|                         break; |                     NavigationHelper.openChannelFragment(getSupportFragmentManager(), serviceId, url, title); | ||||||
|                     case NONE: |                     break; | ||||||
|                         throw new Exception("Url not known to service. service=" + Integer.toString(serviceId) + " url=" + url); |  | ||||||
|                 } |  | ||||||
|             } catch (Exception e) { |  | ||||||
|                 e.printStackTrace(); |  | ||||||
|             } |             } | ||||||
|         } else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) { |         } else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) { | ||||||
|             String searchQuery = intent.getStringExtra(Constants.KEY_QUERY); |             String searchQuery = intent.getStringExtra(Constants.KEY_QUERY); | ||||||
|             if (searchQuery == null) searchQuery = ""; |             if (searchQuery == null) searchQuery = ""; | ||||||
|             int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0); |             int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0); | ||||||
|             openSearchFragment(serviceId, searchQuery); |             NavigationHelper.openSearchFragment(getSupportFragmentManager(), serviceId, searchQuery); | ||||||
|         } else { |         } else { | ||||||
|             getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); |             getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); | ||||||
|             openMainFragment();//openSearchFragment(); |             NavigationHelper.openMainFragment(getSupportFragmentManager()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void openMainFragment() { |  | ||||||
|         ImageLoader.getInstance().clearMemoryCache(); |  | ||||||
|         getSupportFragmentManager().beginTransaction() |  | ||||||
|                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) |  | ||||||
|                 .replace(R.id.fragment_holder, new MainFragment()) |  | ||||||
|                 .commit(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void openSearchFragment(int serviceId, String query) { |  | ||||||
|         getSupportFragmentManager().beginTransaction() |  | ||||||
|                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) |  | ||||||
|                 .replace(R.id.fragment_holder, SearchFragment.getInstance(serviceId, query)) |  | ||||||
|                 .addToBackStack(null) |  | ||||||
|                 .commit(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void openVideoDetailFragment(int serviceId, String url, String title, boolean autoPlay) { |  | ||||||
|         Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); |  | ||||||
|         if (title == null) title = ""; |  | ||||||
|  |  | ||||||
|         if (fragment instanceof VideoDetailFragment && fragment.isVisible()) { |  | ||||||
|             VideoDetailFragment detailFragment = (VideoDetailFragment) fragment; |  | ||||||
|             detailFragment.setAutoplay(autoPlay); |  | ||||||
|             detailFragment.selectAndLoadVideo(serviceId, url, title); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         VideoDetailFragment instance = VideoDetailFragment.getInstance(serviceId, url, title); |  | ||||||
|         instance.setAutoplay(autoPlay); |  | ||||||
|  |  | ||||||
|         getSupportFragmentManager().beginTransaction() |  | ||||||
|                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) |  | ||||||
|                 .replace(R.id.fragment_holder, instance) |  | ||||||
|                 .addToBackStack(null) |  | ||||||
|                 .commit(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void openChannelFragment(int serviceId, String url, String name) { |  | ||||||
|         if (name == null) name = ""; |  | ||||||
|         getSupportFragmentManager().beginTransaction() |  | ||||||
|                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) |  | ||||||
|                 .replace(R.id.fragment_holder, ChannelFragment.getInstance(serviceId, url, name)) |  | ||||||
|                 .addToBackStack(null) |  | ||||||
|                 .commit(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void handleVideoDetailIntent(int serviceId, String url, Intent intent) { |  | ||||||
|         boolean autoPlay = intent.getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false); |  | ||||||
|         String title = intent.getStringExtra(Constants.KEY_TITLE); |  | ||||||
|         openVideoDetailFragment(serviceId, url, title, autoPlay); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void handleChannelIntent(int serviceId, String url, Intent intent) { |  | ||||||
|         String name = intent.getStringExtra(Constants.KEY_TITLE); |  | ||||||
|         openChannelFragment(serviceId, url, name); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,26 +33,39 @@ import java.util.HashSet; | |||||||
|  * to the part of the service which can handle the url. |  * to the part of the service which can handle the url. | ||||||
|  */ |  */ | ||||||
| public class RouterActivity extends Activity { | public class RouterActivity extends Activity { | ||||||
|     //private static final String TAG = "RouterActivity" |  | ||||||
|  |     @Override | ||||||
|  |     protected void onCreate(Bundle savedInstanceState) { | ||||||
|  |         super.onCreate(savedInstanceState); | ||||||
|  |  | ||||||
|  |         String videoUrl = getUrl(getIntent()); | ||||||
|  |         handleUrl(videoUrl); | ||||||
|  |  | ||||||
|  |         finish(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected void handleUrl(String url) { | ||||||
|  |         try { | ||||||
|  |             NavigationHelper.openByLink(this, url); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /*////////////////////////////////////////////////////////////////////////// | ||||||
|  |     // Utils | ||||||
|  |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Removes invisible separators (\p{Z}) and punctuation characters including |      * Removes invisible separators (\p{Z}) and punctuation characters including | ||||||
|      * brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for |      * brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for | ||||||
|      * more details. |      * more details. | ||||||
|      */ |      */ | ||||||
|     private final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]"; |     protected final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]"; | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected void onCreate(Bundle savedInstanceState) { |  | ||||||
|         super.onCreate(savedInstanceState); |  | ||||||
|         handleIntent(getIntent()); |  | ||||||
|         finish(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void handleIntent(Intent intent) { |  | ||||||
|         String videoUrl = ""; |  | ||||||
|  |  | ||||||
|  |     protected String getUrl(Intent intent) { | ||||||
|         // first gather data and find service |         // first gather data and find service | ||||||
|  |         String videoUrl = null; | ||||||
|         if (intent.getData() != null) { |         if (intent.getData() != null) { | ||||||
|             // this means the video was called though another app |             // this means the video was called though another app | ||||||
|             videoUrl = intent.getData().toString(); |             videoUrl = intent.getData().toString(); | ||||||
| @@ -62,14 +75,10 @@ public class RouterActivity extends Activity { | |||||||
|             videoUrl = getUris(extraText)[0]; |             videoUrl = getUris(extraText)[0]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         try { |         return videoUrl; | ||||||
|             NavigationHelper.openByLink(this, videoUrl); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static String removeHeadingGibberish(final String input) { |     protected String removeHeadingGibberish(final String input) { | ||||||
|         int start = 0; |         int start = 0; | ||||||
|         for (int i = input.indexOf("://") - 1; i >= 0; i--) { |         for (int i = input.indexOf("://") - 1; i >= 0; i--) { | ||||||
|             if (!input.substring(i, i + 1).matches("\\p{L}")) { |             if (!input.substring(i, i + 1).matches("\\p{L}")) { | ||||||
| @@ -80,7 +89,7 @@ public class RouterActivity extends Activity { | |||||||
|         return input.substring(start, input.length()); |         return input.substring(start, input.length()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static String trim(final String input) { |     protected String trim(final String input) { | ||||||
|         if (input == null || input.length() < 1) { |         if (input == null || input.length() < 1) { | ||||||
|             return input; |             return input; | ||||||
|         } else { |         } else { | ||||||
| @@ -103,7 +112,7 @@ public class RouterActivity extends Activity { | |||||||
|      * @param sharedText text to scan for URLs. |      * @param sharedText text to scan for URLs. | ||||||
|      * @return potential URLs |      * @return potential URLs | ||||||
|      */ |      */ | ||||||
|     private String[] getUris(final String sharedText) { |     protected String[] getUris(final String sharedText)  { | ||||||
|         final Collection<String> result = new HashSet<>(); |         final Collection<String> result = new HashSet<>(); | ||||||
|         if (sharedText != null) { |         if (sharedText != null) { | ||||||
|             final String[] array = sharedText.split("\\p{Space}"); |             final String[] array = sharedText.split("\\p{Space}"); | ||||||
|   | |||||||
| @@ -1,9 +1,7 @@ | |||||||
| package org.schabi.newpipe; | package org.schabi.newpipe; | ||||||
|  |  | ||||||
| import android.app.Activity; |  | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.os.Bundle; |  | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.extractor.NewPipe; | import org.schabi.newpipe.extractor.NewPipe; | ||||||
| @@ -12,57 +10,26 @@ import org.schabi.newpipe.player.PopupVideoPlayer; | |||||||
| import org.schabi.newpipe.util.Constants; | import org.schabi.newpipe.util.Constants; | ||||||
| import org.schabi.newpipe.util.PermissionHelper; | import org.schabi.newpipe.util.PermissionHelper; | ||||||
|  |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashSet; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * This activity is thought to open video streams form an external app using the popup player. |  * Get the url from the intent and open a popup player | ||||||
|  */ |  */ | ||||||
| public class RouterPopupActivity extends Activity { | public class RouterPopupActivity extends RouterActivity { | ||||||
|     //private static final String TAG = "RouterPopupActivity"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Removes invisible separators (\p{Z}) and punctuation characters including |  | ||||||
|      * brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for |  | ||||||
|      * more details. |  | ||||||
|      */ |  | ||||||
|     private final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]"; |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected void onCreate(Bundle savedInstanceState) { |     protected void handleUrl(String url) { | ||||||
|         super.onCreate(savedInstanceState); |  | ||||||
|         handleIntent(getIntent()); |  | ||||||
|         finish(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     private void handleIntent(Intent intent) { |  | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M | ||||||
|                 && !PermissionHelper.checkSystemAlertWindowPermission(this)) { |                 && !PermissionHelper.checkSystemAlertWindowPermission(this)) { | ||||||
|             Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); |             Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         String videoUrl = ""; |         StreamingService service = NewPipe.getServiceByUrl(url); | ||||||
|         StreamingService service; |  | ||||||
|  |  | ||||||
|         // first gather data and find service |  | ||||||
|         if (intent.getData() != null) { |  | ||||||
|             // this means the video was called though another app |  | ||||||
|             videoUrl = intent.getData().toString(); |  | ||||||
|         } else if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) { |  | ||||||
|             //this means that vidoe was called through share menu |  | ||||||
|             String extraText = intent.getStringExtra(Intent.EXTRA_TEXT); |  | ||||||
|             videoUrl = getUris(extraText)[0]; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         service = NewPipe.getServiceByUrl(videoUrl); |  | ||||||
|         if (service == null) { |         if (service == null) { | ||||||
|             Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show(); |             Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Intent callIntent = new Intent(this, PopupVideoPlayer.class); |         Intent callIntent = new Intent(this, PopupVideoPlayer.class); | ||||||
|         switch (service.getLinkTypeByUrl(videoUrl)) { |         switch (service.getLinkTypeByUrl(url)) { | ||||||
|             case STREAM: |             case STREAM: | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
| @@ -70,61 +37,8 @@ public class RouterPopupActivity extends Activity { | |||||||
|                 return; |                 return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         callIntent.putExtra(Constants.KEY_URL, videoUrl); |         callIntent.putExtra(Constants.KEY_URL, url); | ||||||
|         callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId()); |         callIntent.putExtra(Constants.KEY_SERVICE_ID, service.getServiceId()); | ||||||
|         startService(callIntent); |         startService(callIntent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static String removeHeadingGibberish(final String input) { |  | ||||||
|         int start = 0; |  | ||||||
|         for (int i = input.indexOf("://") - 1; i >= 0; i--) { |  | ||||||
|             if (!input.substring(i, i + 1).matches("\\p{L}")) { |  | ||||||
|                 start = i + 1; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return input.substring(start, input.length()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static String trim(final String input) { |  | ||||||
|         if (input == null || input.length() < 1) { |  | ||||||
|             return input; |  | ||||||
|         } else { |  | ||||||
|             String output = input; |  | ||||||
|             while (output.length() > 0 && output.substring(0, 1).matches(REGEX_REMOVE_FROM_URL)) { |  | ||||||
|                 output = output.substring(1); |  | ||||||
|             } |  | ||||||
|             while (output.length() > 0 |  | ||||||
|                     && output.substring(output.length() - 1, output.length()).matches(REGEX_REMOVE_FROM_URL)) { |  | ||||||
|                 output = output.substring(0, output.length() - 1); |  | ||||||
|             } |  | ||||||
|             return output; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Retrieves all Strings which look remotely like URLs from a text. |  | ||||||
|      * Used if NewPipe was called through share menu. |  | ||||||
|      * |  | ||||||
|      * @param sharedText text to scan for URLs. |  | ||||||
|      * @return potential URLs |  | ||||||
|      */ |  | ||||||
|     private String[] getUris(final String sharedText) { |  | ||||||
|         final Collection<String> result = new HashSet<>(); |  | ||||||
|         if (sharedText != null) { |  | ||||||
|             final String[] array = sharedText.split("\\p{Space}"); |  | ||||||
|             for (String s : array) { |  | ||||||
|                 s = trim(s); |  | ||||||
|                 if (s.length() != 0) { |  | ||||||
|                     if (s.matches(".+://.+")) { |  | ||||||
|                         result.add(removeHeadingGibberish(s)); |  | ||||||
|                     } else if (s.matches(".+\\..+")) { |  | ||||||
|                         result.add("http://" + s); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return result.toArray(new String[result.size()]); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ public abstract class BaseFragment extends Fragment { | |||||||
|     protected static final boolean DEBUG = MainActivity.DEBUG; |     protected static final boolean DEBUG = MainActivity.DEBUG; | ||||||
|  |  | ||||||
|     protected AppCompatActivity activity; |     protected AppCompatActivity activity; | ||||||
|     protected OnItemSelectedListener onItemSelectedListener; |  | ||||||
|  |  | ||||||
|     protected AtomicBoolean isLoading = new AtomicBoolean(false); |     protected AtomicBoolean isLoading = new AtomicBoolean(false); | ||||||
|     protected AtomicBoolean wasLoading = new AtomicBoolean(false); |     protected AtomicBoolean wasLoading = new AtomicBoolean(false); | ||||||
| @@ -64,7 +63,6 @@ public abstract class BaseFragment extends Fragment { | |||||||
|         if (DEBUG) Log.d(TAG, "onAttach() called with: context = [" + context + "]"); |         if (DEBUG) Log.d(TAG, "onAttach() called with: context = [" + context + "]"); | ||||||
|  |  | ||||||
|         activity = (AppCompatActivity) context; |         activity = (AppCompatActivity) context; | ||||||
|         onItemSelectedListener = (OnItemSelectedListener) context; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ public class MainFragment extends Fragment { | |||||||
|     /*////////////////////////////////////////////////////////////////////////// |     /*////////////////////////////////////////////////////////////////////////// | ||||||
|     // Menu |     // Menu | ||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | ||||||
|         super.onCreateOptionsMenu(menu, inflater); |         super.onCreateOptionsMenu(menu, inflater); | ||||||
| @@ -68,7 +69,7 @@ public class MainFragment extends Fragment { | |||||||
|     public boolean onOptionsItemSelected(MenuItem item) { |     public boolean onOptionsItemSelected(MenuItem item) { | ||||||
|         switch (item.getItemId()) { |         switch (item.getItemId()) { | ||||||
|             case R.id.action_search: |             case R.id.action_search: | ||||||
|                 NavigationHelper.openSearch(activity, 0, ""); |                 NavigationHelper.openSearchFragment(getFragmentManager(), 0, ""); | ||||||
|                 return true; |                 return true; | ||||||
|         } |         } | ||||||
|         return super.onOptionsItemSelected(item); |         return super.onOptionsItemSelected(item); | ||||||
|   | |||||||
| @@ -1,10 +0,0 @@ | |||||||
| package org.schabi.newpipe.fragments; |  | ||||||
|  |  | ||||||
| import org.schabi.newpipe.extractor.StreamingService; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Interface for communication purposes between activity and fragment |  | ||||||
|  */ |  | ||||||
| public interface OnItemSelectedListener { |  | ||||||
|     void onItemSelected(StreamingService.LinkType linkType, int serviceId, String url, String name); |  | ||||||
| } |  | ||||||
| @@ -240,7 +240,7 @@ public class ChannelFragment extends BaseFragment implements ChannelExtractorWor | |||||||
|             @Override |             @Override | ||||||
|             public void selected(int serviceId, String url, String title) { |             public void selected(int serviceId, String url, String title) { | ||||||
|                 if (DEBUG) Log.d(TAG, "selected() called with: serviceId = [" + serviceId + "], url = [" + url + "], title = [" + title + "]"); |                 if (DEBUG) Log.d(TAG, "selected() called with: serviceId = [" + serviceId + "], url = [" + url + "], title = [" + title + "]"); | ||||||
|                 NavigationHelper.openVideoDetail(onItemSelectedListener, serviceId, url, title); |                 NavigationHelper.openVideoDetailFragment(getFragmentManager(), serviceId, url, title); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -314,7 +314,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor | |||||||
|         switch (requestCode) { |         switch (requestCode) { | ||||||
|             case ReCaptchaActivity.RECAPTCHA_REQUEST: |             case ReCaptchaActivity.RECAPTCHA_REQUEST: | ||||||
|                 if (resultCode == Activity.RESULT_OK) { |                 if (resultCode == Activity.RESULT_OK) { | ||||||
|                     NavigationHelper.openVideoDetail(onItemSelectedListener, serviceId, videoUrl, videoTitle); |                     NavigationHelper.openVideoDetailFragment(getFragmentManager(), serviceId, videoUrl, videoTitle); | ||||||
|                 } else Log.e(TAG, "ReCaptcha failed"); |                 } else Log.e(TAG, "ReCaptcha failed"); | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
| @@ -354,7 +354,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor | |||||||
|                 openInPopup(); |                 openInPopup(); | ||||||
|                 break; |                 break; | ||||||
|             case R.id.detail_uploader_button: |             case R.id.detail_uploader_button: | ||||||
|                 NavigationHelper.openChannel(onItemSelectedListener, currentStreamInfo.service_id, currentStreamInfo.channel_url, currentStreamInfo.uploader); |                 NavigationHelper.openChannelFragment(getFragmentManager(), currentStreamInfo.service_id, currentStreamInfo.channel_url, currentStreamInfo.uploader); | ||||||
|                 break; |                 break; | ||||||
|             case R.id.detail_thumbnail_background_button: |             case R.id.detail_thumbnail_background_button: | ||||||
|                 playVideo(currentStreamInfo); |                 playVideo(currentStreamInfo); | ||||||
|   | |||||||
| @@ -224,13 +224,13 @@ public class SearchFragment extends BaseFragment implements SuggestionWorker.OnS | |||||||
|             infoListAdapter.setOnStreamInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() { |             infoListAdapter.setOnStreamInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void selected(int serviceId, String url, String title) { |                 public void selected(int serviceId, String url, String title) { | ||||||
|                     NavigationHelper.openVideoDetail(onItemSelectedListener, serviceId, url, title); |                     NavigationHelper.openVideoDetailFragment(getFragmentManager(), serviceId, url, title); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|             infoListAdapter.setOnChannelInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() { |             infoListAdapter.setOnChannelInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void selected(int serviceId, String url, String title) { |                 public void selected(int serviceId, String url, String title) { | ||||||
|                     NavigationHelper.openChannel(onItemSelectedListener, serviceId, url, title); |                     NavigationHelper.openChannelFragment(getFragmentManager(), serviceId, url, title); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| @@ -389,7 +389,7 @@ public class SearchFragment extends BaseFragment implements SuggestionWorker.OnS | |||||||
|             public void onClick(View v) { |             public void onClick(View v) { | ||||||
|                 if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]"); |                 if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]"); | ||||||
|                 if (TextUtils.isEmpty(searchEditText.getText())) { |                 if (TextUtils.isEmpty(searchEditText.getText())) { | ||||||
|                     NavigationHelper.openMainActivity(activity); |                     NavigationHelper.openMainFragment(getFragmentManager()); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -263,6 +263,7 @@ public class PopupVideoPlayer extends Service { | |||||||
|         i.putExtra(Constants.KEY_TITLE, videoTitle); |         i.putExtra(Constants.KEY_TITLE, videoTitle); | ||||||
|         i.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM); |         i.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM); | ||||||
|         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||||||
|  |         i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); | ||||||
|         context.startActivity(i); |         context.startActivity(i); | ||||||
|         context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); |         context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -69,7 +69,7 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { |     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { | ||||||
|         Log.d("TAG", "onPreferenceTreeClick() called with: preferenceScreen = [" + preferenceScreen + "], preference = [" + preference + "]"); |         if (MainActivity.DEBUG) Log.d("TAG", "onPreferenceTreeClick() called with: preferenceScreen = [" + preferenceScreen + "], preference = [" + preference + "]"); | ||||||
|         if (preference.getKey().equals(DOWNLOAD_PATH_PREFERENCE) || preference.getKey().equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { |         if (preference.getKey().equals(DOWNLOAD_PATH_PREFERENCE) || preference.getKey().equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { | ||||||
|             Intent i = new Intent(activity, FilePickerActivity.class) |             Intent i = new Intent(activity, FilePickerActivity.class) | ||||||
|                     .putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false) |                     .putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false) | ||||||
| @@ -87,7 +87,7 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer | |||||||
|     @Override |     @Override | ||||||
|     public void onActivityResult(int requestCode, int resultCode, Intent data) { |     public void onActivityResult(int requestCode, int resultCode, Intent data) { | ||||||
|         super.onActivityResult(requestCode, resultCode, data); |         super.onActivityResult(requestCode, resultCode, data); | ||||||
|         Log.d("TAG", "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); |         if (MainActivity.DEBUG) Log.d("TAG", "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); | ||||||
|  |  | ||||||
|         if ((requestCode == REQUEST_DOWNLOAD_PATH || requestCode == REQUEST_DOWNLOAD_AUDIO_PATH) && resultCode == Activity.RESULT_OK) { |         if ((requestCode == REQUEST_DOWNLOAD_PATH || requestCode == REQUEST_DOWNLOAD_AUDIO_PATH) && resultCode == Activity.RESULT_OK) { | ||||||
|             String key = getString(requestCode == REQUEST_DOWNLOAD_PATH ? R.string.download_path_key : R.string.download_path_audio_key); |             String key = getString(requestCode == REQUEST_DOWNLOAD_PATH ? R.string.download_path_key : R.string.download_path_audio_key); | ||||||
| @@ -101,7 +101,7 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /* | ||||||
|      * Update ONLY the summary of some preferences that don't fire in the onSharedPreferenceChanged or CAN'T be update via xml (%s) |      * Update ONLY the summary of some preferences that don't fire in the onSharedPreferenceChanged or CAN'T be update via xml (%s) | ||||||
|      * |      * | ||||||
|      * For example, the download_path use the startActivityForResult, firing the onStop of this fragment, |      * For example, the download_path use the startActivityForResult, firing the onStop of this fragment, | ||||||
| @@ -114,7 +114,7 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { |     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { | ||||||
|         Log.d("TAG", "onSharedPreferenceChanged() called with: sharedPreferences = [" + sharedPreferences + "], key = [" + key + "]"); |         if (MainActivity.DEBUG) Log.d("TAG", "onSharedPreferenceChanged() called with: sharedPreferences = [" + sharedPreferences + "], key = [" + key + "]"); | ||||||
|         String summary = null; |         String summary = null; | ||||||
|  |  | ||||||
|         if (key.equals(USE_TOR_KEY)) { |         if (key.equals(USE_TOR_KEY)) { | ||||||
| @@ -131,10 +131,10 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer | |||||||
|         } else if (key.equals(THEME)) { |         } else if (key.equals(THEME)) { | ||||||
|             summary = sharedPreferences.getString(THEME, getString(R.string.default_theme_value)); |             summary = sharedPreferences.getString(THEME, getString(R.string.default_theme_value)); | ||||||
|             if (!summary.equals(currentTheme)) { // If it's not the current theme |             if (!summary.equals(currentTheme)) { // If it's not the current theme | ||||||
|                 Intent intentToMain = new Intent(activity, MainActivity.class); |                 getActivity().recreate(); | ||||||
|                 intentToMain.putExtra(Constants.KEY_THEME_CHANGE, true); |  | ||||||
|                 startActivity(intentToMain); |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!TextUtils.isEmpty(summary)) findPreference(key).setSummary(summary); |         if (!TextUtils.isEmpty(summary)) findPreference(key).setSummary(summary); | ||||||
|   | |||||||
| @@ -3,6 +3,10 @@ package org.schabi.newpipe.util; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.preference.PreferenceManager; | import android.preference.PreferenceManager; | ||||||
|  | import android.support.v4.app.Fragment; | ||||||
|  | import android.support.v4.app.FragmentManager; | ||||||
|  |  | ||||||
|  | import com.nostra13.universalimageloader.core.ImageLoader; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.MainActivity; | import org.schabi.newpipe.MainActivity; | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
| @@ -10,8 +14,10 @@ import org.schabi.newpipe.extractor.NewPipe; | |||||||
| import org.schabi.newpipe.extractor.StreamingService; | import org.schabi.newpipe.extractor.StreamingService; | ||||||
| import org.schabi.newpipe.extractor.stream_info.AudioStream; | import org.schabi.newpipe.extractor.stream_info.AudioStream; | ||||||
| import org.schabi.newpipe.extractor.stream_info.StreamInfo; | import org.schabi.newpipe.extractor.stream_info.StreamInfo; | ||||||
| import org.schabi.newpipe.fragments.OnItemSelectedListener; | import org.schabi.newpipe.fragments.MainFragment; | ||||||
|  | import org.schabi.newpipe.fragments.channel.ChannelFragment; | ||||||
| import org.schabi.newpipe.fragments.detail.VideoDetailFragment; | import org.schabi.newpipe.fragments.detail.VideoDetailFragment; | ||||||
|  | import org.schabi.newpipe.fragments.search.SearchFragment; | ||||||
| import org.schabi.newpipe.player.BackgroundPlayer; | import org.schabi.newpipe.player.BackgroundPlayer; | ||||||
| import org.schabi.newpipe.player.BasePlayer; | import org.schabi.newpipe.player.BasePlayer; | ||||||
| import org.schabi.newpipe.player.VideoPlayer; | import org.schabi.newpipe.player.VideoPlayer; | ||||||
| @@ -36,7 +42,6 @@ public class NavigationHelper { | |||||||
|         return mIntent; |         return mIntent; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, VideoPlayer instance) { |     public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, VideoPlayer instance) { | ||||||
|         return new Intent(context, targetClazz) |         return new Intent(context, targetClazz) | ||||||
|                 .putExtra(BasePlayer.VIDEO_TITLE, instance.getVideoTitle()) |                 .putExtra(BasePlayer.VIDEO_TITLE, instance.getVideoTitle()) | ||||||
| @@ -66,31 +71,69 @@ public class NavigationHelper { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /*////////////////////////////////////////////////////////////////////////// |     /*////////////////////////////////////////////////////////////////////////// | ||||||
|     // Through Interface (faster) |     // Through FragmentManager | ||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     public static void openChannel(OnItemSelectedListener listener, int serviceId, String url) { |     public static void openMainFragment(FragmentManager fragmentManager) { | ||||||
|         openChannel(listener, serviceId, url, null); |         ImageLoader.getInstance().clearMemoryCache(); | ||||||
|  |         fragmentManager.beginTransaction() | ||||||
|  |                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) | ||||||
|  |                 .replace(R.id.fragment_holder, new MainFragment()) | ||||||
|  |                 .commit(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void openChannel(OnItemSelectedListener listener, int serviceId, String url, String name) { |     public static void openSearchFragment(FragmentManager fragmentManager, int serviceId, String query) { | ||||||
|         listener.onItemSelected(StreamingService.LinkType.CHANNEL, serviceId, url, name); |         fragmentManager.beginTransaction() | ||||||
|  |                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) | ||||||
|  |                 .replace(R.id.fragment_holder, SearchFragment.getInstance(serviceId, query)) | ||||||
|  |                 .addToBackStack(null) | ||||||
|  |                 .commit(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void openVideoDetail(OnItemSelectedListener listener, int serviceId, String url) { |     public static void openVideoDetailFragment(FragmentManager fragmentManager, int serviceId, String url, String title) { | ||||||
|         openVideoDetail(listener, serviceId, url, null); |         openVideoDetailFragment(fragmentManager, serviceId, url, title, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void openVideoDetail(OnItemSelectedListener listener, int serviceId, String url, String title) { |     public static void openVideoDetailFragment(FragmentManager fragmentManager, int serviceId, String url, String title, boolean autoPlay) { | ||||||
|         listener.onItemSelected(StreamingService.LinkType.STREAM, serviceId, url, title); |         Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_holder); | ||||||
|  |         if (title == null) title = ""; | ||||||
|  |  | ||||||
|  |         if (fragment instanceof VideoDetailFragment && fragment.isVisible()) { | ||||||
|  |             VideoDetailFragment detailFragment = (VideoDetailFragment) fragment; | ||||||
|  |             detailFragment.setAutoplay(autoPlay); | ||||||
|  |             detailFragment.selectAndLoadVideo(serviceId, url, title); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         VideoDetailFragment instance = VideoDetailFragment.getInstance(serviceId, url, title); | ||||||
|  |         instance.setAutoplay(autoPlay); | ||||||
|  |  | ||||||
|  |         fragmentManager.beginTransaction() | ||||||
|  |                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) | ||||||
|  |                 .replace(R.id.fragment_holder, instance) | ||||||
|  |                 .addToBackStack(null) | ||||||
|  |                 .commit(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static void openChannelFragment(FragmentManager fragmentManager, int serviceId, String url, String name) { | ||||||
|  |         if (name == null) name = ""; | ||||||
|  |         fragmentManager.beginTransaction() | ||||||
|  |                 .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out) | ||||||
|  |                 .replace(R.id.fragment_holder, ChannelFragment.getInstance(serviceId, url, name)) | ||||||
|  |                 .addToBackStack(null) | ||||||
|  |                 .commit(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /*////////////////////////////////////////////////////////////////////////// |     /*////////////////////////////////////////////////////////////////////////// | ||||||
|     // Through Intents |     // Through Intents | ||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     public static void openByLink(Context context, String url) throws Exception { |     public static void openSearch(Context context, int serviceId, String query) { | ||||||
|         context.startActivity(getIntentByLink(context, url)); |         Intent mIntent = new Intent(context, MainActivity.class); | ||||||
|  |         mIntent.putExtra(Constants.KEY_SERVICE_ID, serviceId); | ||||||
|  |         mIntent.putExtra(Constants.KEY_QUERY, query); | ||||||
|  |         mIntent.putExtra(Constants.KEY_OPEN_SEARCH, true); | ||||||
|  |         context.startActivity(mIntent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void openChannel(Context context, int serviceId, String url) { |     public static void openChannel(Context context, int serviceId, String url) { | ||||||
| @@ -118,12 +161,12 @@ public class NavigationHelper { | |||||||
|         context.startActivity(mIntent); |         context.startActivity(mIntent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void openSearch(Context context, int serviceId, String query) { |     public static void openByLink(Context context, String url) throws Exception { | ||||||
|         Intent mIntent = new Intent(context, MainActivity.class); |         Intent intentByLink = getIntentByLink(context, url); | ||||||
|         mIntent.putExtra(Constants.KEY_SERVICE_ID, serviceId); |         if (intentByLink == null) throw new NullPointerException("getIntentByLink(context = [" + context + "], url = [" + url + "]) returned null"); | ||||||
|         mIntent.putExtra(Constants.KEY_QUERY, query); |         intentByLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||||||
|         mIntent.putExtra(Constants.KEY_OPEN_SEARCH, true); |         intentByLink.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||||||
|         context.startActivity(mIntent); |         context.startActivity(intentByLink); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static Intent getOpenIntent(Context context, String url, int serviceId, StreamingService.LinkType type) { |     private static Intent getOpenIntent(Context context, String url, int serviceId, StreamingService.LinkType type) { | ||||||
| @@ -147,8 +190,7 @@ public class NavigationHelper { | |||||||
|             case CHANNEL: |             case CHANNEL: | ||||||
|                 return getOpenIntent(context, url, serviceId, StreamingService.LinkType.CHANNEL); |                 return getOpenIntent(context, url, serviceId, StreamingService.LinkType.CHANNEL); | ||||||
|             case NONE: |             case NONE: | ||||||
|                 throw new Exception("Url not known to service. service=" |                 throw new Exception("Url not known to service. service=" + serviceId + " url=" + url); | ||||||
|                         + Integer.toString(serviceId) + " url=" + url); |  | ||||||
|         } |         } | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Mauricio Colli
					Mauricio Colli