added downloading items on the downloads tab, they can be cancelled

TODO, update home fragment when downloads tab cancels
pull/1/head
Denis Çerri 4 years ago
parent a3f0667c7d
commit b6f6edb690
No known key found for this signature in database
GPG Key ID: 3F50F14A8E7F7A13

@ -320,7 +320,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/arrow_upward/baseline_arrow_upward_24.xml" />
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/history/baseline_history_24.xml" />
</map>
</option>
</PersistentState>
@ -331,7 +331,7 @@
<option name="values">
<map>
<entry key="color" value="00a6ff" />
<entry key="outputName" value="ic_up" />
<entry key="outputName" value="ic_history" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map>
</option>

@ -51,6 +51,7 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_downloads.xml" value="0.2395" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_filter.xml" value="0.1965" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_go_up.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_history.xml" value="0.1965" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_home.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_image.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_info.xml" value="0.109" />
@ -81,7 +82,7 @@
<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.25" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_bottom_sheet.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_card.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_card.xml" value="0.33" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_card_shimmer.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_filter_sheet.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_no_results.xml" value="0.18854166666666666" />

@ -49,10 +49,6 @@
android:name=".DownloaderService"
android:enabled="true"
android:exported="false" />
<meta-data
android:name = "ytAPIkey"
android:value = "${ytAPI}"
/>
</application>
</manifest>

