added downloading items on the downloads tab, they can be cancelled
TODO, update home fragment when downloads tab cancels
This commit is contained in:
parent
a3f0667c7d
commit
b6f6edb690
20 changed files with 367 additions and 155 deletions
|
|
@ -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/");
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_history.xml
Normal file
5
app/src/main/res/drawable/ic_history.xml
Normal file
|
|
@ -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>
|
||||
<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"
|
||||
>
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/chips_recycler_horizontalscrollview"
|
||||
android:id="@+id/shimmer_downloads_framelayout"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<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" />
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<include layout="@layout/downloads_no_results"
|
||||
android:visibility="gone" />
|
||||
|
||||
<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">
|
||||
|
||||
|
||||
<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" />
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</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…
Reference in a new issue