new features

added download range for playlists functionality
made result cards clickable so you can download only them
pull/1/head
Denis Çerri 4 years ago
parent 4ed26c6b47
commit b81add6008
No known key found for this signature in database
GPG Key ID: 3F50F14A8E7F7A13

@ -64,10 +64,10 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/activity_custom_command.xml" value="0.15940685820203893" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.18" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/activity_settings.xml" value="0.16875" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/download_all_card.xml" value="0.3375" />
<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.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_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" />
@ -75,6 +75,8 @@
<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_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" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/result_card.xml" value="0.33" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/result_card_shimmer.xml" value="0.1" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/search_result.xml" value="0.33" />

@ -156,5 +156,4 @@ public class MainActivity extends AppCompatActivity{
isDownloadServiceRunning = false;
}
}

@ -20,6 +20,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.deniscerri.ytdl.R;
import com.deniscerri.ytdl.database.Video;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.card.MaterialCardView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
@ -41,7 +42,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private CardView cardView;
private MaterialCardView cardView;
public ViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
super(itemView);
@ -62,7 +63,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Video video = videoList.get(position);
CardView card = holder.cardView;
MaterialCardView card = holder.cardView;
// THUMBNAIL ----------------------------------
ImageView thumbnail = card.findViewById(R.id.result_image_view);
String imageURL= video.getThumb();
@ -112,8 +113,18 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
if(video.isVideoDownloaded() == 1){
videoBtn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
}
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());
});
}
@Override
@ -123,7 +134,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
public interface OnItemClickListener {
void onButtonClick(int position, String type);
void onCardClick(CardView card);
void onCardClick(int position, boolean add);
}
public void setVideoList(ArrayList<Video> videoList){

@ -12,10 +12,12 @@ 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;
@ -25,6 +27,7 @@ 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;
@ -44,7 +47,11 @@ import com.deniscerri.ytdl.util.NotificationUtil;
import com.facebook.shimmer.ShimmerFrameLayout;
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.FloatingActionButton;
import com.google.android.material.textfield.TextInputLayout;
import com.yausername.youtubedl_android.DownloadProgressCallback;
import com.yausername.youtubedl_android.YoutubeDL;
import com.yausername.youtubedl_android.YoutubeDLRequest;
@ -77,6 +84,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
private HomeRecyclerViewAdapter homeRecyclerViewAdapter;
private NestedScrollView scrollView;
private ShimmerFrameLayout shimmerCards;
private CoordinatorLayout downloadFabs;
private BottomSheetDialog bottomSheet;
private LayoutInflater layoutinflater;
Context context;
@ -86,6 +95,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
private static final String TAG = "HomeFragment";
private ArrayList<Video> resultObjects;
private ArrayList<Video> selectedObjects;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private DBManager dbManager;
@ -125,6 +135,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
compositeDisposable = new CompositeDisposable();
downloadQueue = new LinkedList<>();
resultObjects = new ArrayList<>();
selectedObjects = new ArrayList<>();
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
@ -140,6 +151,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
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);
homeRecyclerViewAdapter = new HomeRecyclerViewAdapter(resultObjects, this, activity);
recyclerView.setAdapter(homeRecyclerViewAdapter);
@ -153,6 +165,15 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
} else {
initCards();
}
FloatingActionButton music_fab = downloadFabs.findViewById(R.id.audio_fab);
FloatingActionButton video_fab = downloadFabs.findViewById(R.id.video_fab);
music_fab.setTag("SELECT##mp3");
video_fab.setTag("SELECT##mp4");
music_fab.setOnClickListener(this);
video_fab.setOnClickListener(this);
return fragmentView;
}
@ -415,16 +436,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
layoutinflater.inflate(R.layout.download_all_card, r);
CardView card = r.findViewById(R.id.downloadall_card_view);
LinearLayout buttonLayout = card.findViewById(R.id.downloadall_button_layout);
Button musicBtn = buttonLayout.findViewById(R.id.downloadall_music);
musicBtn.setTag("ALL##mp3");
Button videoBtn = buttonLayout.findViewById(R.id.downloadall_video);
videoBtn.setTag("ALL##mp4");
musicBtn.setOnClickListener(this);
videoBtn.setOnClickListener(this);
card.setTag("downloadAll");
card.setOnClickListener(this);
Handler uiHandler = new Handler(Looper.getMainLooper());
uiHandler.post(() -> homeLinearLayout.addView(r));
@ -667,11 +680,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
}
@Override
public void onCardClick(CardView card) {
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);
}
@Override
public void onClick(View v) {
String viewIdName;
@ -685,12 +701,15 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
if (viewIdName.contains("mp3") || viewIdName.contains("mp4")) {
Log.e(TAG, viewIdName);
String[] buttonData = viewIdName.split("##");
if (buttonData[0].equals("ALL")) {
for (int i = 0; i < resultObjects.size(); i++) {
Video vid = findVideo(resultObjects.get(i).getVideoId());
if (buttonData[0].equals("SELECT")) {
for (int i = 0; i < selectedObjects.size(); i++) {
Video vid = findVideo(selectedObjects.get(i).getVideoId());
vid.setDownloadedType(buttonData[1]);
homeRecyclerViewAdapter.notifyItemChanged(resultObjects.indexOf(vid));
downloadQueue.add(vid);
}
selectedObjects = new ArrayList<>();
downloadFabs.setVisibility(View.GONE);
if (downloading) {
Toast.makeText(context, R.string.added_to_queue, Toast.LENGTH_LONG).show();
@ -700,6 +719,70 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
startDownload(downloadQueue);
}
}
if (viewIdName.equals("downloadAll")){
//remove previously selected
for (int i = 0; i < selectedObjects.size(); i++) {
Video vid = findVideo(selectedObjects.get(i).getVideoId());
homeRecyclerViewAdapter.notifyItemChanged(resultObjects.indexOf(vid));
}
selectedObjects = new ArrayList<>();
downloadFabs.setVisibility(View.GONE);
bottomSheet = new BottomSheetDialog(context);
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE);
bottomSheet.setContentView(R.layout.home_download_all_bottom_sheet);
TextInputLayout first = bottomSheet.findViewById(R.id.first_textinput);
first.getEditText().setText(String.valueOf(1));
TextInputLayout last = bottomSheet.findViewById(R.id.last_textinput);
last.getEditText().setText(String.valueOf(resultObjects.size()));
Button audio = bottomSheet.findViewById(R.id.bottomsheet_audio_button);
audio.setOnClickListener(view -> {
int start = Integer.parseInt(first.getEditText().getText().toString());
int end = Integer.parseInt(last.getEditText().getText().toString());
initDownloadAll(bottomSheet, start, end, "mp3");
});
Button video = bottomSheet.findViewById(R.id.bottomsheet_video_button);
video.setOnClickListener(view -> {
int start = Integer.parseInt(first.getEditText().getText().toString());
int end = Integer.parseInt(last.getEditText().getText().toString());
initDownloadAll(bottomSheet, start, end, "mp4");
});
bottomSheet.show();
bottomSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
}
}
}
private void initDownloadAll(BottomSheetDialog bottomSheet, int start, int end, String type){
if(start > end){
TextInputLayout first = bottomSheet.findViewById(R.id.first_textinput);
first.setError(getString(R.string.first_cant_be_larger_than_last));
TextInputLayout last = bottomSheet.findViewById(R.id.last_textinput);
last.setError(getString(R.string.last_cant_be_smaller_than_first));
return;
}
bottomSheet.cancel();
if (start <= 1) start = 0;
for (int i = start; i < end; i++){
Video vid = findVideo(resultObjects.get(i).getVideoId());
vid.setDownloadedType(type);
downloadQueue.add(vid);
}
if (downloading) {
Toast.makeText(context, R.string.added_to_queue, Toast.LENGTH_LONG).show();
return;
}
mainActivity.startDownloadService(downloadQueue.peek().getTitle(), NotificationUtil.DOWNLOAD_NOTIFICATION_ID);
startDownload(downloadQueue);
}
}