@ -40,7 +40,7 @@ import io.reactivex.schedulers.Schedulers;
public class DownloaderService extends Service {
private LocalBinder binder = new LocalBinder();
private Map<Activity, IDownloaderListener> activities = new ConcurrentHashMap<>();
private Map<Activity, ArrayList<IDownloaderListener>> activities = new ConcurrentHashMap<>();
private DownloadInfo downloadInfo = new DownloadInfo();
private LinkedList<Video> downloadQueue = new LinkedList<>();
private CompositeDisposable compositeDisposable = new CompositeDisposable();
@ -60,12 +60,15 @@ public class DownloaderService extends Service {
}
notificationUtil.updateDownloadNotification(downloadNotificationID,
line, (int) progress, downloadQueue.size(), title);
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadProgress(downloadInfo);
if (activities.get(activity) != null){
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadProgress(downloadInfo);
}
}
});
}
}catch (Exception ignored){}
@ -135,9 +138,9 @@ public class DownloaderService extends Service {
return downloadInfo;
}
public void addActivity(Activity activity, IDownloaderListener callback) {
public void addActivity(Activity activity, ArrayList<IDownloaderListener> callbacks) {
if(!activities.containsKey(activity)){
activities.put(activity, callback);
activities.put(activity, callbacks);
}
}
@ -186,8 +189,10 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadServiceEnd();
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadServiceEnd();
}
});
}
}catch (Exception e){
@ -199,8 +204,10 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadCancel(downloadInfo);
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadCancel(downloadInfo);
}
});
}
}catch (Exception e){
@ -212,8 +219,10 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadEnd(downloadInfo);
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadEnd(downloadInfo);
}
});
}
}catch (Exception e){
@ -238,15 +247,16 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadStart(downloadInfo);
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadStart(downloadInfo);
}
});
}
}catch (Exception err){
err.printStackTrace();
}
String url = video.getURL();
YoutubeDLRequest request = new YoutubeDLRequest(url);
String type = video.getDownloadedType();
@ -332,8 +342,10 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadEnd(downloadInfo);
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadEnd(downloadInfo);
}
});
}
}catch (Exception e){
@ -351,8 +363,10 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadError(downloadInfo);
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadError(downloadInfo);
}
});
}
}catch (Exception err){
@ -405,9 +419,11 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadEnd(downloadInfo);
callback.onDownloadServiceEnd();
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadEnd(downloadInfo);
callback.onDownloadServiceEnd();
}
});
}
}catch (Exception e){
@ -418,9 +434,11 @@ public class DownloaderService extends Service {
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadError(downloadInfo);
callback.onDownloadServiceEnd();
for (int i = 0; i < activities.get(activity).size(); i++){
IDownloaderListener callback = activities.get(activity).get(i);
callback.onDownloadError(downloadInfo);
callback.onDownloadServiceEnd();
}
});
}
}catch (Exception err){

@ -14,6 +14,8 @@ import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.deniscerri.ytdlnis.database.DBManager;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding;
import com.deniscerri.ytdlnis.page.DownloadsFragment;
@ -24,7 +26,12 @@ import com.deniscerri.ytdlnis.service.IDownloaderListener;
import com.deniscerri.ytdlnis.service.IDownloaderService;
import com.deniscerri.ytdlnis.util.UpdateUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends AppCompatActivity{
@ -53,9 +60,9 @@ public class MainActivity extends AppCompatActivity{
iDownloaderService = (IDownloaderService) service;
isDownloadServiceRunning = true;
try{
iDownloaderService.addActivity(MainActivity.this, listeners);
for (int i = 0; i < listeners.size(); i++){
IDownloaderListener listener = listeners.get(i);
iDownloaderService.addActivity(MainActivity.this, listener);
listener.onDownloadStart(iDownloaderService.getDownloadInfo());
}
}catch(Exception e){
@ -164,6 +171,7 @@ public class MainActivity extends AppCompatActivity{
}
public void startDownloadService(ArrayList<Video> downloadQueue, IDownloaderListener awaitingListener){
addQueueToDownloads(downloadQueue);
if(isDownloadServiceRunning){
iDownloaderService.updateQueue(downloadQueue);
return;
@ -174,6 +182,21 @@ public class MainActivity extends AppCompatActivity{
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
public void addQueueToDownloads(ArrayList<Video> downloadQueue) {
try {
DBManager dbManager = new DBManager(context);
for (int i = downloadQueue.size() - 1; i >= 0; i--){
Video v = downloadQueue.get(i);
v.setQueuedDownload(true);
dbManager.addToHistory(v);
}
dbManager.close();
downloadsFragment.initCards();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopDownloadService(){
if(!isDownloadServiceRunning) return;
iDownloaderService.removeActivity(this);
@ -230,8 +253,4 @@ public class MainActivity extends AppCompatActivity{
}
}
public void updateHistoryFragment(){
downloadsFragment.initCards();
}
}

@ -1,17 +1,20 @@
package com.deniscerri.ytdlnis.adapter;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
@ -21,6 +24,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.database.Video;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.squareup.picasso.Picasso;
import java.io.File;
@ -30,13 +34,13 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
private ArrayList<Video> videoList;
private ArrayList<String> websites;
private final OnItemClickListener onItemClickListener;
private Context context;
private Activity activity;
public DownloadsRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Context context){
public DownloadsRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Activity activity){
this.videoList = videos;
this.websites = new ArrayList<>();
this.onItemClickListener = onItemClickListener;
this.context = context;
this.activity = activity;
}
@Override
@ -91,30 +95,47 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
// TIME DOWNLOADED ----------------------------------
TextView datetime = card.findViewById(R.id.downloads_info_time);
String downloadedTime = video.getDownloadedTime();
if (downloadedTime == null) downloadedTime = activity.getString(R.string.currently_downloading) + " " + video.getDownloadedType();
datetime.setText(downloadedTime);
//IS IN THE FILE SYSTEM?
String path = video.getDownloadPath();
File file = new File(path);
boolean filePresent = true;
if(!file.exists() && !path.isEmpty()){
filePresent = false;
thumbnail.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(){{setSaturation(0f);}}));
thumbnail.setAlpha(0.7f);
}
// BUTTON ----------------------------------
LinearLayout buttonLayout = card.findViewById(R.id.downloads_download_button_layout);
MaterialButton btn = buttonLayout.findViewById(R.id.downloads_download_button_type);
if(video.getDownloadedType() != null){
if(video.getDownloadedType().equals("audio")){
if (filePresent) btn.setIcon(ContextCompat.getDrawable(context, R.drawable.ic_music_downloaded));
else btn.setIcon(ContextCompat.getDrawable(context, R.drawable.ic_music));
}else{
if (filePresent) btn.setIcon(ContextCompat.getDrawable(context, R.drawable.ic_video_downloaded));
else btn.setIcon(ContextCompat.getDrawable(context, R.drawable.ic_video));
// PROGRESS BAR ----------------------------------------------------
LinearProgressIndicator progressBar = card.findViewById(R.id.download_progress);
progressBar.setTag(video.getURL()+video.getDownloadedType()+"##progress");
if (video.isQueuedDownload()){
progressBar.setVisibility(View.VISIBLE);
btn.setOnClickListener(view -> onItemClickListener.onButtonClick(position));
btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel));
}else {
progressBar.setVisibility(View.GONE);
progressBar.setIndeterminate(true);
//IS IN THE FILE SYSTEM?
String path = video.getDownloadPath();
File file = new File(path);
boolean filePresent = true;
if(!file.exists() && !path.isEmpty()){
filePresent = false;
thumbnail.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(){{setSaturation(0f);}}));
thumbnail.setAlpha(0.7f);
}
if(video.getDownloadedType() != null){
if(video.getDownloadedType().equals("audio")){
if (filePresent) btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
else btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
}else{
if (filePresent) btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
else btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
}
}
if (btn.hasOnClickListeners()) btn.setOnClickListener(null);
}
card.setOnClickListener(view -> onItemClickListener.onCardClick(position));
@ -127,6 +148,7 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
public interface OnItemClickListener {
void onCardClick(int position);
void onButtonClick(int position);
}
public void setVideoList(ArrayList<Video> videoList){

@ -18,7 +18,7 @@ import java.util.ArrayList;
public class DBManager extends SQLiteOpenHelper {
public static final String db_name = "ytdlnis_db";
public static final int db_version = 10;
public static final int db_version = 7;
public static final String results_table_name = "results";
public static final String history_table_name = "history";
public static final String id = "id";
@ -38,7 +38,7 @@ public class DBManager extends SQLiteOpenHelper {
public static final String downloadingAudio = "downloadingAudio";
public static final String downloadingVideo = "downloadingVideo";
public static final String playlistTitle = "playlistTitle";
public static final String isQueuedDownload = "isQueuedDownload";
public DBManager(Context context){
super(context, db_name, null, db_version);
@ -74,7 +74,8 @@ public class DBManager extends SQLiteOpenHelper {
+ type + " TEXT,"
+ time + " TEXT,"
+ downloadPath + " TEXT,"
+ website + " TEXT)";
+ website + " TEXT,"
+ isQueuedDownload + " INTEGER)";
sqLiteDatabase.execSQL(query);
}
@ -198,7 +199,8 @@ public class DBManager extends SQLiteOpenHelper {
cursor.getString(cursor.getColumnIndex(type)),
cursor.getString(cursor.getColumnIndex(time)),
cursor.getString(cursor.getColumnIndex(downloadPath)),
cursor.getString(cursor.getColumnIndex(website))));
cursor.getString(cursor.getColumnIndex(website)),
cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
} while (cursor.moveToNext());
}
@ -244,11 +246,32 @@ public class DBManager extends SQLiteOpenHelper {
values.put(time, v.getDownloadedTime());
values.put(downloadPath, v.getDownloadPath());
values.put(website, v.getWebsite());
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
db.insert(history_table_name, null, values);
db.close();
}
public void updateHistoryItem(Video v){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(url, v.getURL());
values.put(title, v.getTitle());
values.put(author, v.getAuthor());
values.put(duration, v.getDuration());
values.put(thumb, v.getThumb());
values.put(type, v.getDownloadedType());
values.put(time, v.getDownloadedTime());
values.put(downloadPath, v.getDownloadPath());
values.put(website, v.getWebsite());
values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
db.update(history_table_name, values, where, null);
db.close();
}
public void updateDownloadStatusOnResult(String id, String type, boolean downloaded){
SQLiteDatabase db = this.getReadableDatabase();
ContentValues values = new ContentValues();

@ -20,6 +20,7 @@ public class Video implements Parcelable {
private String website;
private boolean downloadingAudio;
private boolean downloadingVideo;
private boolean queuedDownload;
private String playlistTitle;
// RESULTS OBJECT
@ -42,7 +43,7 @@ public class Video implements Parcelable {
//HISTORY OBJECT
public Video(int id, String url, String title, String author, String duration, String thumb,
String downloadedType, String downloadedTime, String downloadPath, String website) {
String downloadedType, String downloadedTime, String downloadPath, String website, int queued) {
this.id = id;
this.url = url;
this.title = title;
@ -53,6 +54,7 @@ public class Video implements Parcelable {
this.downloadedTime = downloadedTime;
this.downloadPath = downloadPath;
this.website = website;
this.queuedDownload = (queued == 1);
}
private boolean intToBoolean(int i){
@ -237,6 +239,14 @@ public class Video implements Parcelable {
this.playlistTitle = playlistTitle;
}
public boolean isQueuedDownload() {
return queuedDownload;
}
public void setQueuedDownload(boolean queuedDownload) {
this.queuedDownload = queuedDownload;
}
@Override
public int describeContents() {
return 0;

@ -25,6 +25,9 @@ import com.deniscerri.ytdlnis.util.NotificationUtil;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class CustomCommandActivity extends AppCompatActivity {
private static final String TAG = "CustomCommandActivity";
private MaterialToolbar topAppBar;
@ -45,7 +48,9 @@ public class CustomCommandActivity extends AppCompatActivity {
iDownloaderService = (IDownloaderService) service;
isDownloadServiceRunning = true;
try{
iDownloaderService.addActivity(CustomCommandActivity.this, listener);
ArrayList<IDownloaderListener> listeners = new ArrayList<>();
listeners.add(listener);
iDownloaderService.addActivity(CustomCommandActivity.this, listeners);
listener.onDownloadStart(iDownloaderService.getDownloadInfo());
}catch(Exception e){
e.printStackTrace();

@ -5,15 +5,13 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Handler;
import android.os.Looper;
import android.text.InputType;
@ -28,7 +26,7 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.deniscerri.ytdlnis.MainActivity;
import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter;
import com.deniscerri.ytdlnis.database.DBManager;
@ -42,8 +40,16 @@ import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.Locale;
/**
* A fragment representing a list of Items.
@ -54,6 +60,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
private DBManager dbManager;
Context context;
Activity activity;
MainActivity mainActivity;
Context fragmentContext;
private LayoutInflater layoutinflater;
private ShimmerFrameLayout shimmerCards;
@ -67,6 +74,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
private LinearLayout selectionChips;
private ChipGroup websiteGroup;
private ArrayList<Video> downloadsObjects;
private LinearProgressIndicator progressBar;
private String format = "";
private String website = "";
private String sort = "DESC";
@ -79,27 +87,90 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
public void onDownloadStart(DownloadInfo downloadInfo) {
try{
if(downloadInfo != null){
Video v = downloadInfo.getVideo();
progressBar = fragmentView.findViewWithTag(v.getURL()+v.getDownloadedType()+"##progress");
}
}catch(Exception ignored){}
}
public void onDownloadProgress(DownloadInfo info) {
activity.runOnUiThread(() -> {
try{
}catch(Exception ignored){}
int progress = info.getProgress();
Video v = info.getVideo();
if (progress > 0) {
progressBar = fragmentView.findViewWithTag(v.getURL()+v.getDownloadedType()+"##progress");
progressBar.setProgressCompat(progress, true);
}
}catch(Exception ignored){
}
});
}
public void onDownloadError(DownloadInfo info){
try{
int position = downloadsObjects.indexOf(info.getVideo());
Video v = downloadsObjects.get(position);
dbManager = new DBManager(context);
dbManager.clearHistoryItem(v);
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
}catch(Exception ignored){}
}
public void onDownloadEnd(DownloadInfo downloadInfo) {
Video item = downloadInfo.getVideo();
String url = item.getURL();
String type = downloadInfo.getDownloadType();
item = findVideo(url, type);
try{
// MEDIA SCAN
ArrayList<File> files = new ArrayList<>();
String title = downloadInfo.getVideo().getTitle().replaceAll("[^a-zA-Z0-9]","");
String pathTmp = "";
File path = new File(downloadInfo.getDownloadPath());
for( File file : path.listFiles() ){
if(file.isFile()){
pathTmp = file.getAbsolutePath().replaceAll("[^a-zA-Z0-9]","");
if (pathTmp.contains(title)){
files.add(file);
}
}
}
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) paths[i] = files.get(i).getAbsolutePath();
MediaScannerConnection.scanFile(context, paths, null, null);
item.setDownloadedType(type);
Calendar cal = Calendar.getInstance();
Date date = new Date();
cal.setTime(date);
int day = cal.get(Calendar.DAY_OF_MONTH);
String month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
int year = cal.get(Calendar.YEAR);
DateFormat formatter = new SimpleDateFormat("HH:mm", Locale.getDefault());
String time = formatter.format(date);
String downloadedTime = day + " " + month + " " + year + " " + time;
String downloadPath = "";
try{
downloadPath = paths[0];
}catch(Exception e){
e.printStackTrace();
}
dbManager = new DBManager(context);
try {
item.setDownloadedTime(downloadedTime);
item.setDownloadPath(downloadPath);
item.setQueuedDownload(false);
dbManager.updateHistoryItem(item);
dbManager.close();
downloadsRecyclerViewAdapter.notifyItemChanged(downloadsObjects.indexOf(item));
} catch (Exception ignored) {
}
}catch(Exception ignored){}
}
@ -136,6 +207,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false);
context = fragmentView.getContext().getApplicationContext();
activity = getActivity();
mainActivity = (MainActivity) activity;
fragmentContext = fragmentView.getContext();
layoutinflater = LayoutInflater.from(context);
shimmerCards = fragmentView.findViewById(R.id.shimmer_downloads_framelayout);
@ -149,8 +221,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
downloadsObjects = new ArrayList<>();
recyclerView = fragmentView.findViewById(R.id.recycler_view_downloads);
downloadsRecyclerViewAdapter = new DownloadsRecyclerViewAdapter(downloadsObjects, this, context);
downloadsRecyclerViewAdapter = new DownloadsRecyclerViewAdapter(downloadsObjects, this, activity);
recyclerView.setAdapter(downloadsRecyclerViewAdapter);
recyclerView.setNestedScrollingEnabled(false);
@ -160,7 +231,6 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
return fragmentView;
}
public void initCards(){
shimmerCards.startShimmer();
shimmerCards.setVisibility(View.VISIBLE);
@ -210,6 +280,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
}
};
MaterialToolbar toolbar = fragmentView.findViewById(R.id.downloads_toolbar);
topAppBar.getMenu().findItem(R.id.search_downloads).setOnActionExpandListener(onActionExpandListener);
SearchView searchView = (SearchView) topAppBar.getMenu().findItem(R.id.search_downloads).getActionView();
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
@ -318,7 +390,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
}
private void initChips(){
//sort
//sort and history/downloading switch
Chip sortChip = fragmentView.findViewById(R.id.sort_chip);
sortChip.setOnClickListener(view -> {
sortSheet = new BottomSheetDialog(fragmentContext);
@ -358,6 +430,9 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
audio.setOnClickListener(view -> {
if (audio.isChecked()) {
format = "audio";
if (recyclerView.getVisibility() == View.GONE){
}
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
audio.setChecked(true);
}else {
@ -388,6 +463,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
}
private void updateWebsiteChips(){
websiteGroup.removeAllViews();
@ -503,5 +580,27 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
bottomSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
}
@Override
public void onButtonClick(int position) {
try {
Video vid = downloadsObjects.get(position);
downloadsObjects.remove(position);
dbManager = new DBManager(context);
dbManager.clearHistoryItem(vid);
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
mainActivity.removeItemFromDownloadQueue(vid);
}catch (Exception ignored){}
}
public Video findVideo(String url, String type) {
for (int i = 0; i < downloadsObjects.size(); i++) {
Video v = downloadsObjects.get(i);
if ((v.getURL()).equals(url) && v.getDownloadedType().equals(type) && v.isQueuedDownload()) {
return v;
}
}
return null;
}
}

@ -143,32 +143,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
if (type.equals("audio")) item.setDownloadedAudio(1);
else item.setDownloadedVideo(1);
homeRecyclerViewAdapter.notifyItemChanged(resultObjects.indexOf(findVideo(id)));
// MEDIA SCAN
ArrayList<File> files = new ArrayList<>();
String title = downloadInfo.getVideo().getTitle().replaceAll("[^a-zA-Z0-9]","");
String pathTmp = "";
File path = new File(downloadInfo.getDownloadPath());
for( File file : path.listFiles() ){
if(file.isFile()){
pathTmp = file.getAbsolutePath().replaceAll("[^a-zA-Z0-9]","");
if (pathTmp.contains(title)){
files.add(file);
}
}
}
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) paths[i] = files.get(i).getAbsolutePath();
MediaScannerConnection.scanFile(context, paths, null, null);
String typeTmp = item.getDownloadedType();
item.setDownloadedType(type);
addToHistory(item, new Date(), paths);
item.setDownloadedType(typeTmp);
updateDownloadStatusOnResult(item, type, true);
mainActivity.updateHistoryFragment();
downloading = false;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(false);
}catch(Exception ignored){}

@ -6,7 +6,7 @@ import java.util.ArrayList;
public interface IDownloaderService {
DownloadInfo getDownloadInfo();
void addActivity(Activity activity, IDownloaderListener callback);
void addActivity(Activity activity, ArrayList<IDownloaderListener> callback);
void removeActivity(Activity activity);
void updateQueue(ArrayList<Video> queue);
void cancelDownload(boolean cancelAll);

@ -34,15 +34,10 @@ public class InfoUtil {
private DBManager dbManager;
public InfoUtil(Context context) {
@Nullable ApplicationInfo applicationInfo;
try{
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
key = sharedPreferences.getString("api_key", "");
applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
if (key.isEmpty()) key = applicationInfo.metaData.getString("ytAPIkey");
Log.e(TAG, key);
dbManager = new DBManager(context);
Thread thread = new Thread(() -> {
//get Locale
JSONObject country = genericRequest("https://ipwho.is/");

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
</vector>

@ -32,6 +32,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/download_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:indeterminate="true"
android:visibility="gone"
android:alpha="0.7"
android:scaleY="100" />
<TextView
android:id="@+id/downloads_title"
android:layout_width="300dp"
@ -93,12 +103,12 @@
android:paddingRight="20dp">
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
android:id="@+id/downloads_download_button_type"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_width="55dp"
android:layout_height="55dp"
app:cornerRadius="10dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
/>

@ -25,7 +25,7 @@
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
@ -33,6 +33,7 @@
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<HorizontalScrollView
android:id="@+id/chips_recycler_horizontalscrollview"
android:layout_width="wrap_content"
android:scrollbars="none"
android:layout_height="wrap_content">
@ -44,7 +45,9 @@
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
app:selectionRequired="false"
app:singleSelection="false">
<com.google.android.material.chip.Chip
android:id="@+id/sort_chip"
@ -101,6 +104,7 @@
android:id="@+id/recycler_view_downloads"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_below="@+id/chips_recycler_horizontalscrollview"
android:scrollbars="vertical"
android:nestedScrollingEnabled="false"
android:clipToPadding="false"
@ -110,54 +114,72 @@
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<include layout="@layout/downloads_no_results"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycler_view_progress_downloads"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_below="@+id/chips_recycler_horizontalscrollview"
android:scrollbars="vertical"
android:nestedScrollingEnabled="false"
android:clipToPadding="false"
android:paddingBottom="150dp"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
>
<com.facebook.shimmer.ShimmerFrameLayout
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:id="@+id/shimmer_downloads_framelayout"
android:orientation="vertical">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/shimmer_downloads_linear_layout"
<com.facebook.shimmer.ShimmerFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:visibility="gone"
android:layout_height="match_parent"
android:layout_below="@+id/chips_recycler_horizontalscrollview"
android:id="@+id/shimmer_downloads_framelayout"
android:orientation="vertical">
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<LinearLayout
android:id="@+id/shimmer_downloads_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
<include layout="@layout/downloads_card_shimmer" />
</LinearLayout>
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
</RelativeLayout>
<include layout="@layout/downloads_no_results"
android:visibility="gone" />
</com.facebook.shimmer.ShimmerFrameLayout>
<include layout="@layout/downloads_bottom_sheet"
android:visibility="gone" />

@ -42,6 +42,7 @@
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:indeterminate="true"
android:visibility="gone"
android:alpha="0.7"
android:scaleY="100" />

@ -105,4 +105,5 @@
<string name="sort_by">Rendit</string>
<string name="newest_first">Të rejat në fillim</string>
<string name="oldest_first">Të vjetrat në fillim</string>
<string name="currently_downloading">Duke Shkarkuar</string>
</resources>

@ -110,4 +110,5 @@
<string name="oldest_first">Oldest First</string>
<item type="id" name="cancelDownload" />
<string name="trendingPlaylist" translatable="false">ytdlnis-TRENDING</string>
<string name="currently_downloading">Downloading</string>
</resources>

@ -35,4 +35,13 @@
<item name="android:layout_marginStart">5dp</item>
</style>
<style name="Divider.Vertical.NoLine" parent="Divider">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:layout_marginBottom">10dp</item>
<item name="android:layout_marginEnd">5dp</item>
<item name="android:layout_marginStart">5dp</item>
</style>
</resources>

Loading…
Cancel
Save