added chips to downloads fragment (sort, filter by type and website)

pull/1/head
Denis Çerri 4 years ago
parent e86b44ee51
commit 42deee3f2e
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/cancel/baseline_cancel_24.xml" />
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/arrow_upward/baseline_arrow_upward_24.xml" />
</map>
</option>
</PersistentState>
@ -331,7 +331,7 @@
<option name="values">
<map>
<entry key="color" value="00a6ff" />
<entry key="outputName" value="ic_cancel" />
<entry key="outputName" value="ic_up" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map>
</option>

@ -42,6 +42,7 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_baseline_keyboard_arrow_right_24.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_cancel.xml" value="0.2395" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_chapters.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_check.xml" value="0.2395" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_cloud_download.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_code.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_delete_all.xml" value="0.109" />
@ -67,6 +68,7 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_settings.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_speed.xml" value="0.14" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_subtitles.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_up.xml" value="0.1965" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_update.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_update_app.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_video.xml" value="0.1275" />
@ -78,7 +80,15 @@
<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.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_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" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/downloads_sort_sheet.xml" value="0.33" />
<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/filter_chip.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_downloads.xml" value="0.33" />
<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.16" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_more.xml" value="0.33" />
@ -95,6 +105,7 @@
<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" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/bottom_nav_menu.xml" value="0.20555555555555555" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/downloads_menu.xml" value="0.18854166666666666" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/history_menu.xml" value="0.17" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.25" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/settings_menu.xml" value="0.16875" />

@ -10,14 +10,13 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding;
import com.deniscerri.ytdlnis.page.HistoryFragment;
import com.deniscerri.ytdlnis.page.DownloadsFragment;
import com.deniscerri.ytdlnis.page.HomeFragment;
import com.deniscerri.ytdlnis.page.MoreFragment;
import com.deniscerri.ytdlnis.page.settings.SettingsActivity;
@ -36,7 +35,7 @@ public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private HomeFragment homeFragment;
private HistoryFragment historyFragment;
private DownloadsFragment downloadsFragment;
private MoreFragment moreFragment;
private Fragment lastFragment;
@ -87,7 +86,7 @@ public class MainActivity extends AppCompatActivity{
fm = getSupportFragmentManager();
homeFragment = new HomeFragment();
historyFragment = new HistoryFragment();
downloadsFragment = new DownloadsFragment();
moreFragment = new MoreFragment();
initFragments();
@ -102,12 +101,12 @@ public class MainActivity extends AppCompatActivity{
}
replaceFragment(homeFragment);
}else if(id == R.id.downloads){
if(lastFragment == historyFragment){
historyFragment.scrollToTop();
if(lastFragment == downloadsFragment){
downloadsFragment.scrollToTop();
}else {
this.setTitle(getString(R.string.downloads));
}
replaceFragment(historyFragment);
replaceFragment(downloadsFragment);
}else if(id == R.id.more){
if(lastFragment == moreFragment){
Intent intent = new Intent(context, SettingsActivity.class);
@ -135,7 +134,7 @@ public class MainActivity extends AppCompatActivity{
Log.e(TAG, action);
homeFragment = new HomeFragment();
historyFragment = new HistoryFragment();
downloadsFragment = new DownloadsFragment();
moreFragment = new MoreFragment();
homeFragment.handleIntent(intent);
@ -146,9 +145,9 @@ public class MainActivity extends AppCompatActivity{
private void initFragments(){
fm.beginTransaction()
.replace(R.id.frame_layout, homeFragment)
.add(R.id.frame_layout, historyFragment)
.add(R.id.frame_layout, downloadsFragment)
.add(R.id.frame_layout, moreFragment)
.hide(historyFragment)
.hide(downloadsFragment)
.hide(moreFragment)
.commit();
@ -156,7 +155,7 @@ public class MainActivity extends AppCompatActivity{
listeners = new ArrayList<>();
listeners.add(homeFragment.listener);
listeners.add(historyFragment.listener);
listeners.add(downloadsFragment.listener);
}
private void replaceFragment(Fragment f){
@ -232,7 +231,7 @@ public class MainActivity extends AppCompatActivity{
}
public void updateHistoryFragment(){
historyFragment.initCards();
downloadsFragment.initCards();
}
}

@ -1,7 +1,6 @@
package com.deniscerri.ytdlnis.adapter;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
@ -10,7 +9,6 @@ import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -28,13 +26,15 @@ import com.squareup.picasso.Picasso;
import java.io.File;
import java.util.ArrayList;
public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecyclerViewAdapter.ViewHolder> {
public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<DownloadsRecyclerViewAdapter.ViewHolder> {
private ArrayList<Video> videoList;
private ArrayList<String> websites;
private final OnItemClickListener onItemClickListener;
private Context context;
public HistoryRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Context context){
public DownloadsRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Context context){
this.videoList = videos;
this.websites = new ArrayList<>();
this.onItemClickListener = onItemClickListener;
this.context = context;
}
@ -49,7 +49,7 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
public ViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
super(itemView);
cardView = itemView.findViewById(R.id.history_card_view);
cardView = itemView.findViewById(R.id.downloads_card_view);
}
}
@ -57,9 +57,9 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View cardView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.history_card, parent, false);
.inflate(R.layout.downloads_card, parent, false);
return new HistoryRecyclerViewAdapter.ViewHolder(cardView, onItemClickListener);
return new DownloadsRecyclerViewAdapter.ViewHolder(cardView, onItemClickListener);
}
@Override
@ -67,7 +67,7 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
Video video = videoList.get(position);
CardView card = holder.cardView;
// THUMBNAIL ----------------------------------
ImageView thumbnail = card.findViewById(R.id.history_image_view);
ImageView thumbnail = card.findViewById(R.id.downloads_image_view);
String imageURL= video.getThumb();
Handler uiHandler = new Handler(Looper.getMainLooper());
@ -75,7 +75,7 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
thumbnail.setColorFilter(Color.argb(70, 0, 0, 0));
// TITLE ----------------------------------
TextView videoTitle = card.findViewById(R.id.history_title);
TextView videoTitle = card.findViewById(R.id.downloads_title);
String title = video.getTitle();
if(title.length() > 100){
@ -84,12 +84,12 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
videoTitle.setText(title);
// Bottom Info ----------------------------------
TextView bottomInfo = card.findViewById(R.id.history_info_bottom);
TextView bottomInfo = card.findViewById(R.id.downloads_info_bottom);
String info = video.getAuthor() + " • " + video.getDuration();
bottomInfo.setText(info);
// TIME DOWNLOADED ----------------------------------
TextView datetime = card.findViewById(R.id.history_info_time);
TextView datetime = card.findViewById(R.id.downloads_info_time);
String downloadedTime = video.getDownloadedTime();
datetime.setText(downloadedTime);
@ -104,15 +104,17 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
}
// BUTTON ----------------------------------
LinearLayout buttonLayout = card.findViewById(R.id.history_download_button_layout);
MaterialButton btn = buttonLayout.findViewById(R.id.history_download_button_type);
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));
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));
}
}
card.setOnClickListener(view -> onItemClickListener.onCardClick(position));
@ -129,12 +131,25 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
public void setVideoList(ArrayList<Video> videoList){
this.videoList = videoList;
setWebsiteList();
notifyDataSetChanged();
}
public ArrayList<String> getWebsites(){
return websites;
}
public void setWebsiteList(){
websites = new ArrayList<>();
for (Video video : videoList){
if (!websites.contains(video.getWebsite())) websites.add(video.getWebsite());
}
}
public void clear(){
int size = videoList.size();
videoList.clear();
websites.clear();
notifyItemRangeRemoved(0, size);
}

