other new features
- check for updates when app launches - remove scrollview so that recyclerview can recycle. It wont hide the top bar but thats a sacrifice for the greater good. - remove download all mini card and made it into a floating action button - made video loading from playlists as fast as possible even if you have thousands of videos in a list. It adds videos in recyclerview in a form of pagination - fixed preferences when you just installed the app and you never opened the preference screen you can still download without erroring out
This commit is contained in:
parent
b81add6008
commit
709a3778a2
23 changed files with 505 additions and 488 deletions
|
|
@ -67,13 +67,13 @@
|
|||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/download_all_card.xml" value="0.25" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/empty_history_hint.xml" value="0.2" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.25" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.16" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_more.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_music_editor.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_settings.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_bottom_sheet.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_card.xml" value="0.1" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_card_shimmer.xml" value="0.22" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_card.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_card_shimmer.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_no_results.xml" value="0.21" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/home_download_all_bottom_sheet.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/home_video_bottom_sheet.xml" value="0.1703125" />
|
||||
|
|
|
|||
|
|
@ -21,6 +21,6 @@ public class ExampleInstrumentedTest {
|
|||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
assertEquals("com.yausername.youtubedl_android_example", appContext.getPackageName());
|
||||
assertEquals("com.deniscerri.ytdl", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
package com.deniscerri.ytdl;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Environment;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.deniscerri.ytdl.util.NotificationUtil;
|
||||
import com.deniscerri.ytdl.util.UpdateUtil;
|
||||
import com.google.android.material.color.DynamicColors;
|
||||
import com.yausername.ffmpeg.FFmpeg;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
import com.yausername.youtubedl_android.YoutubeDLException;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.exceptions.UndeliverableException;
|
||||
|
|
@ -30,6 +39,7 @@ public class App extends Application {
|
|||
notificationUtil = new NotificationUtil(this);
|
||||
createNotificationChannels();
|
||||
|
||||
PreferenceManager.setDefaultValues(this, "root_preferences", this.MODE_PRIVATE, R.xml.root_preferences, false);
|
||||
configureRxJavaErrorHandler();
|
||||
Completable.fromAction(this::initLibraries).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new DisposableCompletableObserver() {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@ import android.util.Log;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.deniscerri.ytdl.databinding.ActivityMainBinding;
|
||||
import com.deniscerri.ytdl.page.HistoryFragment;
|
||||
import com.deniscerri.ytdl.page.HomeFragment;
|
||||
import com.deniscerri.ytdl.page.MoreFragment;
|
||||
import com.deniscerri.ytdl.page.MusicEditorFragment;
|
||||
import com.deniscerri.ytdl.page.settings.SettingsActivity;
|
||||
import com.deniscerri.ytdl.page.settings.SettingsFragment;
|
||||
import com.deniscerri.ytdl.util.UpdateUtil;
|
||||
|
||||
|
||||
public class MainActivity extends AppCompatActivity{
|
||||
|
|
@ -27,7 +30,6 @@ public class MainActivity extends AppCompatActivity{
|
|||
|
||||
private HomeFragment homeFragment;
|
||||
private HistoryFragment historyFragment;
|
||||
private MusicEditorFragment musicEditorFragment;
|
||||
private MoreFragment moreFragment;
|
||||
|
||||
private Fragment lastFragment;
|
||||
|
|
@ -58,15 +60,15 @@ public class MainActivity extends AppCompatActivity{
|
|||
|
||||
setContentView(R.layout.activity_main);
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
context = getBaseContext();
|
||||
|
||||
checkUpdate();
|
||||
|
||||
fm = getSupportFragmentManager();
|
||||
|
||||
homeFragment = new HomeFragment();
|
||||
historyFragment = new HistoryFragment();
|
||||
moreFragment = new MoreFragment();
|
||||
musicEditorFragment = new MusicEditorFragment();
|
||||
|
||||
initFragments();
|
||||
|
||||
|
|
@ -94,8 +96,6 @@ public class MainActivity extends AppCompatActivity{
|
|||
this.setTitle(getString(R.string.more));
|
||||
}
|
||||
replaceFragment(moreFragment);
|
||||
}else if(id == R.id.music_editor){
|
||||
replaceFragment(musicEditorFragment);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
|
@ -114,9 +114,9 @@ public class MainActivity extends AppCompatActivity{
|
|||
if(Intent.ACTION_SEND.equals(action)){
|
||||
Log.e(TAG, action);
|
||||
|
||||
|
||||
homeFragment = new HomeFragment();
|
||||
historyFragment = new HistoryFragment();
|
||||
moreFragment = new MoreFragment();
|
||||
|
||||
homeFragment.handleIntent(intent);
|
||||
initFragments();
|
||||
|
|
@ -128,10 +128,8 @@ public class MainActivity extends AppCompatActivity{
|
|||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, historyFragment)
|
||||
.add(R.id.frame_layout, moreFragment)
|
||||
.add(R.id.frame_layout, musicEditorFragment)
|
||||
.hide(historyFragment)
|
||||
.hide(moreFragment)
|
||||
.hide(musicEditorFragment)
|
||||
.commit();
|
||||
|
||||
lastFragment = homeFragment;
|
||||
|
|
@ -156,4 +154,8 @@ public class MainActivity extends AppCompatActivity{
|
|||
isDownloadServiceRunning = false;
|
||||
}
|
||||
|
||||
private void checkUpdate(){
|
||||
UpdateUtil updateUtil = new UpdateUtil(this);
|
||||
updateUtil.updateApp();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
|||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
|
@ -27,11 +28,13 @@ import java.util.ArrayList;
|
|||
|
||||
public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerViewAdapter.ViewHolder> {
|
||||
private ArrayList<Video> videoList;
|
||||
private ArrayList<MaterialCardView> checkedVideos;
|
||||
private final OnItemClickListener onItemClickListener;
|
||||
private Activity activity;
|
||||
|
||||
public HomeRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Activity activity){
|
||||
this.videoList = videos;
|
||||
this.checkedVideos = new ArrayList<>();
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
this.activity = activity;
|
||||
}
|
||||
|
|
@ -56,6 +59,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
|
|||
View cardView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.result_card, parent, false);
|
||||
|
||||
checkedVideos = new ArrayList<>();
|
||||
return new HomeRecyclerViewAdapter.ViewHolder(cardView, onItemClickListener);
|
||||
}
|
||||
|
||||
|
|
@ -116,15 +120,27 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
|
|||
card.setChecked(false);
|
||||
card.setStrokeWidth(0);
|
||||
card.setTag(videoID + "##card");
|
||||
card.setOnClickListener(view -> {
|
||||
if(card.isChecked()){
|
||||
card.setStrokeWidth(0);
|
||||
}else{
|
||||
card.setStrokeWidth(5);
|
||||
}
|
||||
card.setChecked(!card.isChecked());
|
||||
onItemClickListener.onCardClick(position, card.isChecked());
|
||||
card.setOnLongClickListener(view -> {
|
||||
checkCard(card, position);
|
||||
return true;
|
||||
});
|
||||
card.setOnClickListener(view -> {
|
||||
if(checkedVideos.size() > 0){
|
||||
checkCard(card, position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkCard(MaterialCardView card, int position){
|
||||
if(card.isChecked()){
|
||||
card.setStrokeWidth(0);
|
||||
checkedVideos.remove(card);
|
||||
}else{
|
||||
card.setStrokeWidth(5);
|
||||
checkedVideos.add(card);
|
||||
}
|
||||
card.setChecked(!card.isChecked());
|
||||
onItemClickListener.onCardClick(position, card.isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -137,9 +153,13 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
|
|||
void onCardClick(int position, boolean add);
|
||||
}
|
||||
|
||||
public void setVideoList(ArrayList<Video> videoList){
|
||||
this.videoList = videoList;
|
||||
notifyDataSetChanged();
|
||||
public void setVideoList(ArrayList<Video> list, boolean reset){
|
||||
int size = videoList.size();
|
||||
if(reset || size == 0){
|
||||
videoList = new ArrayList<>();
|
||||
}
|
||||
videoList.addAll(list);
|
||||
notifyItemRangeInserted(size, videoList.size());
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -46,6 +47,7 @@ public class YoutubeAPIManager {
|
|||
}
|
||||
|
||||
public ArrayList<Video> search(String query) throws JSONException{
|
||||
videos = new ArrayList<>();
|
||||
//short data
|
||||
JSONObject res = genericRequest("https://youtube.googleapis.com/youtube/v3/search?part=snippet&q="+query+"&maxResults=25®ionCode="+countryCODE+"&key="+key);
|
||||
JSONArray dataArray = res.getJSONArray("items");
|
||||
|
|
@ -91,7 +93,9 @@ public class YoutubeAPIManager {
|
|||
return videos;
|
||||
}
|
||||
|
||||
public ArrayList<Video> getPlaylist(String id, String nextPageToken) throws JSONException{
|
||||
public PlaylistTuple getPlaylist(String id, String nextPageToken) throws JSONException{
|
||||
videos = new ArrayList<>();
|
||||
|
||||
String url = "https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&pageToken="+nextPageToken+"&maxResults=50®ionCode="+countryCODE+"&playlistId="+id+"&key="+key;
|
||||
//short data
|
||||
JSONObject res = genericRequest(url);
|
||||
|
|
@ -131,11 +135,7 @@ public class YoutubeAPIManager {
|
|||
videos.add(v);
|
||||
}
|
||||
String next = res.optString("nextPageToken");
|
||||
if(next != ""){
|
||||
ArrayList<Video> nextPage = getPlaylist(id,next);
|
||||
}
|
||||
|
||||
return videos;
|
||||
return new PlaylistTuple(next, videos);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -323,5 +323,62 @@ public class YoutubeAPIManager {
|
|||
return duration;
|
||||
}
|
||||
|
||||
// public ArrayList<String> getSearchHints(String query){
|
||||
// String url = "https://google.com/complete/search?client=youtube&q="+query;
|
||||
// ArrayList<String> searchHints = new ArrayList<>();
|
||||
//
|
||||
// BufferedReader reader;
|
||||
// String line;
|
||||
// StringBuilder responseContent = new StringBuilder();
|
||||
// HttpURLConnection conn;
|
||||
// JSONArray json;
|
||||
//
|
||||
// try{
|
||||
// URL req = new URL(url);
|
||||
// conn = (HttpURLConnection) req.openConnection();
|
||||
//
|
||||
// conn.setRequestMethod("GET");
|
||||
// conn.setConnectTimeout(10000);
|
||||
// conn.setReadTimeout(5000);
|
||||
//
|
||||
// if(conn.getResponseCode() < 300){
|
||||
// reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
// while((line = reader.readLine()) != null){
|
||||
// responseContent.append(line);
|
||||
// }
|
||||
// reader.close();
|
||||
// String content = responseContent.substring(19, responseContent.length()-1);
|
||||
//
|
||||
// json = new JSONArray(content);
|
||||
// JSONArray hints = (JSONArray) json.get(1);
|
||||
// for (int i = 0; i < hints.length(); i++){
|
||||
// searchHints.add(hints.getJSONArray(i).get(0).toString());
|
||||
// }
|
||||
// }
|
||||
// conn.disconnect();
|
||||
// }catch(Exception e){
|
||||
// Log.e(TAG, e.toString());
|
||||
// }
|
||||
// return searchHints;
|
||||
// }
|
||||
|
||||
public class PlaylistTuple {
|
||||
String nextPageToken;
|
||||
ArrayList<Video> videos;
|
||||
|
||||
PlaylistTuple(String token, ArrayList<Video> videos){
|
||||
nextPageToken = token;
|
||||
this.videos = videos;
|
||||
}
|
||||
|
||||
public String getNextPageToken() {
|
||||
return nextPageToken;
|
||||
}
|
||||
|
||||
public ArrayList<Video> getVideos() {
|
||||
return videos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,8 +153,6 @@ public class DBManager extends SQLiteOpenHelper {
|
|||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
db.execSQL("DELETE FROM " + results_table_name);
|
||||
|
||||
for(Video v : videot){
|
||||
values.put(videoId, v.getVideoId());
|
||||
values.put(title, v.getTitle());
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import androidx.core.app.ActivityCompat;
|
|||
import com.deniscerri.ytdl.BuildConfig;
|
||||
import com.deniscerri.ytdl.DownloaderService;
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.deniscerri.ytdl.page.settings.SettingsFragment;
|
||||
import com.deniscerri.ytdl.util.NotificationUtil;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||
|
|
@ -113,12 +114,6 @@ public class CustomCommandActivity extends AppCompatActivity {
|
|||
startDownloadService(getString(R.string.running_ytdlp_command), NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID);
|
||||
text = text.substring(6).trim();
|
||||
|
||||
if (!isStoragePermissionGranted()) {
|
||||
Toast.makeText(context, R.string.try_again_after_permission, Toast.LENGTH_LONG).show();
|
||||
stopDownloadService();
|
||||
return;
|
||||
}
|
||||
|
||||
YoutubeDLRequest request = new YoutubeDLRequest(Collections.emptyList());
|
||||
String commandRegex = "\"([^\"]*)\"|(\\S+)";
|
||||
Matcher m = Pattern.compile(commandRegex).matcher(text);
|
||||
|
|
@ -131,7 +126,7 @@ public class CustomCommandActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
String downloadsDir = sharedPreferences.getString("command_path", "");
|
||||
String downloadsDir = sharedPreferences.getString("command_path", getString(R.string.command_path));
|
||||
File youtubeDLDir = new File(downloadsDir);
|
||||
if (!youtubeDLDir.exists()) {
|
||||
boolean isDirCreated = youtubeDLDir.mkdir();
|
||||
|
|
@ -165,16 +160,6 @@ public class CustomCommandActivity extends AppCompatActivity {
|
|||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
public boolean isStoragePermissionGranted() {
|
||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void startDownloadService(String title, int id){
|
||||
if(isDownloadServiceRunning) return;
|
||||
Intent serviceIntent = new Intent(context, DownloaderService.class);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ import java.util.ArrayList;
|
|||
*/
|
||||
public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdapter.OnItemClickListener, View.OnClickListener{
|
||||
|
||||
private LinearLayout linearLayout;
|
||||
private View fragmentView;
|
||||
private DBManager dbManager;
|
||||
Context context;
|
||||
|
|
@ -52,10 +51,10 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
private ShimmerFrameLayout shimmerCards;
|
||||
private MaterialToolbar topAppBar;
|
||||
private RecyclerView recyclerView;
|
||||
private NestedScrollView scrollView;
|
||||
private HistoryRecyclerViewAdapter historyRecyclerViewAdapter;
|
||||
private BottomSheetDialog bottomSheet;
|
||||
private Handler uiHandler;
|
||||
private RelativeLayout no_results;
|
||||
|
||||
private ArrayList<Video> historyObjects;
|
||||
private static final String TAG = "HistoryFragment";
|
||||
|
|
@ -85,16 +84,15 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
fragmentView = inflater.inflate(R.layout.fragment_history, container, false);
|
||||
context = fragmentView.getContext();
|
||||
layoutinflater = LayoutInflater.from(context);
|
||||
linearLayout = fragmentView.findViewById(R.id.historylinearLayout1);
|
||||
shimmerCards = fragmentView.findViewById(R.id.shimmer_history_framelayout);
|
||||
topAppBar = fragmentView.findViewById(R.id.history_toolbar);
|
||||
no_results = fragmentView.findViewById(R.id.history_no_results);
|
||||
uiHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
dbManager = new DBManager(context);
|
||||
historyObjects = new ArrayList<>();
|
||||
|
||||
recyclerView = fragmentView.findViewById(R.id.recycler_view_history);
|
||||
scrollView = fragmentView.findViewById(R.id.history_scrollview);
|
||||
|
||||
historyRecyclerViewAdapter = new HistoryRecyclerViewAdapter(historyObjects, this, context);
|
||||
recyclerView.setAdapter(historyRecyclerViewAdapter);
|
||||
|
|
@ -110,7 +108,7 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
shimmerCards.startShimmer();
|
||||
shimmerCards.setVisibility(View.VISIBLE);
|
||||
historyRecyclerViewAdapter.clear();
|
||||
linearLayout.removeAllViews();
|
||||
no_results.setVisibility(View.GONE);
|
||||
try{
|
||||
Thread thread = new Thread(() -> {
|
||||
historyObjects = dbManager.getHistory("");
|
||||
|
|
@ -121,7 +119,7 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
});
|
||||
|
||||
if(historyObjects.size() == 0){
|
||||
uiHandler.post(this::addNoResultsView);
|
||||
uiHandler.post(() -> no_results.setVisibility(View.VISIBLE));
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
|
|
@ -132,16 +130,10 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
}
|
||||
|
||||
public void scrollToTop(){
|
||||
scrollView.smoothScrollTo(-100,-100);
|
||||
recyclerView.scrollToPosition(0);
|
||||
new Handler(Looper.getMainLooper()).post(() -> ((AppBarLayout) topAppBar.getParent()).setExpanded(true, true));
|
||||
}
|
||||
|
||||
private void addNoResultsView(){
|
||||
RelativeLayout no_results = new RelativeLayout(context);
|
||||
layoutinflater.inflate(R.layout.history_no_results, no_results);
|
||||
linearLayout.addView(no_results);
|
||||
}
|
||||
|
||||
private void initMenu(){
|
||||
MenuItem.OnActionExpandListener onActionExpandListener = new MenuItem.OnActionExpandListener() {
|
||||
@Override
|
||||
|
|
@ -168,7 +160,7 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
historyRecyclerViewAdapter.clear();
|
||||
historyRecyclerViewAdapter.setVideoList(historyObjects);
|
||||
|
||||
if(historyObjects.size() == 0) addNoResultsView();
|
||||
if(historyObjects.size() == 0) no_results.setVisibility(View.VISIBLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -180,9 +172,10 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
historyRecyclerViewAdapter.setVideoList(historyObjects);
|
||||
|
||||
if (historyObjects.size() == 0) {
|
||||
linearLayout.removeAllViews();
|
||||
addNoResultsView();
|
||||
}else linearLayout.removeAllViews();
|
||||
no_results.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
no_results.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -207,7 +200,7 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
dbManager.clearHistory();
|
||||
historyRecyclerViewAdapter.clear();
|
||||
addNoResultsView();
|
||||
no_results.setVisibility(View.VISIBLE);
|
||||
});
|
||||
delete_dialog.show();
|
||||
return true;
|
||||
|
|
@ -254,7 +247,7 @@ public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdap
|
|||
dbManager.clearHistoryItem(v);
|
||||
|
||||
if(historyObjects.size() == 0){
|
||||
uiHandler.post(this::addNoResultsView);
|
||||
uiHandler.post(() -> no_results.setVisibility(View.VISIBLE));
|
||||
}
|
||||
});
|
||||
delete_dialog.show();
|
||||
|
|
|
|||
|
|
@ -12,25 +12,19 @@ import android.os.Handler;
|
|||
import android.os.Looper;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
|
@ -49,7 +43,7 @@ import com.google.android.material.appbar.AppBarLayout;
|
|||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.yausername.youtubedl_android.DownloadProgressCallback;
|
||||
|
|
@ -79,14 +73,12 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
private View fragmentView;
|
||||
private ProgressBar progressBar;
|
||||
private String inputQuery;
|
||||
private LinearLayout homeLinearLayout;
|
||||
private RecyclerView recyclerView;
|
||||
private HomeRecyclerViewAdapter homeRecyclerViewAdapter;
|
||||
private NestedScrollView scrollView;
|
||||
private ShimmerFrameLayout shimmerCards;
|
||||
private CoordinatorLayout downloadFabs;
|
||||
private CoordinatorLayout downloadAllFab;
|
||||
private BottomSheetDialog bottomSheet;
|
||||
private LayoutInflater layoutinflater;
|
||||
|
||||
Context context;
|
||||
Activity activity;
|
||||
|
|
@ -103,7 +95,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
private Queue<Video> downloadQueue;
|
||||
|
||||
MainActivity mainActivity;
|
||||
private static final NotificationUtil notificationUtil = App.notificationUtil;
|
||||
private final NotificationUtil notificationUtil = App.notificationUtil;
|
||||
|
||||
private final DownloadProgressCallback callback = new DownloadProgressCallback() {
|
||||
@Override
|
||||
|
|
@ -142,16 +134,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
context = fragmentView.getContext();
|
||||
activity = getActivity();
|
||||
mainActivity = (MainActivity) activity;
|
||||
layoutinflater = LayoutInflater.from(context);
|
||||
|
||||
|
||||
//initViews
|
||||
homeLinearLayout = fragmentView.findViewById(R.id.linearLayout1);
|
||||
shimmerCards = fragmentView.findViewById(R.id.shimmer_results_framelayout);
|
||||
topAppBar = fragmentView.findViewById(R.id.home_toolbar);
|
||||
scrollView = fragmentView.findViewById(R.id.home_scrollview);
|
||||
recyclerView = fragmentView.findViewById(R.id.recycler_view_home);
|
||||
downloadFabs = fragmentView.findViewById(R.id.home_download_fabs);
|
||||
downloadFabs = fragmentView.findViewById(R.id.download_selected_coordinator);
|
||||
downloadAllFab = fragmentView.findViewById(R.id.download_all_coordinator);
|
||||
|
||||
homeRecyclerViewAdapter = new HomeRecyclerViewAdapter(resultObjects, this, activity);
|
||||
recyclerView.setAdapter(homeRecyclerViewAdapter);
|
||||
|
|
@ -174,6 +164,11 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
music_fab.setOnClickListener(this);
|
||||
video_fab.setOnClickListener(this);
|
||||
|
||||
|
||||
ExtendedFloatingActionButton download_all_fab = downloadAllFab.findViewById(R.id.download_all_fab);
|
||||
download_all_fab.setTag("downloadAll");
|
||||
download_all_fab.setOnClickListener(this);
|
||||
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
|
|
@ -182,17 +177,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
shimmerCards.startShimmer();
|
||||
shimmerCards.setVisibility(View.VISIBLE);
|
||||
homeRecyclerViewAdapter.clear();
|
||||
homeLinearLayout.removeAllViews();
|
||||
try {
|
||||
Thread thread = new Thread(() -> {
|
||||
Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
dbManager = new DBManager(context);
|
||||
youtubeAPIManager = new YoutubeAPIManager(context);
|
||||
resultObjects = dbManager.getResults();
|
||||
boolean trending = false;
|
||||
|
||||
if (resultObjects.size() == 0) {
|
||||
trending = true;
|
||||
try {
|
||||
resultObjects = youtubeAPIManager.getTrending(context);
|
||||
} catch (Exception e) {
|
||||
|
|
@ -200,20 +192,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}
|
||||
}
|
||||
if (resultObjects != null) {
|
||||
scrollToTop();
|
||||
|
||||
if (trending) {
|
||||
uiHandler.post(this::addTrendingText);
|
||||
|
||||
} else {
|
||||
if (resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) {
|
||||
createDownloadAllCard();
|
||||
}
|
||||
uiHandler.post(this::scrollToTop);
|
||||
if (resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) {
|
||||
uiHandler.post(() -> downloadAllFab.setVisibility(View.VISIBLE));
|
||||
}
|
||||
}
|
||||
|
||||
uiHandler.post(() -> {
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects);
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects, true);
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
});
|
||||
|
|
@ -225,16 +211,18 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}
|
||||
|
||||
private void initMenu() {
|
||||
youtubeAPIManager = new YoutubeAPIManager(context);
|
||||
|
||||
MenuItem.OnActionExpandListener onActionExpandListener = new MenuItem.OnActionExpandListener() {
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(MenuItem menuItem) {
|
||||
scrollView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
|
||||
scrollView.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -254,39 +242,39 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
return false;
|
||||
}
|
||||
public boolean onQueryTextChange(String newText) { return false; }
|
||||
});
|
||||
|
||||
topAppBar.setOnClickListener(view -> scrollToTop());
|
||||
|
||||
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
|
||||
switch (m.getItemId()){
|
||||
case R.id.delete_results:
|
||||
dbManager.clearResults();
|
||||
recyclerView.removeAllViews();
|
||||
initCards();
|
||||
return true;
|
||||
case R.id.refresh_results:
|
||||
recyclerView.removeAllViews();
|
||||
initCards();
|
||||
return true;
|
||||
case R.id.open_settings:
|
||||
Intent intent = new Intent(context, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
int itemId = m.getItemId();
|
||||
if(itemId == R.id.delete_results){
|
||||
dbManager.clearResults();
|
||||
recyclerView.removeAllViews();
|
||||
downloadAllFab.setVisibility(View.GONE);
|
||||
initCards();
|
||||
}else if(itemId == R.id.refresh_results){
|
||||
recyclerView.removeAllViews();
|
||||
selectedObjects = new ArrayList<>();
|
||||
downloadFabs.setVisibility(View.GONE);
|
||||
initCards();
|
||||
}else if(itemId == R.id.open_settings){
|
||||
Intent intent = new Intent(context, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void handleIntent(Intent intent) {
|
||||
inputQuery = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
}
|
||||
|
||||
public void scrollToTop() {
|
||||
scrollView.smoothScrollTo(-100,-100);
|
||||
recyclerView.scrollToPosition(0);
|
||||
new Handler(Looper.getMainLooper()).post(() -> ((AppBarLayout) topAppBar.getParent()).setExpanded(true, true));
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +282,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
shimmerCards.startShimmer();
|
||||
shimmerCards.setVisibility(View.VISIBLE);
|
||||
homeRecyclerViewAdapter.clear();
|
||||
homeLinearLayout.removeAllViews();
|
||||
Log.e(TAG, String.valueOf(homeRecyclerViewAdapter.getItemCount()));
|
||||
|
||||
dbManager = new DBManager(context);
|
||||
youtubeAPIManager = new YoutubeAPIManager(context);
|
||||
|
|
@ -330,10 +318,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
} catch (Exception e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
dbManager.clearResults();
|
||||
dbManager.addToResults(resultObjects);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects);
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects, true);
|
||||
//addEndofResultsText();
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
|
|
@ -371,11 +359,11 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
|
||||
dbManager.clearResults();
|
||||
dbManager.addToResults(resultObjects);
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects);
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects, true);
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
});
|
||||
|
|
@ -396,22 +384,35 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
resultObjects = youtubeAPIManager.getPlaylist(query, "");
|
||||
String nextPageToken = "";
|
||||
dbManager.clearResults();
|
||||
homeRecyclerViewAdapter.setVideoList(new ArrayList<>(), true);
|
||||
do {
|
||||
YoutubeAPIManager.PlaylistTuple tmp = youtubeAPIManager.getPlaylist(query, nextPageToken);
|
||||
ArrayList<Video> tmp_vids = tmp.getVideos();
|
||||
String tmp_token = tmp.getNextPageToken();
|
||||
resultObjects.addAll(tmp_vids);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
homeRecyclerViewAdapter.setVideoList(tmp_vids, false);
|
||||
//addEndofResultsText();
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
});
|
||||
Thread.sleep(1000);
|
||||
dbManager.addToResults(tmp_vids);
|
||||
if (tmp_token.isEmpty()) break;
|
||||
if (tmp_token.equals(nextPageToken)) break;
|
||||
nextPageToken = tmp_token;
|
||||
}while (true);
|
||||
|
||||
// DOWNLOAD ALL BUTTON
|
||||
if (resultObjects.size() > 1) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> downloadAllFab.setVisibility(View.VISIBLE));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
dbManager.addToResults(resultObjects);
|
||||
// DOWNLOAD ALL BUTTON
|
||||
if (resultObjects.size() > 1) {
|
||||
createDownloadAllCard();
|
||||
}
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
homeRecyclerViewAdapter.setVideoList(resultObjects);
|
||||
//addEndofResultsText();
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
|
|
@ -424,24 +425,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
|
||||
}
|
||||
|
||||
private void addTrendingText(){
|
||||
TextView trendingText = new TextView(context);
|
||||
trendingText.setText(R.string.Trending);
|
||||
trendingText.setPadding(70, 0 , 0, 0);
|
||||
homeLinearLayout.addView(trendingText);
|
||||
}
|
||||
|
||||
private void createDownloadAllCard() {
|
||||
RelativeLayout r = new RelativeLayout(context);
|
||||
layoutinflater.inflate(R.layout.download_all_card, r);
|
||||
|
||||
CardView card = r.findViewById(R.id.downloadall_card_view);
|
||||
card.setTag("downloadAll");
|
||||
card.setOnClickListener(this);
|
||||
|
||||
Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
uiHandler.post(() -> homeLinearLayout.addView(r));
|
||||
}
|
||||
|
||||
public Video findVideo(String id) {
|
||||
for (int i = 0; i < resultObjects.size(); i++) {
|
||||
|
|
@ -465,11 +448,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
try {
|
||||
video = videos.peek();
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isStoragePermissionGranted()) {
|
||||
Toast.makeText(context, R.string.try_again_after_permission, Toast.LENGTH_LONG).show();
|
||||
mainActivity.stopDownloadService();
|
||||
return;
|
||||
}
|
||||
|
|
@ -548,8 +526,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
//scroll to Card
|
||||
View view = fragmentView.findViewWithTag(id + "##progress");
|
||||
scrollView.requestChildFocus(view, view);
|
||||
recyclerView.scrollToPosition(resultObjects.indexOf(findVideo(id)));
|
||||
progressBar.setProgress(0);
|
||||
downloading = true;
|
||||
|
||||
|
|
@ -562,8 +539,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
progressBar.setProgress(0);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
//TODO show download finished
|
||||
|
||||
if (theClickedButton != null) {
|
||||
if (type.equals("mp3")) {
|
||||
theClickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
|
||||
|
|
@ -589,8 +564,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Toast.makeText(context, R.string.failed_download, Toast.LENGTH_LONG).show();
|
||||
progressBar.setProgress(0);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
//TODO notification failed
|
||||
downloading = false;
|
||||
|
||||
// SCAN NEXT IN QUEUE
|
||||
|
|
@ -639,10 +612,11 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
String downloadsDir;
|
||||
if (type.equals("mp3")) {
|
||||
downloadsDir = sharedPreferences.getString("music_path", "");
|
||||
downloadsDir = sharedPreferences.getString("music_path", getString(R.string.music_path));
|
||||
} else {
|
||||
downloadsDir = sharedPreferences.getString("video_path", "");
|
||||
downloadsDir = sharedPreferences.getString("video_path", getString(R.string.video_path));
|
||||
}
|
||||
|
||||
File youtubeDLDir = new File(downloadsDir);
|
||||
if (!youtubeDLDir.exists()) {
|
||||
boolean isDirCreated = youtubeDLDir.mkdir();
|
||||
|
|
@ -653,16 +627,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
return youtubeDLDir;
|
||||
}
|
||||
|
||||
public boolean isStoragePermissionGranted() {
|
||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClick(int position, String type) {
|
||||
Log.e(TAG, type);
|
||||
|
|
@ -675,15 +639,38 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Toast.makeText(context, R.string.added_to_queue, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
mainActivity.startDownloadService(vid.getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
if (isStoragePermissionGranted()){
|
||||
mainActivity.startDownloadService(vid.getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStoragePermissionGranted() {
|
||||
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}else{
|
||||
downloadQueue = new LinkedList<>();
|
||||
ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCardClick(int position, boolean add) {
|
||||
Video video = resultObjects.get(position);
|
||||
if (add) selectedObjects.add(video); else selectedObjects.remove(video);
|
||||
if(selectedObjects.size() > 1) downloadFabs.setVisibility(View.VISIBLE); else downloadFabs.setVisibility(View.GONE);
|
||||
if(selectedObjects.size() > 1){
|
||||
downloadAllFab.setVisibility(View.GONE);
|
||||
downloadFabs.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
downloadFabs.setVisibility(View.GONE);
|
||||
if (resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) {
|
||||
downloadAllFab.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -715,8 +702,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Toast.makeText(context, R.string.added_to_queue, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
mainActivity.startDownloadService(downloadQueue.peek().getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
if(isStoragePermissionGranted()){
|
||||
mainActivity.startDownloadService(downloadQueue.peek().getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewIdName.equals("downloadAll")){
|
||||
|
|
@ -782,7 +771,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Toast.makeText(context, R.string.added_to_queue, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
mainActivity.startDownloadService(downloadQueue.peek().getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
if(isStoragePermissionGranted()){
|
||||
mainActivity.startDownloadService(downloadQueue.peek().getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
|
||||
startDownload(downloadQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,12 +29,8 @@ import io.reactivex.schedulers.Schedulers;
|
|||
public class MoreFragment extends PreferenceFragmentCompat {
|
||||
Preference updateYTDL;
|
||||
Preference updateApp;
|
||||
MaterialCardView materialCardView;
|
||||
|
||||
public static boolean updatingYTDL;
|
||||
public static boolean updatingApp;
|
||||
public static final String TAG = "MoreFragment";
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
private UpdateUtil updateUtil;
|
||||
|
||||
|
||||
@Override
|
||||
|
|
@ -44,94 +40,16 @@ public class MoreFragment extends PreferenceFragmentCompat {
|
|||
updateYTDL = findPreference("update_ytdl");
|
||||
updateApp = findPreference("update_app");
|
||||
|
||||
updateUtil = new UpdateUtil(getContext());
|
||||
|
||||
updateYTDL.setOnPreferenceClickListener(preference -> {
|
||||
updateYoutubeDL();
|
||||
updateUtil.updateYoutubeDL();
|
||||
return true;
|
||||
});
|
||||
|
||||
updateApp.setOnPreferenceClickListener(preference -> {
|
||||
updateApp();
|
||||
updateUtil.updateApp();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void updateYoutubeDL() {
|
||||
if (updatingYTDL) {
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_updating_started), Toast.LENGTH_SHORT).show();
|
||||
|
||||
updatingYTDL = true;
|
||||
Disposable disposable = Observable.fromCallable(() -> YoutubeDL.getInstance().updateYoutubeDL(getContext()))
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(status -> {
|
||||
switch (status) {
|
||||
case DONE:
|
||||
Toast.makeText(getContext(), getString(R.string.ytld_update_success), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ALREADY_UP_TO_DATE:
|
||||
Toast.makeText(getContext(), getString(R.string.you_are_in_latest_version), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
default:
|
||||
Toast.makeText(getContext(), status.toString(), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
updatingYTDL = false;
|
||||
}, e -> {
|
||||
if(BuildConfig.DEBUG) Log.e(TAG, getString(R.string.ytdl_update_failed), e);
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_update_failed), Toast.LENGTH_LONG).show();
|
||||
updatingYTDL = false;
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
|
||||
private void updateApp(){
|
||||
if (updatingApp) {
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateUtil updateUtil = new UpdateUtil(getContext());
|
||||
AtomicReference<JSONObject> res = new AtomicReference<>(new JSONObject());
|
||||
|
||||
try{
|
||||
Thread thread = new Thread(() -> res.set(updateUtil.checkForAppUpdate()));
|
||||
thread.start();
|
||||
thread.join();
|
||||
}catch(Exception e){
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
if(res.get() == null){
|
||||
Toast.makeText(getContext(), R.string.error_checking_latest_version, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
String version = "";
|
||||
String body = "";
|
||||
try {
|
||||
version = res.get().getString("tag_name");
|
||||
body = res.get().getString("body");
|
||||
} catch (JSONException ignored) {}
|
||||
|
||||
if(version.equals("v"+BuildConfig.VERSION_NAME)){
|
||||
getActivity().runOnUiThread(() -> Toast.makeText(getContext(), R.string.you_are_running_latest_version, Toast.LENGTH_SHORT).show());
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder updateDialog = new MaterialAlertDialogBuilder(getContext())
|
||||
.setTitle(version)
|
||||
.setMessage(body)
|
||||
.setIcon(R.drawable.ic_update_app)
|
||||
.setNegativeButton("Cancel", (dialogInterface, i) -> {})
|
||||
.setPositiveButton("Update", (dialogInterface, i) -> updateUtil.updateApp(res.get()));
|
||||
updateDialog.show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package com.deniscerri.ytdl.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.deniscerri.ytdl.R;
|
||||
|
||||
public class MusicEditorFragment extends Fragment {
|
||||
|
||||
public MusicEditorFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_music_editor, container, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package com.deniscerri.ytdl.page.settings;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
|
@ -12,6 +15,7 @@ import androidx.activity.result.ActivityResultCallback;
|
|||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
|
@ -20,6 +24,7 @@ import androidx.preference.SeekBarPreference;
|
|||
import androidx.preference.SwitchPreferenceCompat;
|
||||
import com.deniscerri.ytdl.BuildConfig;
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.deniscerri.ytdl.util.UpdateUtil;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
|
@ -49,10 +54,11 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
|
||||
Preference version;
|
||||
|
||||
private UpdateUtil updateUtil;
|
||||
|
||||
public static final int MUSIC_PATH_CODE = 33333;
|
||||
public static final int VIDEO_PATH_CODE = 55555;
|
||||
public static final int COMMAND_PATH_CODE = 77777;
|
||||
private static boolean firstRun = true;
|
||||
private static final String TAG = "SettingsFragment";
|
||||
|
||||
|
||||
|
|
@ -60,6 +66,16 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey);
|
||||
|
||||
updateUtil = new UpdateUtil(requireContext());
|
||||
|
||||
initPreferences();
|
||||
initListeners();
|
||||
}
|
||||
|
||||
private void initPreferences(){
|
||||
SharedPreferences preferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
musicPath = findPreference("music_path");
|
||||
videoPath = findPreference("video_path");
|
||||
commandPath = findPreference("command_path");
|
||||
|
|
@ -79,24 +95,14 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
version = findPreference("version");
|
||||
version.setSummary(BuildConfig.VERSION_NAME);
|
||||
|
||||
if(firstRun){
|
||||
initPreferences();
|
||||
if (preferences.getString("music_path", "").isEmpty()){
|
||||
editor.putString("music_path", getString(R.string.music_path));
|
||||
}
|
||||
initListeners();
|
||||
}
|
||||
|
||||
private void initPreferences(){
|
||||
SharedPreferences preferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
if(preferences.getString("music_path", "").isEmpty()){
|
||||
editor.putString("music_path", "/storage/emulated/0/Music/");
|
||||
if (preferences.getString("video_path", "").isEmpty()){
|
||||
editor.putString("video_path", getString(R.string.video_path));
|
||||
}
|
||||
if(preferences.getString("video_path", "").isEmpty()){
|
||||
editor.putString("video_path", "/storage/emulated/0/Movies/");
|
||||
}
|
||||
if(preferences.getString("command_path", "").isEmpty()){
|
||||
editor.putString("command_path", "/storage/emulated/0/Download");
|
||||
if (preferences.getString("command_path", "").isEmpty()){
|
||||
editor.putString("command_path", getString(R.string.command_path));
|
||||
}
|
||||
|
||||
editor.putInt("concurrent_fragments", concurrentFragments.getValue());
|
||||
|
|
@ -111,7 +117,6 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
editor.putInt("audio_quality", audioQuality.getValue());
|
||||
|
||||
editor.apply();
|
||||
firstRun = false;
|
||||
}
|
||||
|
||||
private void initListeners(){
|
||||
|
|
@ -209,6 +214,11 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
return true;
|
||||
});
|
||||
|
||||
version.setOnPreferenceClickListener(preference -> {
|
||||
updateUtil.updateApp();
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> musicPathResultLauncher = registerForActivityResult(
|
||||
|
|
|
|||
|
|
@ -10,25 +10,81 @@ import android.util.Log;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.deniscerri.ytdl.App;
|
||||
import com.deniscerri.ytdl.BuildConfig;
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class UpdateUtil {
|
||||
Context context;
|
||||
private final String TAG = "UpdateUtil";
|
||||
private DownloadManager downloadManager;
|
||||
public static boolean updatingYTDL;
|
||||
public static boolean updatingApp;
|
||||
MaterialCardView materialCardView;
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
public UpdateUtil(Context context){
|
||||
this.context = context;
|
||||
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
}
|
||||
|
||||
public void updateApp(){
|
||||
if (updatingApp) {
|
||||
Toast.makeText(context, context.getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
AtomicReference<JSONObject> res = new AtomicReference<>(new JSONObject());
|
||||
try{
|
||||
Thread thread = new Thread(() -> res.set(checkForAppUpdate()));
|
||||
thread.start();
|
||||
thread.join();
|
||||
}catch(Exception e){
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
if(res.get() == null){
|
||||
Toast.makeText(context, R.string.error_checking_latest_version, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
String version = "";
|
||||
String body = "";
|
||||
try {
|
||||
version = res.get().getString("tag_name");
|
||||
body = res.get().getString("body");
|
||||
} catch (JSONException ignored) {}
|
||||
|
||||
if(version.equals("v"+BuildConfig.VERSION_NAME)){
|
||||
Toast.makeText(context, R.string.you_are_in_latest_version, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder updateDialog = new MaterialAlertDialogBuilder(context)
|
||||
.setTitle(version)
|
||||
.setMessage(body)
|
||||
.setIcon(R.drawable.ic_update_app)
|
||||
.setNegativeButton("Cancel", (dialogInterface, i) -> {})
|
||||
.setPositiveButton("Update", (dialogInterface, i) -> startAppUpdate(res.get()));
|
||||
updateDialog.show();
|
||||
}
|
||||
|
||||
|
||||
public JSONObject checkForAppUpdate(){
|
||||
String url = "https://api.github.com/repos/deniscerri/ytdlnis/releases/latest";
|
||||
|
||||
|
|
@ -69,7 +125,7 @@ public class UpdateUtil {
|
|||
return json;
|
||||
}
|
||||
|
||||
public void updateApp(JSONObject updateInfo){
|
||||
private void startAppUpdate(JSONObject updateInfo){
|
||||
try{
|
||||
JSONArray versions = updateInfo.getJSONArray("assets");
|
||||
String url = "";
|
||||
|
|
@ -95,7 +151,7 @@ public class UpdateUtil {
|
|||
|
||||
downloadManager.enqueue(new DownloadManager.Request(uri)
|
||||
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
|
||||
DownloadManager.Request.NETWORK_MOBILE)
|
||||
DownloadManager.Request.NETWORK_MOBILE)
|
||||
.setAllowedOverRoaming(true)
|
||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||
.setTitle(context.getString(R.string.downloading_update))
|
||||
|
|
@ -104,5 +160,38 @@ public class UpdateUtil {
|
|||
}catch(Exception ignored){}
|
||||
}
|
||||
|
||||
public void updateYoutubeDL() {
|
||||
if (updatingYTDL) {
|
||||
Toast.makeText(context, context.getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.makeText(context, context.getString(R.string.ytdl_updating_started), Toast.LENGTH_SHORT).show();
|
||||
|
||||
updatingYTDL = true;
|
||||
Disposable disposable = Observable.fromCallable(() -> YoutubeDL.getInstance().updateYoutubeDL(context))
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(status -> {
|
||||
switch (status) {
|
||||
case DONE:
|
||||
Toast.makeText(context, context.getString(R.string.ytld_update_success), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ALREADY_UP_TO_DATE:
|
||||
Toast.makeText(context, context.getString(R.string.you_are_in_latest_version), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
default:
|
||||
Toast.makeText(context, status.toString(), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
updatingYTDL = false;
|
||||
}, e -> {
|
||||
if(BuildConfig.DEBUG) Log.e(TAG, context.getString(R.string.ytdl_update_failed), e);
|
||||
Toast.makeText(context, context.getString(R.string.ytdl_update_failed), Toast.LENGTH_LONG).show();
|
||||
updatingYTDL = false;
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,86 +6,6 @@
|
|||
android:id="@+id/historycoordinator"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/history_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/home_main_linearlayout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/historylinearLayout1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_gravity="center"
|
||||
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/recycler_view_history"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:layout_margin="10dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
>
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/shimmer_history_framelayout"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shimmer_history_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/history_appbarlayout"
|
||||
app:liftOnScroll="false"
|
||||
|
|
@ -105,6 +25,64 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/recycler_view_history"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:layout_margin="10dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
>
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<include layout="@layout/history_no_results"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:id="@+id/shimmer_history_framelayout"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shimmer_history_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||
|
||||
<include layout="@layout/history_bottom_sheet"
|
||||
android:visibility="gone" />
|
||||
|
|
|
|||
|
|
@ -6,74 +6,9 @@
|
|||
android:id="@+id/homecoordinator"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/home_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/home_main_linearlayout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/recycler_view_home"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:layout_margin="10dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
>
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/shimmer_results_framelayout"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shimmer_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/home_appbarlayout"
|
||||
app:liftOnScroll="false"
|
||||
app:liftOnScroll="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
|
@ -90,8 +25,72 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/recycler_view_home"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="150dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
/>
|
||||
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/shimmer_results_framelayout"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shimmer_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
<include layout="@layout/result_card_shimmer" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/home_download_fabs"
|
||||
android:id="@+id/download_all_coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/download_all_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:text="@string/download_all"
|
||||
app:icon="@drawable/ic_down"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/download_selected_coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent">
|
||||
|
|
@ -108,7 +107,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimaryContainer"
|
||||
android:padding="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
|
|
@ -126,6 +124,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginLeft="5dp"
|
||||
app:srcCompat="@drawable/ic_video"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".page.MusicEditorFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="ello" />
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout android:id="@+id/history_shimmer_relative_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:layout_height="150dp"
|
||||
app:layout_constraintDimensionRatio="H,2.66:1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout
|
||||
android:id="@+id/history_no_results"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
<item android:title="@string/history"
|
||||
android:icon="@drawable/ic_history"
|
||||
android:id="@+id/history"/>
|
||||
<item android:title="@string/music_editor"
|
||||
android:icon="@drawable/ic_music_downloaded"
|
||||
android:id="@+id/music_editor"/>
|
||||
<item android:title="@string/more"
|
||||
android:icon="@drawable/ic_more"
|
||||
android:id="@+id/more"/>
|
||||
|
|
|
|||
|
|
@ -53,8 +53,15 @@
|
|||
<string name="run">Ekzekuto</string>
|
||||
<string name="running_ytdlp_command">Duke Ekzekutuar Komandën yt-dlp</string>
|
||||
<string name="command_directory">Direktoria e Komandës</string>
|
||||
<string name="you_are_running_latest_version">Ti je në versionin e fundit</string>
|
||||
<string name="error_checking_latest_version">Gabim në kontrollin e versionit!</string>
|
||||
<string name="couldnt_find_apk">Nuk u gjet një apk e vlefshme!</string>
|
||||
<string name="downloading_update">Duke Përditësuar</string>
|
||||
<string name="chooose_range">Zgjidh Shtrirjen</string>
|
||||
<string name="audio">Audio</string>
|
||||
<string name="video">Video</string>
|
||||
<string name="first">E para</string>
|
||||
<string name="last">E fundit</string>
|
||||
<string name="choose_range_desc">Cilëso cilën pjesë të listës do të shkarkosh. Lëre siç është që t\'i shkarkosh të gjitha</string>
|
||||
<string name="last_cant_be_smaller_than_first">Indeksi i fundit nuk mund të jetë më i vogël se indeksi i parë</string>
|
||||
<string name="first_cant_be_larger_than_last">Indeksi i parë nuk mund të jetë më i madh se indeksi i fundit</string>
|
||||
</resources>
|
||||
|
|
@ -53,7 +53,6 @@
|
|||
<string name="run">Run</string>
|
||||
<string name="running_ytdlp_command">Running yt-dlp Custom Command</string>
|
||||
<string name="command_directory">Custom Command Directory</string>
|
||||
<string name="you_are_running_latest_version">You are running the latest version!</string>
|
||||
<string name="error_checking_latest_version">Error checking for latest version!</string>
|
||||
<string name="couldnt_find_apk">Couldn\'t find a suitable apk!</string>
|
||||
<string name="downloading_update">Downloading Update</string>
|
||||
|
|
@ -65,4 +64,7 @@
|
|||
<string name="choose_range_desc">Write the range to download from the playlist. Leave as it is to download everything!</string>
|
||||
<string name="last_cant_be_smaller_than_first">Last index cannot be smaller than the first!</string>
|
||||
<string name="first_cant_be_larger_than_last">First index cannot be larger than the last!</string>
|
||||
<string name="music_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
<string name="video_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
<string name="command_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -5,16 +5,19 @@
|
|||
<Preference
|
||||
app:icon="@drawable/ic_music_downloaded"
|
||||
app:key="music_path"
|
||||
app:defaultValue="@string/music_path"
|
||||
app:title="@string/music_directory" />
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_video_downloaded"
|
||||
app:key="video_path"
|
||||
app:defaultValue="@string/video_path"
|
||||
app:title="@string/video_directory" />
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
app:key="command_path"
|
||||
app:defaultValue="@string/command_path"
|
||||
app:title="@string/command_directory" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
|
@ -108,6 +111,6 @@
|
|||
app:allowDividerAbove="true"
|
||||
app:icon="@drawable/ic_info"
|
||||
app:key="version"
|
||||
app:title="@string/version"></Preference>
|
||||
app:title="@string/version"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
Reference in a new issue