mirror of
				https://framagit.org/tom79/fedilab-tube
				synced 2025-06-05 21:09:11 +02:00 
			
		
		
		
	Manage Playlists
This commit is contained in:
		| @@ -58,6 +58,16 @@ | ||||
|             android:configChanges="orientation|screenSize" | ||||
|             android:label="@string/app_name" | ||||
|             android:windowSoftInputMode="stateAlwaysHidden" /> | ||||
|         <activity | ||||
|             android:name=".AllPlaylistsActivity" | ||||
|             android:configChanges="orientation|screenSize" | ||||
|             android:label="@string/app_name" | ||||
|             android:windowSoftInputMode="stateAlwaysHidden" /> | ||||
|         <activity | ||||
|             android:name=".PlaylistsActivity" | ||||
|             android:configChanges="orientation|screenSize" | ||||
|             android:label="@string/app_name" | ||||
|             android:windowSoftInputMode="stateAlwaysHidden" /> | ||||
|         <activity | ||||
|             android:name=".MyVideosActivity" | ||||
|             android:configChanges="orientation|screenSize" | ||||
|   | ||||
| @@ -0,0 +1,397 @@ | ||||
| package app.fedilab.fedilabtube; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Bundle; | ||||
| import android.text.InputFilter; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.view.WindowManager; | ||||
| import android.view.inputmethod.InputMethodManager; | ||||
| import android.widget.AdapterView; | ||||
| import android.widget.ArrayAdapter; | ||||
| import android.widget.EditText; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.ListView; | ||||
| import android.widget.RelativeLayout; | ||||
| import android.widget.Spinner; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
|  | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
|  | ||||
| import net.gotev.uploadservice.MultipartUploadRequest; | ||||
| import net.gotev.uploadservice.ServerResponse; | ||||
| import net.gotev.uploadservice.UploadInfo; | ||||
| import net.gotev.uploadservice.UploadNotificationConfig; | ||||
| import net.gotev.uploadservice.UploadStatusDelegate; | ||||
|  | ||||
| import java.net.MalformedURLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask; | ||||
| import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeChannelsAsyncTask; | ||||
| import app.fedilab.fedilabtube.client.APIResponse; | ||||
| import app.fedilab.fedilabtube.client.entities.Account; | ||||
| import app.fedilab.fedilabtube.client.entities.Playlist; | ||||
| import app.fedilab.fedilabtube.drawer.PlaylistAdapter; | ||||
| import app.fedilab.fedilabtube.fragment.DisplayPlaylistsFragment; | ||||
| import app.fedilab.fedilabtube.helper.Helper; | ||||
| import app.fedilab.fedilabtube.interfaces.OnPlaylistActionInterface; | ||||
| import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface; | ||||
| import es.dmoral.toasty.Toasty; | ||||
|  | ||||
| import static app.fedilab.fedilabtube.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation; | ||||
|  | ||||
|  | ||||
| public class AllPlaylistsActivity extends AppCompatActivity implements OnPlaylistActionInterface, OnRetrievePeertubeInterface { | ||||
|  | ||||
|  | ||||
|     private AsyncTask<Void, Void, Void> asyncTask; | ||||
|     private List<Playlist> playlists; | ||||
|     private RelativeLayout mainLoader; | ||||
|     private FloatingActionButton add_new; | ||||
|     private PlaylistAdapter playlistAdapter; | ||||
|     private RelativeLayout textviewNoAction; | ||||
|     private HashMap<Integer, String> privacyToSend; | ||||
|     private HashMap<String, String> channelToSend; | ||||
|     private Spinner set_upload_channel; | ||||
|     private Spinner set_upload_privacy; | ||||
|     private HashMap<String, String> channels; | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         setContentView(R.layout.activity_all_playlist); | ||||
|  | ||||
|         if (getSupportActionBar() != null) | ||||
|             getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|         setTitle(R.string.playlists); | ||||
|  | ||||
|         playlists = new ArrayList<>(); | ||||
|  | ||||
|  | ||||
|         ListView lv_playlist = findViewById(R.id.lv_playlist); | ||||
|         textviewNoAction = findViewById(R.id.no_action); | ||||
|         mainLoader = findViewById(R.id.loader); | ||||
|         RelativeLayout nextElementLoader = findViewById(R.id.loading_next_items); | ||||
|         mainLoader.setVisibility(View.VISIBLE); | ||||
|         nextElementLoader.setVisibility(View.GONE); | ||||
|         playlists = new ArrayList<>(); | ||||
|         playlistAdapter = new PlaylistAdapter(AllPlaylistsActivity.this, playlists, textviewNoAction); | ||||
|         lv_playlist.setAdapter(playlistAdapter); | ||||
|         asyncTask = new ManagePlaylistsAsyncTask(AllPlaylistsActivity.this, ManagePlaylistsAsyncTask.action.GET_PLAYLIST, null, null, null, AllPlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|         add_new = findViewById(R.id.add_new); | ||||
|  | ||||
|  | ||||
|         LinkedHashMap<Integer, String> privaciesInit = new LinkedHashMap<>(peertubeInformation.getPrivacies()); | ||||
|         Map.Entry<Integer, String> entryInt = privaciesInit.entrySet().iterator().next(); | ||||
|         privacyToSend = new HashMap<>(); | ||||
|         privacyToSend.put(entryInt.getKey(), entryInt.getValue()); | ||||
|  | ||||
|  | ||||
|         if (add_new != null) { | ||||
|             add_new.setOnClickListener(view -> { | ||||
|                 final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|                 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(AllPlaylistsActivity.this); | ||||
|                 LayoutInflater inflater1 = getLayoutInflater(); | ||||
|                 View dialogView = inflater1.inflate(R.layout.add_playlist, new LinearLayout(AllPlaylistsActivity.this), false); | ||||
|                 dialogBuilder.setView(dialogView); | ||||
|                 EditText display_name = dialogView.findViewById(R.id.display_name); | ||||
|                 EditText description = dialogView.findViewById(R.id.description); | ||||
|                 set_upload_channel = dialogView.findViewById(R.id.set_upload_channel); | ||||
|                 set_upload_privacy = dialogView.findViewById(R.id.set_upload_privacy); | ||||
|  | ||||
|  | ||||
|                 new RetrievePeertubeChannelsAsyncTask(AllPlaylistsActivity.this, AllPlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|  | ||||
|                 display_name.setFilters(new InputFilter[]{new InputFilter.LengthFilter(120)}); | ||||
|                 description.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1000)}); | ||||
|  | ||||
|                 dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> { | ||||
|  | ||||
|                     if (display_name.getText() != null && display_name.getText().toString().trim().length() > 0) { | ||||
|  | ||||
|                         Playlist playlist = new Playlist(); | ||||
|                         playlist.setDisplayName(display_name.getText().toString().trim()); | ||||
|                         if (description.getText() != null && description.getText().toString().trim().length() > 0) { | ||||
|                             playlist.setDescription(description.getText().toString().trim()); | ||||
|                         } | ||||
|                         String idChannel = null; | ||||
|                         if (channelToSend != null) { | ||||
|                             Map.Entry<String, String> channelM = channelToSend.entrySet().iterator().next(); | ||||
|                             idChannel = channelM.getValue(); | ||||
|                             if (idChannel.length() > 0) | ||||
|                                 playlist.setVideoChannelId(idChannel); | ||||
|                         } | ||||
|                         Map.Entry<Integer, String> privacyM = privacyToSend.entrySet().iterator().next(); | ||||
|                         String label = privacyM.getValue(); | ||||
|                         String idPrivacy = String.valueOf(privacyM.getKey()); | ||||
|                         if (label.equals("Public") && (playlist.getVideoChannelId() == null || playlist.getVideoChannelId().equals(""))) { | ||||
|                             Toasty.error(AllPlaylistsActivity.this, getString(R.string.error_channel_mandatory), Toast.LENGTH_LONG).show(); | ||||
|                         } else { | ||||
|                             if (privacyToSend != null) { | ||||
|                                 playlist.setPrivacy(privacyToSend); | ||||
|                             } | ||||
|                             //new ManagePlaylistsAsyncTask(context, ManagePlaylistsAsyncTask.action.CREATE_PLAYLIST, playlist, null, null, DisplayPlaylistsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|                             UploadNotificationConfig uploadConfig = new UploadNotificationConfig(); | ||||
|                             uploadConfig.getCompleted().autoClear = true; | ||||
|                             try { | ||||
|                                 String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); | ||||
|                                 new MultipartUploadRequest(AllPlaylistsActivity.this, "https://" + Helper.getLiveInstance(AllPlaylistsActivity.this) + "/api/v1/video-playlists/") | ||||
|                                         //.addFileToUpload(uri.toString().replace("file://",""), "videofile") | ||||
|                                         .addHeader("Authorization", "Bearer " + token) | ||||
|                                         .setNotificationConfig(uploadConfig) | ||||
|                                         // .addParameter("name", filename) | ||||
|                                         .addParameter("videoChannelId", idChannel) | ||||
|                                         .addParameter("privacy", idPrivacy) | ||||
|                                         .addParameter("displayName", playlist.getDisplayName()) | ||||
|                                         .addParameter("description", playlist.getDescription()) | ||||
|                                         .setMaxRetries(1) | ||||
|                                         .setDelegate(new UploadStatusDelegate() { | ||||
|                                             @Override | ||||
|                                             public void onProgress(Context context, UploadInfo uploadInfo) { | ||||
|                                                 // your code here | ||||
|                                             } | ||||
|  | ||||
|                                             @Override | ||||
|                                             public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, | ||||
|                                                                 Exception exception) { | ||||
|                                                 // your code here | ||||
|                                                 exception.printStackTrace(); | ||||
|                                             } | ||||
|  | ||||
|                                             @Override | ||||
|                                             public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { | ||||
|                                                 DisplayPlaylistsFragment displayPlaylistsFragment; | ||||
|                                                 displayPlaylistsFragment = (DisplayPlaylistsFragment) getSupportFragmentManager().findFragmentByTag("PLAYLISTS"); | ||||
|                                                 final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); | ||||
|                                                 if (displayPlaylistsFragment != null) { | ||||
|                                                     ft.detach(displayPlaylistsFragment); | ||||
|                                                     ft.attach(displayPlaylistsFragment); | ||||
|                                                     ft.commit(); | ||||
|                                                 } | ||||
|                                             } | ||||
|  | ||||
|                                             @Override | ||||
|                                             public void onCancelled(Context context, UploadInfo uploadInfo) { | ||||
|                                                 // your code here | ||||
|                                             } | ||||
|                                         }) | ||||
|                                         .startUpload(); | ||||
|                             } catch (MalformedURLException e) { | ||||
|                                 e.printStackTrace(); | ||||
|                             } | ||||
|  | ||||
|                             dialog.dismiss(); | ||||
|                             add_new.setEnabled(false); | ||||
|                         } | ||||
|                     } else { | ||||
|                         Toasty.error(AllPlaylistsActivity.this, getString(R.string.error_display_name), Toast.LENGTH_LONG).show(); | ||||
|                     } | ||||
|  | ||||
|                 }); | ||||
|                 dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); | ||||
|  | ||||
|  | ||||
|                 AlertDialog alertDialog = dialogBuilder.create(); | ||||
|                 alertDialog.setTitle(getString(R.string.action_playlist_create)); | ||||
|                 alertDialog.setOnDismissListener(dialogInterface -> { | ||||
|                     //Hide keyboard | ||||
|                     InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); | ||||
|                     assert imm != null; | ||||
|                     imm.hideSoftInputFromWindow(display_name.getWindowToken(), 0); | ||||
|                 }); | ||||
|                 if (alertDialog.getWindow() != null) | ||||
|                     alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); | ||||
|                 alertDialog.show(); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         if (asyncTask != null && !asyncTask.isCancelled()) { | ||||
|             asyncTask.cancel(true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { | ||||
|         mainLoader.setVisibility(View.GONE); | ||||
|         add_new.setEnabled(true); | ||||
|         if (apiResponse.getError() != null) { | ||||
|             Toasty.error(AllPlaylistsActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (actionType == ManagePlaylistsAsyncTask.action.GET_PLAYLIST) { | ||||
|             if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) { | ||||
|                 this.playlists.addAll(apiResponse.getPlaylists()); | ||||
|                 playlistAdapter.notifyDataSetChanged(); | ||||
|                 textviewNoAction.setVisibility(View.GONE); | ||||
|             } else { | ||||
|                 textviewNoAction.setVisibility(View.VISIBLE); | ||||
|             } | ||||
|         } else if (actionType == ManagePlaylistsAsyncTask.action.CREATE_PLAYLIST) { | ||||
|             if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) { | ||||
|                 Intent intent = new Intent(AllPlaylistsActivity.this, PlaylistsActivity.class); | ||||
|                 Bundle b = new Bundle(); | ||||
|                 b.putParcelable("playlist", apiResponse.getPlaylists().get(0)); | ||||
|                 intent.putExtras(b); | ||||
|                 startActivity(intent); | ||||
|                 this.playlists.add(0, apiResponse.getPlaylists().get(0)); | ||||
|                 playlistAdapter.notifyDataSetChanged(); | ||||
|                 textviewNoAction.setVisibility(View.GONE); | ||||
|             } else { | ||||
|                 Toasty.error(AllPlaylistsActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             } | ||||
|         } else if (actionType == ManagePlaylistsAsyncTask.action.DELETE_PLAYLIST) { | ||||
|             if (this.playlists.size() == 0) | ||||
|                 textviewNoAction.setVisibility(View.VISIBLE); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertube(APIResponse apiResponse) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertubeComments(APIResponse apiResponse) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertubeChannels(APIResponse apiResponse) { | ||||
|         if (apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0) { | ||||
|             if (apiResponse.getError() != null && apiResponse.getError().getError() != null) | ||||
|                 Toasty.error(AllPlaylistsActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             else | ||||
|                 Toasty.error(AllPlaylistsActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         //Populate channels | ||||
|         List<Account> accounts = apiResponse.getAccounts(); | ||||
|         String[] channelName = new String[accounts.size() + 1]; | ||||
|         String[] channelId = new String[accounts.size() + 1]; | ||||
|         int i = 1; | ||||
|         channelName[0] = ""; | ||||
|         channelId[0] = ""; | ||||
|         channels = new HashMap<>(); | ||||
|         for (Account account : accounts) { | ||||
|             channels.put(account.getUsername(), account.getId()); | ||||
|             channelName[i] = account.getUsername(); | ||||
|             channelId[i] = account.getId(); | ||||
|             i++; | ||||
|         } | ||||
|  | ||||
|         channelToSend = new HashMap<>(); | ||||
|         channelToSend.put(channelName[0], channelId[0]); | ||||
|         ArrayAdapter<String> adapterChannel = new ArrayAdapter<>(AllPlaylistsActivity.this, | ||||
|                 android.R.layout.simple_spinner_dropdown_item, channelName); | ||||
|         set_upload_channel.setAdapter(adapterChannel); | ||||
|  | ||||
|         LinkedHashMap<String, String> translations = null; | ||||
|         if (peertubeInformation.getTranslations() != null) | ||||
|             translations = new LinkedHashMap<>(peertubeInformation.getTranslations()); | ||||
|  | ||||
|         LinkedHashMap<Integer, String> privaciesInit = new LinkedHashMap<>(peertubeInformation.getPlaylistPrivacies()); | ||||
|         Map.Entry<Integer, String> entryInt = privaciesInit.entrySet().iterator().next(); | ||||
|         privacyToSend = new HashMap<>(); | ||||
|         privacyToSend.put(entryInt.getKey(), entryInt.getValue()); | ||||
|         LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPlaylistPrivacies()); | ||||
|         //Populate privacies | ||||
|         String[] privaciesA = new String[privacies.size()]; | ||||
|         Iterator<Map.Entry<Integer, String>> it = privacies.entrySet().iterator(); | ||||
|         i = 0; | ||||
|         while (it.hasNext()) { | ||||
|             Map.Entry<Integer, String> pair = it.next(); | ||||
|             if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue())) | ||||
|                 privaciesA[i] = pair.getValue(); | ||||
|             else | ||||
|                 privaciesA[i] = translations.get(pair.getValue()); | ||||
|             it.remove(); | ||||
|             i++; | ||||
|         } | ||||
|  | ||||
|         ArrayAdapter<String> adapterPrivacies = new ArrayAdapter<>(AllPlaylistsActivity.this, | ||||
|                 android.R.layout.simple_spinner_dropdown_item, privaciesA); | ||||
|         set_upload_privacy.setAdapter(adapterPrivacies); | ||||
|  | ||||
|         //Manage privacies | ||||
|         set_upload_privacy.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies()); | ||||
|                 Iterator<Map.Entry<Integer, String>> it = privaciesCheck.entrySet().iterator(); | ||||
|                 int i = 0; | ||||
|                 while (it.hasNext()) { | ||||
|                     Map.Entry<Integer, String> pair = it.next(); | ||||
|                     if (i == position) { | ||||
|                         privacyToSend = new HashMap<>(); | ||||
|                         privacyToSend.put(pair.getKey(), pair.getValue()); | ||||
|                         break; | ||||
|                     } | ||||
|                     it.remove(); | ||||
|                     i++; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|         //Manage languages | ||||
|         set_upload_channel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels); | ||||
|                 Iterator<Map.Entry<String, String>> it = channelsCheck.entrySet().iterator(); | ||||
|                 int i = 0; | ||||
|                 while (it.hasNext()) { | ||||
|                     Map.Entry<String, String> pair = it.next(); | ||||
|                     if (i == position) { | ||||
|                         channelToSend = new HashMap<>(); | ||||
|                         channelToSend.put(pair.getKey(), pair.getValue()); | ||||
|                         break; | ||||
|                     } | ||||
|                     it.remove(); | ||||
|                     i++; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @@ -77,12 +77,15 @@ public class MainActivity extends AppCompatActivity { | ||||
|  | ||||
|         MenuItem uploadItem = menu.findItem(R.id.action_upload); | ||||
|         MenuItem myVideosItem = menu.findItem(R.id.action_myvideos); | ||||
|         MenuItem playslistItem = menu.findItem(R.id.action_playlist); | ||||
|         if (Helper.isLoggedIn(MainActivity.this)) { | ||||
|             uploadItem.setVisible(true); | ||||
|             myVideosItem.setVisible(true); | ||||
|             playslistItem.setVisible(true); | ||||
|         } else { | ||||
|             uploadItem.setVisible(false); | ||||
|             myVideosItem.setVisible(false); | ||||
|             playslistItem.setVisible(false); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| @@ -104,6 +107,10 @@ public class MainActivity extends AppCompatActivity { | ||||
|             Intent intent = new Intent(MainActivity.this, MyVideosActivity.class); | ||||
|             startActivity(intent); | ||||
|             return true; | ||||
|         } else if (item.getItemId() == R.id.action_playlist) { | ||||
|             Intent intent = new Intent(MainActivity.this, AllPlaylistsActivity.class); | ||||
|             startActivity(intent); | ||||
|             return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|   | ||||
| @@ -228,7 +228,7 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee | ||||
|             initFullscreenDialog(); | ||||
|             initFullscreenButton(); | ||||
|         } | ||||
|         if( Helper.isLoggedIn(PeertubeActivity.this)) { | ||||
|         if (Helper.isLoggedIn(PeertubeActivity.this)) { | ||||
|             new ManagePlaylistsAsyncTask(PeertubeActivity.this, GET_PLAYLIST, null, null, null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|         } | ||||
|  | ||||
|   | ||||
							
								
								
									
										173
									
								
								app/src/main/java/app/fedilab/fedilabtube/PlaylistsActivity.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								app/src/main/java/app/fedilab/fedilabtube/PlaylistsActivity.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| package app.fedilab.fedilabtube; | ||||
|  | ||||
|  | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Bundle; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.RelativeLayout; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask; | ||||
| import app.fedilab.fedilabtube.client.APIResponse; | ||||
| import app.fedilab.fedilabtube.client.entities.Peertube; | ||||
| import app.fedilab.fedilabtube.client.entities.Playlist; | ||||
| import app.fedilab.fedilabtube.drawer.PeertubeAdapter; | ||||
| import app.fedilab.fedilabtube.interfaces.OnPlaylistActionInterface; | ||||
| import es.dmoral.toasty.Toasty; | ||||
|  | ||||
| import static app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask.action.GET_LIST_VIDEOS; | ||||
|  | ||||
|  | ||||
| public class PlaylistsActivity extends AppCompatActivity implements OnPlaylistActionInterface { | ||||
|  | ||||
|  | ||||
|     LinearLayoutManager mLayoutManager; | ||||
|     private RelativeLayout mainLoader, nextElementLoader, textviewNoAction; | ||||
|     private SwipeRefreshLayout swipeRefreshLayout; | ||||
|     private boolean swiped; | ||||
|     private List<Peertube> peertubes; | ||||
|     private String max_id; | ||||
|     private Playlist playlist; | ||||
|     private boolean firstLoad; | ||||
|     private boolean flag_loading; | ||||
|     private PeertubeAdapter peertubeAdapter; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         if (getSupportActionBar() != null) | ||||
|             getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|  | ||||
|         setContentView(R.layout.activity_playlists); | ||||
|         peertubes = new ArrayList<>(); | ||||
|  | ||||
|         RecyclerView lv_playlist = findViewById(R.id.lv_playlist); | ||||
|         mainLoader = findViewById(R.id.loader); | ||||
|         nextElementLoader = findViewById(R.id.loading_next_status); | ||||
|         textviewNoAction = findViewById(R.id.no_action); | ||||
|         mainLoader.setVisibility(View.VISIBLE); | ||||
|         swipeRefreshLayout = findViewById(R.id.swipeContainer); | ||||
|  | ||||
|  | ||||
|         max_id = null; | ||||
|         flag_loading = true; | ||||
|         firstLoad = true; | ||||
|         swiped = false; | ||||
|  | ||||
|  | ||||
|         mainLoader.setVisibility(View.VISIBLE); | ||||
|         nextElementLoader.setVisibility(View.GONE); | ||||
|  | ||||
|         peertubeAdapter = new PeertubeAdapter(this.peertubes); | ||||
|  | ||||
|         lv_playlist.setAdapter(peertubeAdapter); | ||||
|         mLayoutManager = new LinearLayoutManager(PlaylistsActivity.this); | ||||
|         lv_playlist.setLayoutManager(mLayoutManager); | ||||
|  | ||||
|         Bundle b = getIntent().getExtras(); | ||||
|         if (b != null) { | ||||
|             playlist = b.getParcelable("playlist"); | ||||
|         } else { | ||||
|             Toasty.error(PlaylistsActivity.this, getString(R.string.toast_error_search), Toast.LENGTH_LONG).show(); | ||||
|             return; | ||||
|         } | ||||
|         if (getSupportActionBar() != null) | ||||
|             getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         setTitle(playlist.getDisplayName()); | ||||
|  | ||||
|  | ||||
|         lv_playlist.addOnScrollListener(new RecyclerView.OnScrollListener() { | ||||
|             public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { | ||||
|                 int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition(); | ||||
|                 if (dy > 0) { | ||||
|                     int visibleItemCount = mLayoutManager.getChildCount(); | ||||
|                     int totalItemCount = mLayoutManager.getItemCount(); | ||||
|                     if (firstVisibleItem + visibleItemCount == totalItemCount) { | ||||
|                         if (!flag_loading) { | ||||
|                             flag_loading = true; | ||||
|                             new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, max_id, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|                             nextElementLoader.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|                     } else { | ||||
|                         nextElementLoader.setVisibility(View.GONE); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         swipeRefreshLayout.setOnRefreshListener(() -> { | ||||
|             max_id = null; | ||||
|             firstLoad = true; | ||||
|             flag_loading = true; | ||||
|             swiped = true; | ||||
|             new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, null, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|         }); | ||||
|  | ||||
|         new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, null, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { | ||||
|         mainLoader.setVisibility(View.GONE); | ||||
|         nextElementLoader.setVisibility(View.GONE); | ||||
|         //Discards 404 - error which can often happen due to toots which have been deleted | ||||
|         if (apiResponse.getError() != null) { | ||||
|             if (!apiResponse.getError().getError().startsWith("404 -") && !apiResponse.getError().getError().startsWith("501 -")) | ||||
|                 Toasty.error(PlaylistsActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             swipeRefreshLayout.setRefreshing(false); | ||||
|             swiped = false; | ||||
|             flag_loading = false; | ||||
|             return; | ||||
|         } | ||||
|         if (actionType == GET_LIST_VIDEOS) { | ||||
|  | ||||
|             int previousPosition = this.peertubes.size(); | ||||
|             List<Peertube> videos = apiResponse.getPeertubes(); | ||||
|             max_id = apiResponse.getMax_id(); | ||||
|             flag_loading = (max_id == null); | ||||
|             if (!swiped && firstLoad && (videos == null || videos.size() == 0)) | ||||
|                 textviewNoAction.setVisibility(View.VISIBLE); | ||||
|             else | ||||
|                 textviewNoAction.setVisibility(View.GONE); | ||||
|  | ||||
|             if (swiped) { | ||||
|                 if (previousPosition > 0) { | ||||
|                     this.peertubes.subList(0, previousPosition).clear(); | ||||
|                     peertubeAdapter.notifyItemRangeRemoved(0, previousPosition); | ||||
|                 } | ||||
|                 swiped = false; | ||||
|             } | ||||
|             if (videos != null && videos.size() > 0) { | ||||
|                 this.peertubes.addAll(videos); | ||||
|                 peertubeAdapter.notifyItemRangeInserted(previousPosition, videos.size()); | ||||
|             } | ||||
|             swipeRefreshLayout.setRefreshing(false); | ||||
|             firstLoad = false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -45,7 +45,7 @@ public class ManagePlaylistsAsyncTask extends AsyncTask<Void, Void, Void> { | ||||
|         String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(contextReference.get())); | ||||
|         SQLiteDatabase db = Sqlite.getInstance(contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); | ||||
|         Account account = new AccountDAO(contextReference.get(), db).getUniqAccount(userId, instance); | ||||
|         if( account == null) { | ||||
|         if (account == null) { | ||||
|             account = new AccountDAO(contextReference.get(), db).getUniqAccount(userId, Helper.getPeertubeUrl(instance)); | ||||
|         } | ||||
|         if (account == null) { | ||||
|   | ||||
| @@ -0,0 +1,125 @@ | ||||
| package app.fedilab.fedilabtube.drawer; | ||||
|  | ||||
|  | ||||
| import android.app.AlertDialog; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.BaseAdapter; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.RelativeLayout; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.core.content.ContextCompat; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import app.fedilab.fedilabtube.PlaylistsActivity; | ||||
| import app.fedilab.fedilabtube.R; | ||||
| import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask; | ||||
| import app.fedilab.fedilabtube.client.APIResponse; | ||||
| import app.fedilab.fedilabtube.client.entities.Playlist; | ||||
| import app.fedilab.fedilabtube.interfaces.OnPlaylistActionInterface; | ||||
|  | ||||
|  | ||||
| public class PlaylistAdapter extends BaseAdapter implements OnPlaylistActionInterface { | ||||
|  | ||||
|     private List<Playlist> playlists; | ||||
|     private LayoutInflater layoutInflater; | ||||
|     private Context context; | ||||
|     private PlaylistAdapter playlistAdapter; | ||||
|     private RelativeLayout textviewNoAction; | ||||
|  | ||||
|     public PlaylistAdapter(Context context, List<Playlist> lists, RelativeLayout textviewNoAction) { | ||||
|         this.playlists = lists; | ||||
|         layoutInflater = LayoutInflater.from(context); | ||||
|         this.context = context; | ||||
|         playlistAdapter = this; | ||||
|         this.textviewNoAction = textviewNoAction; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getCount() { | ||||
|         return playlists.size(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Object getItem(int position) { | ||||
|         return playlists.get(position); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public long getItemId(int position) { | ||||
|         return position; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public View getView(final int position, View convertView, ViewGroup parent) { | ||||
|  | ||||
|         final Playlist playlist = playlists.get(position); | ||||
|         final ViewHolder holder; | ||||
|         if (convertView == null) { | ||||
|             convertView = layoutInflater.inflate(R.layout.drawer_playlist, parent, false); | ||||
|             holder = new ViewHolder(); | ||||
|             holder.search_title = convertView.findViewById(R.id.search_keyword); | ||||
|             holder.search_container = convertView.findViewById(R.id.search_container); | ||||
|             convertView.setTag(holder); | ||||
|         } else { | ||||
|             holder = (ViewHolder) convertView.getTag(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         Drawable next = ContextCompat.getDrawable(context, R.drawable.ic_baseline_arrow_forward_ios_24); | ||||
|         holder.search_title.setText(playlist.getDisplayName()); | ||||
|         assert next != null; | ||||
|         final float scale = context.getResources().getDisplayMetrics().density; | ||||
|         next.setBounds(0, 0, (int) (30 * scale + 0.5f), (int) (30 * scale + 0.5f)); | ||||
|         holder.search_title.setCompoundDrawables(null, null, next, null); | ||||
|  | ||||
|         holder.search_container.setOnClickListener(v -> { | ||||
|             Intent intent = new Intent(context, PlaylistsActivity.class); | ||||
|             Bundle b = new Bundle(); | ||||
|             b.putParcelable("playlist", playlist); | ||||
|             intent.putExtras(b); | ||||
|             context.startActivity(intent); | ||||
|         }); | ||||
|  | ||||
|         holder.search_container.setOnLongClickListener(v -> { | ||||
|             AlertDialog.Builder builder = new AlertDialog.Builder(context); | ||||
|             builder.setTitle(context.getString(R.string.action_lists_delete) + ": " + playlist.getDisplayName()); | ||||
|             builder.setMessage(context.getString(R.string.action_lists_confirm_delete)); | ||||
|             builder.setIcon(android.R.drawable.ic_dialog_alert) | ||||
|                     .setPositiveButton(R.string.yes, (dialog, which) -> { | ||||
|                         playlists.remove(playlist); | ||||
|                         playlistAdapter.notifyDataSetChanged(); | ||||
|                         new ManagePlaylistsAsyncTask(context, ManagePlaylistsAsyncTask.action.DELETE_PLAYLIST, playlist, null, null, PlaylistAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|                         if (playlists.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE) | ||||
|                             textviewNoAction.setVisibility(View.VISIBLE); | ||||
|                         dialog.dismiss(); | ||||
|                     }) | ||||
|                     .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) | ||||
|                     .show(); | ||||
|  | ||||
|             return false; | ||||
|         }); | ||||
|         return convertView; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private static class ViewHolder { | ||||
|         LinearLayout search_container; | ||||
|         TextView search_title; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,417 @@ | ||||
| package app.fedilab.fedilabtube.fragment; | ||||
|  | ||||
| import android.app.Activity; | ||||
| import android.content.Context; | ||||
| import android.content.DialogInterface; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Bundle; | ||||
| import android.text.InputFilter; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.view.WindowManager; | ||||
| import android.view.inputmethod.InputMethodManager; | ||||
| import android.widget.AdapterView; | ||||
| import android.widget.ArrayAdapter; | ||||
| import android.widget.EditText; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.ListView; | ||||
| import android.widget.RelativeLayout; | ||||
| import android.widget.Spinner; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
|  | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
|  | ||||
| import net.gotev.uploadservice.MultipartUploadRequest; | ||||
| import net.gotev.uploadservice.ServerResponse; | ||||
| import net.gotev.uploadservice.UploadInfo; | ||||
| import net.gotev.uploadservice.UploadNotificationConfig; | ||||
| import net.gotev.uploadservice.UploadStatusDelegate; | ||||
|  | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import java.net.MalformedURLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import app.fedilab.fedilabtube.PlaylistsActivity; | ||||
| import app.fedilab.fedilabtube.R; | ||||
| import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask; | ||||
| import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeChannelsAsyncTask; | ||||
| import app.fedilab.fedilabtube.client.APIResponse; | ||||
| import app.fedilab.fedilabtube.client.entities.Account; | ||||
| import app.fedilab.fedilabtube.client.entities.Playlist; | ||||
| import app.fedilab.fedilabtube.drawer.PlaylistAdapter; | ||||
| import app.fedilab.fedilabtube.helper.Helper; | ||||
| import app.fedilab.fedilabtube.interfaces.OnPlaylistActionInterface; | ||||
| import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface; | ||||
| import es.dmoral.toasty.Toasty; | ||||
|  | ||||
| import static app.fedilab.fedilabtube.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation; | ||||
|  | ||||
|  | ||||
| public class DisplayPlaylistsFragment extends Fragment implements OnPlaylistActionInterface, OnRetrievePeertubeInterface { | ||||
|  | ||||
|  | ||||
|     private Context context; | ||||
|     private AsyncTask<Void, Void, Void> asyncTask; | ||||
|     private List<Playlist> playlists; | ||||
|     private RelativeLayout mainLoader; | ||||
|     private FloatingActionButton add_new; | ||||
|     private PlaylistAdapter playlistAdapter; | ||||
|     private RelativeLayout textviewNoAction; | ||||
|     private HashMap<Integer, String> privacyToSend; | ||||
|     private HashMap<String, String> channelToSend; | ||||
|     private Spinner set_upload_channel; | ||||
|     private Spinner set_upload_privacy; | ||||
|     private HashMap<String, String> channels; | ||||
|  | ||||
|     @Override | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||||
|  | ||||
|         //View for fragment is the same that fragment accounts | ||||
|         View rootView = inflater.inflate(R.layout.fragment_playlists, container, false); | ||||
|  | ||||
|         context = getContext(); | ||||
|         playlists = new ArrayList<>(); | ||||
|  | ||||
|  | ||||
|         ListView lv_playlist = rootView.findViewById(R.id.lv_playlist); | ||||
|         textviewNoAction = rootView.findViewById(R.id.no_action); | ||||
|         mainLoader = rootView.findViewById(R.id.loader); | ||||
|         RelativeLayout nextElementLoader = rootView.findViewById(R.id.loading_next_items); | ||||
|         mainLoader.setVisibility(View.VISIBLE); | ||||
|         nextElementLoader.setVisibility(View.GONE); | ||||
|         playlists = new ArrayList<>(); | ||||
|         playlistAdapter = new PlaylistAdapter(context, playlists, textviewNoAction); | ||||
|         lv_playlist.setAdapter(playlistAdapter); | ||||
|         asyncTask = new ManagePlaylistsAsyncTask(context, ManagePlaylistsAsyncTask.action.GET_PLAYLIST, null, null, null, DisplayPlaylistsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|         add_new = rootView.findViewById(R.id.add_new); | ||||
|  | ||||
|  | ||||
|         LinkedHashMap<String, String> translations = null; | ||||
|         if (peertubeInformation != null && peertubeInformation.getTranslations() != null) | ||||
|             translations = new LinkedHashMap<>(peertubeInformation.getTranslations()); | ||||
|  | ||||
|         LinkedHashMap<Integer, String> privaciesInit = new LinkedHashMap<>(peertubeInformation.getPrivacies()); | ||||
|         Map.Entry<Integer, String> entryInt = privaciesInit.entrySet().iterator().next(); | ||||
|         privacyToSend = new HashMap<>(); | ||||
|         privacyToSend.put(entryInt.getKey(), entryInt.getValue()); | ||||
|         LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies()); | ||||
|         //Populate privacies | ||||
|         Iterator<Map.Entry<Integer, String>> it = privacies.entrySet().iterator(); | ||||
|         while (it.hasNext()) { | ||||
|             it.remove(); | ||||
|         } | ||||
|  | ||||
|         if (add_new != null) { | ||||
|             add_new.setOnClickListener(view -> { | ||||
|                 final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|                 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context); | ||||
|                 LayoutInflater inflater1 = ((Activity) context).getLayoutInflater(); | ||||
|                 View dialogView = inflater1.inflate(R.layout.add_playlist, new LinearLayout(context), false); | ||||
|                 dialogBuilder.setView(dialogView); | ||||
|                 EditText display_name = dialogView.findViewById(R.id.display_name); | ||||
|                 EditText description = dialogView.findViewById(R.id.description); | ||||
|                 set_upload_channel = dialogView.findViewById(R.id.set_upload_channel); | ||||
|                 set_upload_privacy = dialogView.findViewById(R.id.set_upload_privacy); | ||||
|  | ||||
|  | ||||
|                 new RetrievePeertubeChannelsAsyncTask(context, DisplayPlaylistsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|  | ||||
|                 display_name.setFilters(new InputFilter[]{new InputFilter.LengthFilter(120)}); | ||||
|                 description.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1000)}); | ||||
|  | ||||
|                 dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { | ||||
|                     @Override | ||||
|                     public void onClick(DialogInterface dialog, int id) { | ||||
|  | ||||
|                         if (display_name.getText() != null && display_name.getText().toString().trim().length() > 0) { | ||||
|  | ||||
|                             Playlist playlist = new Playlist(); | ||||
|                             playlist.setDisplayName(display_name.getText().toString().trim()); | ||||
|                             if (description.getText() != null && description.getText().toString().trim().length() > 0) { | ||||
|                                 playlist.setDescription(description.getText().toString().trim()); | ||||
|                             } | ||||
|                             String idChannel = null; | ||||
|                             if (channelToSend != null) { | ||||
|                                 Map.Entry<String, String> channelM = channelToSend.entrySet().iterator().next(); | ||||
|                                 idChannel = channelM.getValue(); | ||||
|                                 if (idChannel.length() > 0) | ||||
|                                     playlist.setVideoChannelId(idChannel); | ||||
|                             } | ||||
|                             Map.Entry<Integer, String> privacyM = privacyToSend.entrySet().iterator().next(); | ||||
|                             String label = privacyM.getValue(); | ||||
|                             String idPrivacy = String.valueOf(privacyM.getKey()); | ||||
|                             if (label.equals("Public") && (playlist.getVideoChannelId() == null || playlist.getVideoChannelId().equals(""))) { | ||||
|                                 Toasty.error(context, context.getString(R.string.error_channel_mandatory), Toast.LENGTH_LONG).show(); | ||||
|                             } else { | ||||
|                                 if (privacyToSend != null) { | ||||
|                                     playlist.setPrivacy(privacyToSend); | ||||
|                                 } | ||||
|                                 //new ManagePlaylistsAsyncTask(context, ManagePlaylistsAsyncTask.action.CREATE_PLAYLIST, playlist, null, null, DisplayPlaylistsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
|                                 UploadNotificationConfig uploadConfig = new UploadNotificationConfig(); | ||||
|                                 uploadConfig.getCompleted().autoClear = true; | ||||
|                                 try { | ||||
|                                     String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); | ||||
|                                     new MultipartUploadRequest(context, "https://" + Helper.getLiveInstance(context) + "/api/v1/video-playlists/") | ||||
|                                             //.addFileToUpload(uri.toString().replace("file://",""), "videofile") | ||||
|                                             .addHeader("Authorization", "Bearer " + token) | ||||
|                                             .setNotificationConfig(uploadConfig) | ||||
|                                             // .addParameter("name", filename) | ||||
|                                             .addParameter("videoChannelId", idChannel) | ||||
|                                             .addParameter("privacy", idPrivacy) | ||||
|                                             .addParameter("displayName", playlist.getDisplayName()) | ||||
|                                             .addParameter("description", playlist.getDescription()) | ||||
|                                             .setMaxRetries(1) | ||||
|                                             .setDelegate(new UploadStatusDelegate() { | ||||
|                                                 @Override | ||||
|                                                 public void onProgress(Context context, UploadInfo uploadInfo) { | ||||
|                                                     // your code here | ||||
|                                                 } | ||||
|  | ||||
|                                                 @Override | ||||
|                                                 public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, | ||||
|                                                                     Exception exception) { | ||||
|                                                     // your code here | ||||
|                                                     exception.printStackTrace(); | ||||
|                                                 } | ||||
|  | ||||
|                                                 @Override | ||||
|                                                 public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { | ||||
|                                                     DisplayPlaylistsFragment displayPlaylistsFragment; | ||||
|                                                     if (getActivity() == null) | ||||
|                                                         return; | ||||
|                                                     displayPlaylistsFragment = (DisplayPlaylistsFragment) getActivity().getSupportFragmentManager().findFragmentByTag("PLAYLISTS"); | ||||
|                                                     final FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); | ||||
|                                                     if (displayPlaylistsFragment != null) { | ||||
|                                                         ft.detach(displayPlaylistsFragment); | ||||
|                                                         ft.attach(displayPlaylistsFragment); | ||||
|                                                         ft.commit(); | ||||
|                                                     } | ||||
|                                                 } | ||||
|  | ||||
|                                                 @Override | ||||
|                                                 public void onCancelled(Context context, UploadInfo uploadInfo) { | ||||
|                                                     // your code here | ||||
|                                                 } | ||||
|                                             }) | ||||
|                                             .startUpload(); | ||||
|                                 } catch (MalformedURLException e) { | ||||
|                                     e.printStackTrace(); | ||||
|                                 } | ||||
|  | ||||
|                                 dialog.dismiss(); | ||||
|                                 add_new.setEnabled(false); | ||||
|                             } | ||||
|                         } else { | ||||
|                             Toasty.error(context, context.getString(R.string.error_display_name), Toast.LENGTH_LONG).show(); | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|                 }); | ||||
|                 dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); | ||||
|  | ||||
|  | ||||
|                 AlertDialog alertDialog = dialogBuilder.create(); | ||||
|                 alertDialog.setTitle(getString(R.string.action_playlist_create)); | ||||
|                 alertDialog.setOnDismissListener(dialogInterface -> { | ||||
|                     //Hide keyboard | ||||
|                     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); | ||||
|                     assert imm != null; | ||||
|                     imm.hideSoftInputFromWindow(display_name.getWindowToken(), 0); | ||||
|                 }); | ||||
|                 if (alertDialog.getWindow() != null) | ||||
|                     alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); | ||||
|                 alertDialog.show(); | ||||
|             }); | ||||
|         } | ||||
|         return rootView; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate(Bundle saveInstance) { | ||||
|         super.onCreate(saveInstance); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onAttach(@NotNull Context context) { | ||||
|         super.onAttach(context); | ||||
|         this.context = context; | ||||
|     } | ||||
|  | ||||
|     public void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         if (asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING) | ||||
|             asyncTask.cancel(true); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { | ||||
|         mainLoader.setVisibility(View.GONE); | ||||
|         add_new.setEnabled(true); | ||||
|         if (apiResponse.getError() != null) { | ||||
|             Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (actionType == ManagePlaylistsAsyncTask.action.GET_PLAYLIST) { | ||||
|             if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) { | ||||
|                 this.playlists.addAll(apiResponse.getPlaylists()); | ||||
|                 playlistAdapter.notifyDataSetChanged(); | ||||
|                 textviewNoAction.setVisibility(View.GONE); | ||||
|             } else { | ||||
|                 textviewNoAction.setVisibility(View.VISIBLE); | ||||
|             } | ||||
|         } else if (actionType == ManagePlaylistsAsyncTask.action.CREATE_PLAYLIST) { | ||||
|             if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) { | ||||
|                 Intent intent = new Intent(context, PlaylistsActivity.class); | ||||
|                 Bundle b = new Bundle(); | ||||
|                 b.putParcelable("playlist", apiResponse.getPlaylists().get(0)); | ||||
|                 intent.putExtras(b); | ||||
|                 context.startActivity(intent); | ||||
|                 this.playlists.add(0, apiResponse.getPlaylists().get(0)); | ||||
|                 playlistAdapter.notifyDataSetChanged(); | ||||
|                 textviewNoAction.setVisibility(View.GONE); | ||||
|             } else { | ||||
|                 Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             } | ||||
|         } else if (actionType == ManagePlaylistsAsyncTask.action.DELETE_PLAYLIST) { | ||||
|             if (this.playlists.size() == 0) | ||||
|                 textviewNoAction.setVisibility(View.VISIBLE); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertube(APIResponse apiResponse) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertubeComments(APIResponse apiResponse) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRetrievePeertubeChannels(APIResponse apiResponse) { | ||||
|         if (apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0) { | ||||
|             if (apiResponse.getError() != null && apiResponse.getError().getError() != null) | ||||
|                 Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); | ||||
|             else | ||||
|                 Toasty.error(context, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         //Populate channels | ||||
|         List<Account> accounts = apiResponse.getAccounts(); | ||||
|         String[] channelName = new String[accounts.size() + 1]; | ||||
|         String[] channelId = new String[accounts.size() + 1]; | ||||
|         int i = 1; | ||||
|         channelName[0] = ""; | ||||
|         channelId[0] = ""; | ||||
|         channels = new HashMap<>(); | ||||
|         for (Account account : accounts) { | ||||
|             channels.put(account.getUsername(), account.getId()); | ||||
|             channelName[i] = account.getUsername(); | ||||
|             channelId[i] = account.getId(); | ||||
|             i++; | ||||
|         } | ||||
|  | ||||
|         channelToSend = new HashMap<>(); | ||||
|         channelToSend.put(channelName[0], channelId[0]); | ||||
|         ArrayAdapter<String> adapterChannel = new ArrayAdapter<>(context, | ||||
|                 android.R.layout.simple_spinner_dropdown_item, channelName); | ||||
|         set_upload_channel.setAdapter(adapterChannel); | ||||
|  | ||||
|         LinkedHashMap<String, String> translations = null; | ||||
|         if (peertubeInformation.getTranslations() != null) | ||||
|             translations = new LinkedHashMap<>(peertubeInformation.getTranslations()); | ||||
|  | ||||
|         LinkedHashMap<Integer, String> privaciesInit = new LinkedHashMap<>(peertubeInformation.getPlaylistPrivacies()); | ||||
|         Map.Entry<Integer, String> entryInt = privaciesInit.entrySet().iterator().next(); | ||||
|         privacyToSend = new HashMap<>(); | ||||
|         privacyToSend.put(entryInt.getKey(), entryInt.getValue()); | ||||
|         LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPlaylistPrivacies()); | ||||
|         //Populate privacies | ||||
|         String[] privaciesA = new String[privacies.size()]; | ||||
|         Iterator<Map.Entry<Integer, String>> it = privacies.entrySet().iterator(); | ||||
|         i = 0; | ||||
|         while (it.hasNext()) { | ||||
|             Map.Entry<Integer, String> pair = it.next(); | ||||
|             if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue())) | ||||
|                 privaciesA[i] = pair.getValue(); | ||||
|             else | ||||
|                 privaciesA[i] = translations.get(pair.getValue()); | ||||
|             it.remove(); | ||||
|             i++; | ||||
|         } | ||||
|  | ||||
|         ArrayAdapter<String> adapterPrivacies = new ArrayAdapter<>(context, | ||||
|                 android.R.layout.simple_spinner_dropdown_item, privaciesA); | ||||
|         set_upload_privacy.setAdapter(adapterPrivacies); | ||||
|  | ||||
|         //Manage privacies | ||||
|         set_upload_privacy.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies()); | ||||
|                 Iterator<Map.Entry<Integer, String>> it = privaciesCheck.entrySet().iterator(); | ||||
|                 int i = 0; | ||||
|                 while (it.hasNext()) { | ||||
|                     Map.Entry<Integer, String> pair = it.next(); | ||||
|                     if (i == position) { | ||||
|                         privacyToSend = new HashMap<>(); | ||||
|                         privacyToSend.put(pair.getKey(), pair.getValue()); | ||||
|                         break; | ||||
|                     } | ||||
|                     it.remove(); | ||||
|                     i++; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|         //Manage languages | ||||
|         set_upload_channel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels); | ||||
|                 Iterator<Map.Entry<String, String>> it = channelsCheck.entrySet().iterator(); | ||||
|                 int i = 0; | ||||
|                 while (it.hasNext()) { | ||||
|                     Map.Entry<String, String> pair = it.next(); | ||||
|                     if (i == position) { | ||||
|                         channelToSend = new HashMap<>(); | ||||
|                         channelToSend.put(pair.getKey(), pair.getValue()); | ||||
|                         break; | ||||
|                     } | ||||
|                     it.remove(); | ||||
|                     i++; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_add_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_add_24.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|         android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" /> | ||||
| </vector> | ||||
| @@ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|         android:pathData="M5.88,4.12L13.76,12l-7.88,7.88L8,22l10,-10L8,2z" /> | ||||
| </vector> | ||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_playlist_play_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_playlist_play_24.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|         android:pathData="M4,10h12v2L4,12zM4,6h12v2L4,8zM4,14h8v2L4,16zM14,14v6l5,-3z" /> | ||||
| </vector> | ||||
							
								
								
									
										74
									
								
								app/src/main/res/layout/activity_all_playlist.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/src/main/res/layout/activity_all_playlist.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:paddingLeft="@dimen/fab_margin" | ||||
|     android:paddingRight="@dimen/fab_margin"> | ||||
|  | ||||
|     <ListView | ||||
|         android:id="@+id/lv_playlist" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:divider="@null" | ||||
|         android:scrollbars="none" /> | ||||
|  | ||||
|     <com.google.android.material.floatingactionbutton.FloatingActionButton | ||||
|         android:id="@+id/add_new" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_alignParentEnd="true" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_margin="@dimen/fab_margin_floating" | ||||
|         android:contentDescription="@string/action_playlist_create" | ||||
|         android:src="@drawable/ic_baseline_add_24" | ||||
|         android:tint="@android:color/white" /> | ||||
|  | ||||
|     <RelativeLayout | ||||
|         android:id="@+id/no_action" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:visibility="gone"> | ||||
|  | ||||
|         <TextView | ||||
|             android:id="@+id/no_action_text" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_gravity="center" | ||||
|             android:gravity="center" | ||||
|             android:padding="10dp" | ||||
|             android:text="@string/action_playlist_add" | ||||
|             android:textSize="25sp" | ||||
|             android:textStyle="italic|bold" | ||||
|             android:typeface="serif" /> | ||||
|     </RelativeLayout> | ||||
|     <!-- Main Loader --> | ||||
|     <RelativeLayout | ||||
|         android:id="@+id/loader" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:gravity="center" | ||||
|         android:visibility="gone"> | ||||
|  | ||||
|         <ProgressBar | ||||
|             android:layout_width="wrap_content" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:indeterminate="true" /> | ||||
|     </RelativeLayout> | ||||
|     <!-- Loader for next items --> | ||||
|     <RelativeLayout | ||||
|         android:id="@+id/loading_next_items" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="20dp" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_gravity="bottom|center_horizontal" | ||||
|         android:gravity="bottom|center_horizontal" | ||||
|         android:visibility="gone"> | ||||
|  | ||||
|         <ProgressBar | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:indeterminate="true" /> | ||||
|     </RelativeLayout> | ||||
|  | ||||
| </RelativeLayout> | ||||
|  | ||||
							
								
								
									
										78
									
								
								app/src/main/res/layout/activity_playlists.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								app/src/main/res/layout/activity_playlists.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:id="@+id/drawer_layout" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:fitsSystemWindows="true"> | ||||
|  | ||||
|     <androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         tools:context="app.fedilab.android.activities.PlaylistsActivity"> | ||||
|  | ||||
|         <RelativeLayout | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:padding="@dimen/fab_margin"> | ||||
|  | ||||
|             <androidx.swiperefreshlayout.widget.SwipeRefreshLayout | ||||
|                 android:id="@+id/swipeContainer" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent"> | ||||
|  | ||||
|                 <androidx.recyclerview.widget.RecyclerView | ||||
|                     android:id="@+id/lv_playlist" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:scrollbars="none" /> | ||||
|             </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> | ||||
|  | ||||
|             <RelativeLayout | ||||
|                 android:id="@+id/no_action" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:visibility="gone"> | ||||
|  | ||||
|                 <TextView | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:layout_gravity="center" | ||||
|                     android:gravity="center" | ||||
|                     android:padding="10dp" | ||||
|                     android:text="@string/action_playlist_empty_content" | ||||
|                     android:textSize="25sp" | ||||
|                     android:textStyle="italic|bold" | ||||
|                     android:typeface="serif" /> | ||||
|             </RelativeLayout> | ||||
|             <!-- Main Loader --> | ||||
|             <RelativeLayout | ||||
|                 android:id="@+id/loader" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:gravity="center" | ||||
|                 android:visibility="gone"> | ||||
|  | ||||
|                 <ProgressBar | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:indeterminate="true" /> | ||||
|             </RelativeLayout> | ||||
|             <!-- Loader for next status --> | ||||
|             <RelativeLayout | ||||
|                 android:id="@+id/loading_next_status" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="20dp" | ||||
|                 android:layout_alignParentBottom="true" | ||||
|                 android:layout_gravity="bottom|center_horizontal" | ||||
|                 android:gravity="bottom|center_horizontal" | ||||
|                 android:visibility="gone"> | ||||
|  | ||||
|                 <ProgressBar | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent" | ||||
|                     android:indeterminate="true" /> | ||||
|             </RelativeLayout> | ||||
|         </RelativeLayout> | ||||
|     </androidx.coordinatorlayout.widget.CoordinatorLayout> | ||||
| </androidx.drawerlayout.widget.DrawerLayout> | ||||
							
								
								
									
										92
									
								
								app/src/main/res/layout/add_playlist.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								app/src/main/res/layout/add_playlist.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:orientation="vertical" | ||||
|     android:padding="15dp"> | ||||
|  | ||||
|     <TextView | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="10dp" | ||||
|         android:labelFor="@+id/display_name" | ||||
|         android:text="@string/display_name" /> | ||||
|  | ||||
|     <EditText | ||||
|         android:id="@+id/display_name" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="5dp" | ||||
|         android:importantForAutofill="no" | ||||
|         android:inputType="text" | ||||
|         android:singleLine="true" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="10dp" | ||||
|         android:labelFor="@+id/description" | ||||
|         android:text="@string/description" /> | ||||
|  | ||||
|     <EditText | ||||
|         android:id="@+id/description" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="5dp" | ||||
|         android:importantForAutofill="no" | ||||
|         android:inputType="text" | ||||
|         android:maxLines="5" /> | ||||
|     <!-- Videos channels --> | ||||
|     <LinearLayout | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:baselineAligned="false" | ||||
|         android:orientation="horizontal"> | ||||
|  | ||||
|         <LinearLayout | ||||
|             android:layout_width="0dp" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_marginTop="10dp" | ||||
|             android:layout_weight="3" | ||||
|             android:gravity="center_vertical" | ||||
|             android:orientation="vertical"> | ||||
|  | ||||
|             <TextView | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:gravity="center" | ||||
|                 android:text="@string/channel" | ||||
|                 android:textSize="16sp" /> | ||||
|  | ||||
|             <Spinner | ||||
|                 android:id="@+id/set_upload_channel" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:textSize="14sp" /> | ||||
|         </LinearLayout> | ||||
|         <!-- Videos Privacy --> | ||||
|         <LinearLayout | ||||
|             android:layout_width="0dp" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_marginTop="10dp" | ||||
|             android:layout_weight="2" | ||||
|             android:gravity="center_vertical" | ||||
|             android:orientation="vertical"> | ||||
|  | ||||
|             <TextView | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:gravity="center" | ||||
|                 android:text="@string/action_privacy" | ||||
|                 android:textSize="16sp" /> | ||||
|  | ||||
|             <Spinner | ||||
|                 android:id="@+id/set_upload_privacy" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:textSize="14sp" /> | ||||
|         </LinearLayout> | ||||
|     </LinearLayout> | ||||
|  | ||||
|  | ||||
| </LinearLayout> | ||||
							
								
								
									
										23
									
								
								app/src/main/res/layout/drawer_playlist.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/res/layout/drawer_playlist.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:id="@+id/search_container" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:divider="?android:dividerHorizontal" | ||||
|     android:orientation="vertical" | ||||
|     android:paddingTop="5dp" | ||||
|     android:showDividers="end"> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/search_keyword" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_gravity="center" | ||||
|         android:layout_marginTop="5dp" | ||||
|         android:layout_marginBottom="5dp" | ||||
|         android:gravity="center" | ||||
|         android:paddingTop="10dp" | ||||
|         android:paddingBottom="10dp" | ||||
|         android:textSize="18sp" | ||||
|         android:textStyle="bold" /> | ||||
| </LinearLayout> | ||||
| @@ -58,5 +58,15 @@ | ||||
|             android:layout_height="match_parent" | ||||
|             android:indeterminate="true" /> | ||||
|     </RelativeLayout> | ||||
|  | ||||
|     <com.google.android.material.floatingactionbutton.FloatingActionButton | ||||
|         android:id="@+id/add_new" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_gravity="bottom|end" | ||||
|         android:layout_margin="@dimen/fab_margin_floating" | ||||
|         android:contentDescription="@string/action_playlist_create" | ||||
|         android:src="@drawable/ic_baseline_add_24" | ||||
|         android:visibility="gone" /> | ||||
| </RelativeLayout> | ||||
|  | ||||
|   | ||||
| @@ -31,4 +31,9 @@ | ||||
|         android:icon="@drawable/ic_baseline_personal_video_24" | ||||
|         android:title="@string/my_videos" | ||||
|         app:showAsAction="ifRoom" /> | ||||
|     <item | ||||
|         android:id="@+id/action_playlist" | ||||
|         android:icon="@drawable/ic_baseline_playlist_play_24" | ||||
|         android:title="@string/playlists" | ||||
|         app:showAsAction="ifRoom" /> | ||||
| </menu> | ||||
|   | ||||
| @@ -5,4 +5,5 @@ | ||||
|     <dimen name="fab_margin">5dp</dimen> | ||||
|     <dimen name="drawer_padding">2dp</dimen> | ||||
|     <dimen name="layout_height_header">100dp</dimen> | ||||
|     <dimen name="fab_margin_floating">16dp</dimen> | ||||
| </resources> | ||||
| @@ -145,4 +145,12 @@ | ||||
|     <string name="action_logout">Déconnexion</string> | ||||
|     <string name="logout_account_confirmation">Voulez-vous vraiment déconnecter le compte @%1$s ?</string> | ||||
|  | ||||
|     <string name="action_lists_delete">Supprimer la liste de lecture</string> | ||||
|     <string name="action_lists_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette liste de lecture ?</string> | ||||
|     <string name="action_playlist_create">Créer une liste de lecture</string> | ||||
|     <string name="display_name">Nom d\'affichage</string> | ||||
|     <string name="error_channel_mandatory">Un canal est requis lorsque la liste de lecture est publique.</string> | ||||
|     <string name="error_display_name">Vous devez fournir un nom d\'affichage !</string> | ||||
|     <string name="action_playlist_empty_content">Cette liste de lecture est vide.</string> | ||||
|     <string name="playlists">Listes de lecture</string> | ||||
| </resources> | ||||
		Reference in New Issue
	
	Block a user