@ -5,6 +5,12 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import com.deniscerri.ytdlnis.R;
import java.io.File;
import java.util.ArrayList;
public class DBManager extends SQLiteOpenHelper {
@ -96,6 +102,31 @@ public class DBManager extends SQLiteOpenHelper {
db.execSQL("UPDATE "+results_table_name+ where);
}
public void clearDeletedHistory(){
ArrayList<Video> videos = getHistory("","","","");
for (int i = 0; i < videos.size(); i++){
Video video = videos.get(i);
String path = video.getDownloadPath();
File file = new File(path);
if(!file.exists() && !path.isEmpty()){
clearHistoryItem(video);
}
}
}
public void clearDuplicateHistory(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL(
"DELETE FROM " + history_table_name +
" WHERE id > (SELECT MIN(h.id) FROM history h WHERE h.url = " + history_table_name + ".url" +
" AND h.type = " + history_table_name + ".type);"
);
//remove downloaded statuses from results
db.execSQL("UPDATE "+results_table_name+ " SET downloadedAudio=0, downloadedVideo=0" +
" WHERE downloadedAudio=1 OR downloadedVideo=1");
}
public void clearResults(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM " + results_table_name);
@ -136,10 +167,15 @@ public class DBManager extends SQLiteOpenHelper {
return list;
}
public ArrayList<Video> getHistory(String query){
public ArrayList<Video> getHistory(String query, String format, String website, String sort){
SQLiteDatabase db = this.getReadableDatabase();
if (sort == null || sort.isEmpty()) sort = "DESC";
Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name
+ " WHERE title LIKE '%"+query+"%' ORDER BY id DESC",
+ " WHERE title LIKE '%"+query+"%'"+
" AND type LIKE '%"+format+"%'"+
" AND website LIKE '%"+website+"%'"+
" ORDER BY id "+sort,
null);
ArrayList<Video> list = new ArrayList<>();
@ -163,7 +199,6 @@ public class DBManager extends SQLiteOpenHelper {
return list;
}
public void addToResults(ArrayList<Video> videot){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();

@ -0,0 +1,504 @@
package com.deniscerri.ytdlnis.page;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
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;
import android.util.Log;
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.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter;
import com.deniscerri.ytdlnis.database.DBManager;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.service.DownloadInfo;
import com.deniscerri.ytdlnis.service.IDownloaderListener;
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.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
/**
* A fragment representing a list of Items.
*/
public class DownloadsFragment extends Fragment implements DownloadsRecyclerViewAdapter.OnItemClickListener, View.OnClickListener{
private View fragmentView;
private DBManager dbManager;
Context context;
Activity activity;
Context fragmentContext;
private LayoutInflater layoutinflater;
private ShimmerFrameLayout shimmerCards;
private MaterialToolbar topAppBar;
private RecyclerView recyclerView;
private DownloadsRecyclerViewAdapter downloadsRecyclerViewAdapter;
private BottomSheetDialog bottomSheet;
private BottomSheetDialog sortSheet;
private Handler uiHandler;
private RelativeLayout no_results;
private LinearLayout selectionChips;
private ChipGroup websiteGroup;
private ArrayList<Video> downloadsObjects;
private String format = "";
private String website = "";
private String sort = "DESC";
private String searchQuery = "";
private static final String TAG = "downloadsFragment";
public IDownloaderListener listener = new IDownloaderListener() {
public void onDownloadStart(DownloadInfo downloadInfo) {
try{
}catch(Exception ignored){}
}
public void onDownloadProgress(DownloadInfo info) {
activity.runOnUiThread(() -> {
try{
}catch(Exception ignored){}
});
}
public void onDownloadError(DownloadInfo info){
try{
}catch(Exception ignored){}
}
public void onDownloadEnd(DownloadInfo downloadInfo) {
try{
}catch(Exception ignored){}
}
@Override
public void onDownloadCancel(DownloadInfo downloadInfo) {
}
public void onDownloadServiceEnd() {}
};
public DownloadsFragment() {
}
@SuppressWarnings("unused")
public static DownloadsFragment newInstance() {
DownloadsFragment fragment = new DownloadsFragment();
Bundle args = new Bundle();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false);
context = fragmentView.getContext().getApplicationContext();
activity = getActivity();
fragmentContext = fragmentView.getContext();
layoutinflater = LayoutInflater.from(context);
shimmerCards = fragmentView.findViewById(R.id.shimmer_downloads_framelayout);
topAppBar = fragmentView.findViewById(R.id.downloads_toolbar);
no_results = fragmentView.findViewById(R.id.downloads_no_results);
selectionChips = fragmentView.findViewById(R.id.downloads_selection_chips);
websiteGroup = fragmentView.findViewById(R.id.website_chip_group);
uiHandler = new Handler(Looper.getMainLooper());
dbManager = new DBManager(context);
downloadsObjects = new ArrayList<>();
recyclerView = fragmentView.findViewById(R.id.recycler_view_downloads);
downloadsRecyclerViewAdapter = new DownloadsRecyclerViewAdapter(downloadsObjects, this, context);
recyclerView.setAdapter(downloadsRecyclerViewAdapter);
recyclerView.setNestedScrollingEnabled(false);
initMenu();
initChips();
initCards();
return fragmentView;
}
public void initCards(){
shimmerCards.startShimmer();
shimmerCards.setVisibility(View.VISIBLE);
downloadsRecyclerViewAdapter.clear();
no_results.setVisibility(View.GONE);
selectionChips.setVisibility(View.VISIBLE);
try{
Thread thread = new Thread(() -> {
downloadsObjects = dbManager.getHistory("", format,website,sort);
uiHandler.post(() -> {
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
shimmerCards.stopShimmer();
shimmerCards.setVisibility(View.GONE);
updateWebsiteChips();
});
if(downloadsObjects.size() == 0){
uiHandler.post(() -> {
no_results.setVisibility(View.VISIBLE);
selectionChips.setVisibility(View.GONE);
websiteGroup.removeAllViews();
});
}
});
thread.start();
}catch(Exception e){
Log.e(TAG, e.toString());
}
}
public void scrollToTop(){
recyclerView.scrollToPosition(0);
new Handler(Looper.getMainLooper()).post(() -> ((AppBarLayout) topAppBar.getParent()).setExpanded(true, true));
}
private void initMenu(){
MenuItem.OnActionExpandListener onActionExpandListener = new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
return true;
}
};
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);
searchView.setQueryHint(getString(R.string.search_history_hint));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
searchQuery = query;
topAppBar.getMenu().findItem(R.id.search_downloads).collapseActionView();
downloadsObjects = dbManager.getHistory(query, format,website,sort);
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
if(downloadsObjects.size() == 0) {
no_results.setVisibility(View.VISIBLE);
selectionChips.setVisibility(View.GONE);
websiteGroup.removeAllViews();
}
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
searchQuery = newText;
downloadsObjects = dbManager.getHistory(newText, format,website,sort);
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
if (downloadsObjects.size() == 0) {
no_results.setVisibility(View.VISIBLE);
selectionChips.setVisibility(View.GONE);
}else{
no_results.setVisibility(View.GONE);
selectionChips.setVisibility(View.VISIBLE);
}
return true;
}
});
topAppBar.setOnClickListener(view -> scrollToTop());
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
int itemID = m.getItemId();
if(itemID == R.id.remove_downloads) {
if (downloadsObjects.size() == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show();
return true;
}
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.confirm_delete_history_desc));
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
dbManager.clearHistory();
downloadsRecyclerViewAdapter.clear();
no_results.setVisibility(View.VISIBLE);
selectionChips.setVisibility(View.GONE);
websiteGroup.removeAllViews();
});
delete_dialog.show();
}else if(itemID == R.id.remove_deleted_downloads){
if (downloadsObjects.size() == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show();
return true;
}
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.confirm_delete_history_deleted_desc));
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
dbManager.clearDeletedHistory();
initCards();
});
delete_dialog.show();
}else if (itemID == R.id.remove_duplicates){
if (downloadsObjects.size() == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show();
return true;
}
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.confirm_delete_history_duplicates_desc));
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
dbManager.clearDuplicateHistory();
initCards();
});
delete_dialog.show();
}
return true;
});
}
private void initChips(){
//sort
Chip sortChip = fragmentView.findViewById(R.id.sort_chip);
sortChip.setOnClickListener(view -> {
sortSheet = new BottomSheetDialog(fragmentContext);
sortSheet.requestWindowFeature(Window.FEATURE_NO_TITLE);
sortSheet.setContentView(R.layout.downloads_sort_sheet);
TextView newest = sortSheet.findViewById(R.id.newest);
TextView oldest = sortSheet.findViewById(R.id.oldest);
newest.setOnClickListener(view1 -> {
sort = "DESC";
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
sortSheet.cancel();
});
oldest.setOnClickListener(view1 -> {
sort = "ASC";
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
sortSheet.cancel();
});
TextView cancel = sortSheet.findViewById(R.id.cancel);
cancel.setOnClickListener(view1 -> {
sortSheet.cancel();
});
sortSheet.show();
sortSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
});
//format
Chip audio = fragmentView.findViewById(R.id.audio_chip);
audio.setOnClickListener(view -> {
if (audio.isChecked()) {
format = "audio";
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
audio.setChecked(true);
}else {
format = "";
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
audio.setChecked(false);
}
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
});
Chip video = fragmentView.findViewById(R.id.video_chip);
video.setOnClickListener(view -> {
if (video.isChecked()) {
format = "video";
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
video.setChecked(true);
}else {
format = "";
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
video.setChecked(false);
}
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
});
}
private void updateWebsiteChips(){
websiteGroup.removeAllViews();
ArrayList<String> websites = downloadsRecyclerViewAdapter.getWebsites();
for (int i = 0; i < websites.size(); i++){
String w = websites.get(i);
Chip tmp = (Chip) layoutinflater.inflate(R.layout.filter_chip, websiteGroup, false);
tmp.setText(w);
tmp.setId(i);
tmp.setOnClickListener(view -> {
if (tmp.isChecked()){
website = (String) tmp.getText();
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
websiteGroup.check(view.getId());
}else{
website = "";
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
websiteGroup.clearCheck();
}
downloadsRecyclerViewAdapter.clear();
downloadsRecyclerViewAdapter.setVideoList(downloadsObjects);
});
websiteGroup.addView(tmp);
}
}
@Override
public void onClick(View v) {
int id = v.getId();
if(id == R.id.bottomsheet_remove_button){
removedownloadsItem((Integer) v.getTag());
}else if(id == R.id.bottom_sheet_link){
copyLinkToClipBoard((Integer) v.getTag());
}else if(id == R.id.bottomsheet_open_link_button){
openLinkIntent((Integer) v.getTag());
}
}
private void removedownloadsItem(int position){
if(bottomSheet != null) bottomSheet.hide();
Video v = downloadsObjects.get(position);
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.you_are_going_to_delete) + " \""+v.getTitle()+"\"!");
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
downloadsObjects.remove(position);
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
downloadsRecyclerViewAdapter.setWebsiteList();
updateWebsiteChips();
dbManager.clearHistoryItem(v);
if(downloadsObjects.size() == 0){
uiHandler.post(() -> {
no_results.setVisibility(View.VISIBLE);
selectionChips.setVisibility(View.GONE);
websiteGroup.removeAllViews();
});
}
});
delete_dialog.show();
}
private void copyLinkToClipBoard(int position){
String url = downloadsObjects.get(position).getURL();
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getString(R.string.url), url);
clipboard.setPrimaryClip(clip);
if(bottomSheet != null) bottomSheet.hide();
Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT).show();
}
private void openLinkIntent(int position){
String url =downloadsObjects.get(position).getURL();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
if(bottomSheet != null) bottomSheet.hide();
startActivity(i);
}
@Override
public void onCardClick(int position) {
bottomSheet = new BottomSheetDialog(fragmentContext);
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE);
bottomSheet.setContentView(R.layout.downloads_bottom_sheet);
Video video = downloadsObjects.get(position);
TextView title = bottomSheet.findViewById(R.id.bottom_sheet_title);
title.setText(video.getTitle());
TextView author = bottomSheet.findViewById(R.id.bottom_sheet_author);
author.setText(video.getAuthor());
Button link = bottomSheet.findViewById(R.id.bottom_sheet_link);
String url = video.getURL();
link.setText(url);
link.setTag(position);
link.setOnClickListener(this);
Button remove = bottomSheet.findViewById(R.id.bottomsheet_remove_button);
remove.setTag(position);
remove.setOnClickListener(this);
Button openLink = bottomSheet.findViewById(R.id.bottomsheet_open_link_button);
openLink.setTag(position);
openLink.setOnClickListener(this);
bottomSheet.show();
bottomSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
}
}