@ -75,7 +75,7 @@ public class NotificationUtil {
public void updateDownloadNotification(int id, String desc, int progress, int queue, String title){
String contentText = "";
if (queue > 1) contentText += queue + " items left\n";
if (queue > 1) contentText += queue - 1 + " item(s) left\n";
contentText += desc.replaceAll("\\[.*?\\]", "");
notificationBuilder.setProgress(100, (int) progress, false)

@ -27,7 +27,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/download_all"
android:gravity="left|center"
android:gravity="center"
android:paddingTop="15dp"
android:paddingRight="20dp"
android:paddingBottom="20dp"
@ -40,37 +40,5 @@
android:shadowDy="4"
android:shadowColor="@color/black" />
<LinearLayout
android:id="@+id/downloadall_button_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
android:orientation="horizontal"
android:paddingBottom="16dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:id="@+id/downloadall_music"
android:layout_width="48dp"
android:layout_height="48dp"
app:cornerRadius="10dp"
app:icon="@drawable/ic_music"
android:layout_marginLeft="10dp"
/>
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:id="@+id/downloadall_video"
android:layout_width="48dp"
android:layout_height="48dp"
app:cornerRadius="10dp"
app:icon="@drawable/ic_video"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>

@ -90,4 +90,54 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/home_download_fabs"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
app:cardCornerRadius="20dp"
android:layout_margin="16dp"
>
<LinearLayout
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
android:id="@+id/audio_fab"
app:elevation="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginRight="5dp"
app:srcCompat="@drawable/ic_music"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/video_fab"
app:elevation="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
app:srcCompat="@drawable/ic_video"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<include layout="@layout/home_download_all_bottom_sheet"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/home_download_all_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/bottom_sheet_title"
android:layout_width="wrap_content"
android:textSize="25sp"
android:textColor="?attr/colorOnSurface"
android:layout_height="wrap_content"
android:text="@string/chooose_range" />
<TextView
android:id="@+id/bottom_sheet_author"
android:layout_width="wrap_content"
android:paddingTop="5dp"
android:textSize="15sp"
android:layout_height="wrap_content"
android:text="@string/choose_range_desc" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/first_textinput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="45"
android:layout_marginLeft="30dp"
app:errorEnabled="true"
android:hint="@string/first"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:inputType="numberDecimal"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/last_textinput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="45"
android:layout_marginRight="30dp"
android:layout_marginLeft="30dp"
app:errorEnabled="true"
android:hint="@string/last"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:inputType="numberDecimal"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="right"
android:layout_margin="20dp"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_audio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
app:icon="@drawable/ic_music"
android:text="@string/audio" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_video_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/video"
app:icon="@drawable/ic_video"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>

@ -16,7 +16,7 @@
app:layout_constraintTop_toTopOf="parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/result_card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -25,6 +25,8 @@
app:cardMaxElevation="12dp"
app:cardBackgroundColor="@color/black"
app:cardPreventCornerOverlap="true"
android:checkable="true"
app:strokeWidth="0dp"
android:layout_margin="10dp">
<androidx.appcompat.widget.AppCompatImageView
@ -109,7 +111,7 @@
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:scaleY="2" />
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -57,4 +57,12 @@
<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>
<string name="chooose_range">Choose Range</string>
<string name="audio">Audio</string>
<string name="video">Video</string>
<string name="first">First</string>
<string name="last">Last</string>
<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>
</resources>

Loading…
Cancel
Save