@ -1,369 +0,0 @@
package com.deniscerri.ytdlnis.page;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Handler;
import android.os.Looper;
import android.text.InputType;
import android.util.Log;
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.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.adapter.HistoryRecyclerViewAdapter;
import com.deniscerri.ytdlnis.database.DBManager;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.service.DownloadInfo;
import com.deniscerri.ytdlnis.service.IDownloaderListener;
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 java.io.File;
import java.util.ArrayList;
import java.util.Date;
/**
* A fragment representing a list of Items.
*/
public class HistoryFragment extends Fragment implements HistoryRecyclerViewAdapter.OnItemClickListener, View.OnClickListener{
private View fragmentView;
private DBManager dbManager;
Context context;
Activity activity;
Context fragmentContext;
private LayoutInflater layoutinflater;
private ShimmerFrameLayout shimmerCards;
private MaterialToolbar topAppBar;
private RecyclerView recyclerView;
private HistoryRecyclerViewAdapter historyRecyclerViewAdapter;
private BottomSheetDialog bottomSheet;
private Handler uiHandler;
private RelativeLayout no_results;
private ArrayList<Video> historyObjects;
private static final String TAG = "HistoryFragment";
public IDownloaderListener listener = new IDownloaderListener() {
public void onDownloadStart(DownloadInfo downloadInfo) {
try{
}catch(Exception ignored){}
}
public void onDownloadProgress(DownloadInfo info) {
activity.runOnUiThread(() -> {
try{
}catch(Exception ignored){}
});
}
public void onDownloadError(DownloadInfo info){
try{
}catch(Exception ignored){}
}
public void onDownloadEnd(DownloadInfo downloadInfo) {
try{
}catch(Exception ignored){}
}
@Override
public void onDownloadCancel(DownloadInfo downloadInfo) {
}
public void onDownloadServiceEnd() {}
};
public HistoryFragment() {
}
@SuppressWarnings("unused")
public static HistoryFragment newInstance() {
HistoryFragment fragment = new HistoryFragment();
Bundle args = new Bundle();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fragmentView = inflater.inflate(R.layout.fragment_history, container, false);
context = fragmentView.getContext().getApplicationContext();
activity = getActivity();
fragmentContext = fragmentView.getContext();
layoutinflater = LayoutInflater.from(context);
shimmerCards = fragmentView.findViewById(R.id.shimmer_history_framelayout);
topAppBar = fragmentView.findViewById(R.id.history_toolbar);
no_results = fragmentView.findViewById(R.id.history_no_results);
uiHandler = new Handler(Looper.getMainLooper());
dbManager = new DBManager(context);
historyObjects = new ArrayList<>();
recyclerView = fragmentView.findViewById(R.id.recycler_view_history);
historyRecyclerViewAdapter = new HistoryRecyclerViewAdapter(historyObjects, this, context);
recyclerView.setAdapter(historyRecyclerViewAdapter);
recyclerView.setNestedScrollingEnabled(false);
initMenu();
initCards();
return fragmentView;
}
public void initCards(){
shimmerCards.startShimmer();
shimmerCards.setVisibility(View.VISIBLE);
historyRecyclerViewAdapter.clear();
no_results.setVisibility(View.GONE);
try{
Thread thread = new Thread(() -> {
historyObjects = dbManager.getHistory("");
uiHandler.post(() -> {
historyRecyclerViewAdapter.setVideoList(historyObjects);
shimmerCards.stopShimmer();
shimmerCards.setVisibility(View.GONE);
});
if(historyObjects.size() == 0){
uiHandler.post(() -> no_results.setVisibility(View.VISIBLE));
}
});
thread.start();
}catch(Exception e){
Log.e(TAG, e.toString());
}
}
public void scrollToTop(){
recyclerView.scrollToPosition(0);
new Handler(Looper.getMainLooper()).post(() -> ((AppBarLayout) topAppBar.getParent()).setExpanded(true, true));
}
private void initMenu(){
MenuItem.OnActionExpandListener onActionExpandListener = new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
return true;
}
};
topAppBar.getMenu().findItem(R.id.search_history).setOnActionExpandListener(onActionExpandListener);
SearchView searchView = (SearchView) topAppBar.getMenu().findItem(R.id.search_history).getActionView();
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
searchView.setQueryHint(getString(R.string.search_history_hint));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
topAppBar.getMenu().findItem(R.id.search_history).collapseActionView();
historyObjects = dbManager.getHistory(query);
historyRecyclerViewAdapter.clear();
historyRecyclerViewAdapter.setVideoList(historyObjects);
if(historyObjects.size() == 0) no_results.setVisibility(View.VISIBLE);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
historyObjects = dbManager.getHistory(newText);
historyRecyclerViewAdapter.clear();
historyRecyclerViewAdapter.setVideoList(historyObjects);
if (historyObjects.size() == 0) {
no_results.setVisibility(View.VISIBLE);
}else{
no_results.setVisibility(View.GONE);
}
return true;
}
});
topAppBar.setOnClickListener(view -> scrollToTop());
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
int itemID = m.getItemId();
if(itemID == R.id.delete_history){
if(historyObjects.size() == 0){
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show();
return true;
}
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.confirm_delete_history_desc));
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
dbManager.clearHistory();
historyRecyclerViewAdapter.clear();
no_results.setVisibility(View.VISIBLE);
});
delete_dialog.show();
}else if(itemID == R.id.filter_history){
// bottomSheet = new BottomSheetDialog(fragmentContext);
// bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE);
// bottomSheet.setContentView(R.layout.history_bottom_sheet);
// Video video = historyObjects.get(position);
//
// TextView title = bottomSheet.findViewById(R.id.bottom_sheet_title);
// title.setText(video.getTitle());
//
// TextView author = bottomSheet.findViewById(R.id.bottom_sheet_author);
// author.setText(video.getAuthor());
//
// Button link = bottomSheet.findViewById(R.id.bottom_sheet_link);
// String url = video.getURL();
// link.setText(url);
// link.setTag(position);
// link.setOnClickListener(this);
//
// Button remove = bottomSheet.findViewById(R.id.bottomsheet_remove_button);
// remove.setTag(position);
// remove.setOnClickListener(this);
//
// Button openLink = bottomSheet.findViewById(R.id.bottomsheet_open_link_button);
// openLink.setTag(position);
// openLink.setOnClickListener(this);
//
// bottomSheet.show();
// bottomSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
}
return true;
});
}
@Override
public void onClick(View v) {
int id = v.getId();
if(id == R.id.bottomsheet_remove_button){
removeHistoryItem((Integer) v.getTag());
}else if(id == R.id.bottom_sheet_link){
copyLinkToClipBoard((Integer) v.getTag());
}else if(id == R.id.bottomsheet_open_link_button){
openLinkIntent((Integer) v.getTag());
}
}
private void removeHistoryItem(int position){
if(bottomSheet != null) bottomSheet.hide();
Video v = historyObjects.get(position);
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
delete_dialog.setTitle(getString(R.string.confirm_delete_history));
delete_dialog.setMessage(getString(R.string.you_are_going_to_delete) + " \""+v.getTitle()+"\"!");
delete_dialog.setNegativeButton(getString(R.string.cancel), (dialogInterface, i) -> {
dialogInterface.cancel();
});
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
historyObjects.remove(position);
historyRecyclerViewAdapter.notifyItemRemoved(position);
historyRecyclerViewAdapter.notifyItemRangeChanged(position, historyObjects.size());
dbManager.clearHistoryItem(v);
if(historyObjects.size() == 0){
uiHandler.post(() -> no_results.setVisibility(View.VISIBLE));
}
});
delete_dialog.show();
}
private void copyLinkToClipBoard(int position){
String url = historyObjects.get(position).getURL();
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getString(R.string.url), url);
clipboard.setPrimaryClip(clip);
if(bottomSheet != null) bottomSheet.hide();
Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT).show();
}
private void openLinkIntent(int position){
String url =historyObjects.get(position).getURL();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
if(bottomSheet != null) bottomSheet.hide();
startActivity(i);
}
@Override
public void onCardClick(int position) {
bottomSheet = new BottomSheetDialog(fragmentContext);
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE);
bottomSheet.setContentView(R.layout.history_bottom_sheet);
Video video = historyObjects.get(position);
TextView title = bottomSheet.findViewById(R.id.bottom_sheet_title);
title.setText(video.getTitle());
TextView author = bottomSheet.findViewById(R.id.bottom_sheet_author);
author.setText(video.getAuthor());
Button link = bottomSheet.findViewById(R.id.bottom_sheet_link);
String url = video.getURL();
link.setText(url);
link.setTag(position);
link.setOnClickListener(this);
Button remove = bottomSheet.findViewById(R.id.bottomsheet_remove_button);
remove.setTag(position);
remove.setOnClickListener(this);
Button openLink = bottomSheet.findViewById(R.id.bottomsheet_open_link_button);
openLink.setTag(position);
openLink.setOnClickListener(this);
bottomSheet.show();
bottomSheet.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
}
}

@ -143,9 +143,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
updateDownloadingStatusOnResult(item, type, false);
homeRecyclerViewAdapter.notifyItemChanged(resultObjects.indexOf(item));
downloading = false;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(false);
// MEDIA SCAN
ArrayList<File> files = new ArrayList<>();
String title = downloadInfo.getVideo().getTitle().replaceAll("[^a-zA-Z0-9]","");
@ -166,6 +163,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
addToHistory(item, new Date(), paths);
updateDownloadStatusOnResult(item, type, true);
mainActivity.updateHistoryFragment();
downloading = false;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(false);
}catch(Exception ignored){}
}
@ -214,14 +214,13 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
resultObjects = new ArrayList<>();
selectedObjects = new ArrayList<>();
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
context = fragmentView.getContext().getApplicationContext();
fragmentContext = fragmentView.getContext();
activity = getActivity();
mainActivity = (MainActivity) activity;
downloading = mainActivity.isDownloadServiceRunning();
//initViews
shimmerCards = fragmentView.findViewById(R.id.shimmer_results_framelayout);
@ -278,6 +277,16 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}else {
if (!downloading){
for (int i = 0; i < resultObjects.size(); i++){
Video tmp = resultObjects.get(i);
if(tmp.isDownloading()){
updateDownloadingStatusOnResult(tmp, "audio", false);
updateDownloadingStatusOnResult(tmp, "video", false);
}
}
}
}
dbManager.close();
if (resultObjects != null) {
@ -699,7 +708,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
Log.e(TAG, viewIdName);
String[] buttonData = viewIdName.split("##");
if (buttonData[0].equals("SELECT")) {
for (int i = 0; i < selectedObjects.size(); i++) {
Video vid = findVideo(selectedObjects.get(i).getVideoId());
vid.setDownloadedType(buttonData[1]);

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/colorAccent" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:colorAccent" android:pathData="M4,12l1.41,1.41L11,7.83V20h2V7.83l5.58,5.59L20,12l-8,-8 -8,8z"/>
</vector>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/history_element_bottom_sheet"
<FrameLayout android:id="@+id/downloads_element_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/history_card_constraintLayout"
android:id="@+id/downloads_card_constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="@+id/history_relative_layout"
android:id="@+id/downloads_relative_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,2.66:1"
@ -15,7 +15,7 @@
app:layout_constraintTop_toTopOf="parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/history_card_view"
android:id="@+id/downloads_card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="10dp"
@ -26,14 +26,14 @@
android:layout_margin="10dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/history_image_view"
android:id="@+id/downloads_image_view"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/history_title"
android:id="@+id/downloads_title"
android:layout_width="300dp"
android:layout_height="100dp"
android:paddingTop="15dp"
@ -49,7 +49,7 @@
android:shadowColor="@color/black" />
<TextView
android:id="@+id/history_info_bottom"
android:id="@+id/downloads_info_bottom"
android:layout_width="250dp"
android:layout_height="match_parent"
android:gravity="bottom"
@ -66,7 +66,7 @@
android:shadowColor="@color/black" />
<TextView
android:id="@+id/history_info_time"
android:id="@+id/downloads_info_time"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
@ -83,7 +83,7 @@
android:shadowColor="@color/black" />
<LinearLayout
android:id="@+id/history_download_button_layout"
android:id="@+id/downloads_download_button_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|right"
@ -94,7 +94,7 @@
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:id="@+id/history_download_button_type"
android:id="@+id/downloads_download_button_type"
android:layout_width="48dp"
android:layout_height="48dp"
app:cornerRadius="10dp"

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/history_shimmer_relative_layout"
<RelativeLayout android:id="@+id/downloads_shimmer_relative_layout"
android:layout_width="match_parent"
android:layout_height="150dp"
app:layout_constraintDimensionRatio="H,2.66:1"
@ -9,7 +9,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.cardview.widget.CardView
android:id="@+id/history_shimmer_card_view"
android:id="@+id/downloads_shimmer_card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="10dp"
@ -20,14 +20,14 @@
android:layout_margin="10dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/history_shimmer_image_view"
android:id="@+id/downloads_shimmer_image_view"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/history_shimmer_title"
android:id="@+id/downloads_shimmer_title"
android:layout_width="250dp"
android:background="@color/light_grey"
android:layout_height="10dp"
@ -38,7 +38,7 @@
/>
<TextView
android:id="@+id/history_shimmer_title2"
android:id="@+id/downloads_shimmer_title2"
android:layout_width="150dp"
android:background="@color/light_grey"
android:layout_height="10dp"
@ -49,7 +49,7 @@
/>
<TextView
android:id="@+id/history_shimmer_bottom"
android:id="@+id/downloads_shimmer_bottom"
android:layout_width="100dp"
android:background="@color/light_grey"
android:layout_height="10dp"
@ -62,7 +62,7 @@
/>
<TextView
android:id="@+id/history_shimmer_date"
android:id="@+id/downloads_shimmer_date"
android:layout_width="100dp"
android:background="@color/light_grey"
android:layout_height="10dp"
@ -75,7 +75,7 @@
/>
<TextView
android:id="@+id/history_shimmer_info_time"
android:id="@+id/downloads_shimmer_info_time"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
@ -92,7 +92,7 @@
android:shadowColor="@color/black" />
<LinearLayout
android:id="@+id/history_shimmer_download_button_layout"
android:id="@+id/downloads_shimmer_download_button_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|right"
@ -103,7 +103,7 @@
<com.google.android.material.button.MaterialButton
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:id="@+id/history_shimmer_download_button_type"
android:id="@+id/downloads_shimmer_download_button_type"
android:layout_width="48dp"
android:layout_height="48dp"
app:cornerRadius="10dp"

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/history_element_bottom_sheet"
<FrameLayout android:id="@+id/downloads_element_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/history_no_results"
android:id="@+id/downloads_no_results"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/downloads_element_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:layout_margin="10dp"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/newest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@string/newest_first"
android:drawablePadding="20dp"
android:paddingBottom="20dp"
app:drawableLeftCompat="@drawable/ic_up" />
<TextView
android:id="@+id/oldest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@string/oldest_first"
android:drawablePadding="20dp"
android:paddingBottom="20dp"
app:drawableLeftCompat="@drawable/ic_down" />
<View style="@style/Divider.Horizontal"/>
<TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
app:icon="@drawable/ic_link"
android:text="@string/cancel"
android:drawablePadding="20dp"
app:drawableLeftCompat="@drawable/ic_cancel" />
</LinearLayout>
</FrameLayout>

@ -1,16 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.chip.Chip
style="@style/Widget.Material3.Chip.Filter"
android:layout_width="wrap_content"
android:textSize="15sp"
android:checked="true"
android:textColor="?attr/colorOnSurface"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/website_chip"
style="@style/Widget.Material3.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Theme.Material3.DayNight"
/>

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/downloadscoordinator"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/downloads_appbarlayout"
app:liftOnScroll="false"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/downloads_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:title="@string/downloads"
app:menu="@menu/downloads_menu"
android:theme="@style/Toolbar"
/>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="10dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<HorizontalScrollView
android:layout_width="wrap_content"
android:scrollbars="none"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/downloads_selection_chips"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:id="@+id/sort_chip"
style="@style/Widget.Material3.Chip.Assist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/ic_down"
android:text="@string/sort_by"/>
</com.google.android.material.chip.ChipGroup>
<View style="@style/Divider.Vertical"/>
<com.google.android.material.chip.ChipGroup
android:id="@+id/format_chip_group"
android:layout_width="wrap_content"
app:selectionRequired="false"
app:singleSelection="true"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:id="@+id/audio_chip"
style="@style/Widget.Material3.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/audio"/>
<com.google.android.material.chip.Chip
android:id="@+id/video_chip"
style="@style/Widget.Material3.Chip.Filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/video"/>
</com.google.android.material.chip.ChipGroup>
<View style="@style/Divider.Vertical"/>
<com.google.android.material.chip.ChipGroup
android:id="@+id/website_chip_group"
app:selectionRequired="false"
app:singleSelection="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.google.android.material.chip.ChipGroup>
</LinearLayout>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycler_view_downloads"
android:orientation="vertical"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:nestedScrollingEnabled="false"
android:clipToPadding="false"
android:paddingBottom="150dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
>
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<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" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/historycoordinator"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/history_appbarlayout"
app:liftOnScroll="false"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/history_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:title="@string/downloads"
app:menu="@menu/history_menu"
android:theme="@style/Toolbar"
/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycler_view_history"
android:orientation="vertical"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:nestedScrollingEnabled="false"
android:layout_margin="10dp"
android:clipToPadding="false"
android:paddingBottom="150dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
>
</androidx.recyclerview.widget.RecyclerView>
<include layout="@layout/history_no_results"
android:visibility="gone" />
<com.facebook.shimmer.ShimmerFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:id="@+id/shimmer_history_framelayout"
android:orientation="vertical">
<LinearLayout
android:id="@+id/shimmer_history_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
<include layout="@layout/history_card_shimmer" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<include layout="@layout/history_bottom_sheet"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -0,0 +1,32 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<item
android:id="@+id/search_downloads"
android:title="@string/search"
android:icon="@drawable/ic_search"
app:showAsAction="collapseActionView|always"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
<item
android:id="@+id/remove_downloads"
android:icon="@drawable/ic_delete_all"
android:title="@string/remove_all"
app:showAsAction="never" />
<item
android:id="@+id/remove_deleted_downloads"
android:icon="@drawable/ic_delete_all"
android:title="@string/remove_deleted"
app:showAsAction="never" />
<item
android:id="@+id/remove_duplicates"
android:icon="@drawable/ic_delete_all"
android:title="@string/remove_duplicates"
app:showAsAction="never" />
</menu>

@ -1,26 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<item
android:id="@+id/search_history"
android:title="@string/search"
android:icon="@drawable/ic_search"
app:showAsAction="collapseActionView|always"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
<item
android:id="@+id/filter_history"
android:icon="@drawable/ic_filter"
android:title="@string/filter_history"
app:showAsAction="ifRoom" />
<item
android:id="@+id/delete_history"
android:icon="@drawable/ic_delete_all"
android:title="@string/fshi_historin"
app:showAsAction="ifRoom" />
</menu>

@ -12,7 +12,7 @@
<item
android:id="@+id/delete_results"
android:title="@string/fshi_rezultatet"
android:title="@string/remove_results"
app:showAsAction="never" />
<item

@ -2,8 +2,8 @@
<resources>
<string name="Trending"><b>Në Trend</b></string>
<string name="search">Kërko</string>
<string name="fshi_rezultatet">Pastro Rezultatet</string>
<string name="fshi_historin">Pastro Historinë</string>
<string name="remove_results">Pastro Rezultatet</string>
<string name="remove_all">Hiqi të gjitha</string>
<string name="end_of_results"><b>Arrite fundin e rezultateve</b></string>
<string name="download_all">Shkarko të gjitha</string>
<string name="settings">Cilësime</string>

@ -1,8 +1,8 @@
<resources>
<string name="app_name" translatable="false">YTDLnis</string>
<string name="search">Search</string>
<string name="fshi_historin">Clear history</string>
<string name="fshi_rezultatet">Clear Results</string>
<string name="remove_all">Remove All</string>
<string name="remove_results">Clear Results</string>
<string name="Trending"><b>Trending</b></string>
<string name="end_of_results"><b>You reached the end of results</b></string>
<string name="download_all">Download All</string>
@ -38,6 +38,8 @@
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="confirm_delete_history_desc">This will delete every item on your history! You can\'t recover them!</string>
<string name="confirm_delete_history_deleted_desc">This will delete any item in your history that doesn\'t find a file matching it\'s download path!</string>
<string name="confirm_delete_history_duplicates_desc">This will delete every duplicate in your history (same url and download type), and keeping the latest version!</string>
<string name="confirm_delete_history">Confirm</string>
<string name="search_history_hint">Search from History</string>
<string name="no_results">No Results</string>
@ -101,5 +103,10 @@
<string name="downloads">Downloads</string>
<string name="filter_history">Filter History</string>
<string name="removed_from_queue">removed from queue!</string>
<string name="remove_deleted">Remove Deleted</string>
<string name="remove_duplicates">Remove Duplicates</string>
<string name="sort_by">Sort by</string>
<string name="newest_first">Newest First</string>
<string name="oldest_first">Oldest First</string>
<item type="id" name="cancelDownload" />
</resources>

@ -16,4 +16,23 @@
<item name="android:searchIcon">@null</item>
</style>
<style name="Divider">
<item name="android:background">@color/light_grey</item>
</style>
<style name="Divider.Horizontal" parent="Divider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item> // You can change thickness here.
<item name="android:layout_marginBottom">20dp</item>
</style>
<style name="Divider.Vertical" parent="Divider">
<item name="android:layout_width">1dp</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