random stuff

This commit is contained in:
Denis Çerri 2023-01-10 11:47:05 +01:00
parent b330a5ba08
commit d91b6dc217
No known key found for this signature in database
GPG key ID: 96B3554AF5B193EE
13 changed files with 751 additions and 392 deletions

View file

@ -134,7 +134,6 @@ dependencies {
implementation "com.squareup.retrofit2:retrofit:$retrofitVer" implementation "com.squareup.retrofit2:retrofit:$retrofitVer"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVer" implementation "com.squareup.retrofit2:converter-gson:$retrofitVer"
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.10"
implementation "org.kodein.di:kodein-di-generic-jvm:6.4.0" implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
implementation "org.kodein.di:kodein-di-framework-android-x:$kodeinVer"
} }

View file

@ -0,0 +1,218 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "12ee531d801d7e6e3fd888f4907adc81",
"entities": [
{
"tableName": "results",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "playlistTitle",
"columnName": "playlistTitle",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadPath",
"columnName": "downloadPath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "downloads",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumb",
"columnName": "thumb",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "downloadPath",
"columnName": "downloadPath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "website",
"columnName": "website",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '12ee531d801d7e6e3fd888f4907adc81')"
]
}
}

View file

@ -194,7 +194,6 @@ class MainActivity : AppCompatActivity() {
lastFragment = homeFragment lastFragment = homeFragment
listeners = ArrayList() listeners = ArrayList()
listeners.add(homeFragment.listener) listeners.add(homeFragment.listener)
listeners.add(downloadsFragment.listener)
} }
private fun replaceFragment(f: Fragment) { private fun replaceFragment(f: Fragment) {
@ -229,8 +228,7 @@ class MainActivity : AppCompatActivity() {
databaseManager.addToHistory(v) databaseManager.addToHistory(v)
} }
databaseManager.close() databaseManager.close()
downloadsFragment.setDownloading(true) //downloadsFragment.initCards()
downloadsFragment.initCards()
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View file

@ -23,6 +23,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.deniscerri.ytdlnis.R; import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.database.Video; import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.database.models.HistoryItem;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.card.MaterialCardView; import com.google.android.material.card.MaterialCardView;
import com.google.android.material.progressindicator.LinearProgressIndicator; import com.google.android.material.progressindicator.LinearProgressIndicator;
@ -30,16 +31,17 @@ import com.squareup.picasso.Picasso;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<DownloadsRecyclerViewAdapter.ViewHolder> { public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<DownloadsRecyclerViewAdapter.ViewHolder> {
private ArrayList<Video> videoList; private List<HistoryItem> videoList;
private ArrayList<Integer> checkedVideos; private ArrayList<Integer> checkedVideos;
private ArrayList<String> websites; private ArrayList<String> websites;
private final OnItemClickListener onItemClickListener; private final OnItemClickListener onItemClickListener;
private Activity activity; private Activity activity;
public DownloadsRecyclerViewAdapter(ArrayList<Video> videos, OnItemClickListener onItemClickListener, Activity activity){ public DownloadsRecyclerViewAdapter(OnItemClickListener onItemClickListener, Activity activity){
this.videoList = videos; this.videoList = new ArrayList<>();
this.websites = new ArrayList<>(); this.websites = new ArrayList<>();
this.checkedVideos = new ArrayList<>(); this.checkedVideos = new ArrayList<>();
this.onItemClickListener = onItemClickListener; this.onItemClickListener = onItemClickListener;
@ -71,7 +73,8 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
@Override @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Video video = videoList.get(position); HistoryItem video = videoList.get(position);
Log.e("AAA", video.toString());
MaterialCardView card = holder.cardView; MaterialCardView card = holder.cardView;
// THUMBNAIL ---------------------------------- // THUMBNAIL ----------------------------------
ImageView thumbnail = card.findViewById(R.id.downloads_image_view); ImageView thumbnail = card.findViewById(R.id.downloads_image_view);
@ -107,51 +110,37 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
// TIME DOWNLOADED ---------------------------------- // TIME DOWNLOADED ----------------------------------
TextView datetime = card.findViewById(R.id.downloads_info_time); TextView datetime = card.findViewById(R.id.downloads_info_time);
String downloadedTime = video.getDownloadedTime(); String downloadedTime = video.getTime();
if (downloadedTime == null) downloadedTime = activity.getString(R.string.currently_downloading) + " " + video.getDownloadedType(); if (downloadedTime.isEmpty()) downloadedTime = activity.getString(R.string.currently_downloading) + " " + video.getType();
datetime.setText(downloadedTime); datetime.setText(downloadedTime);
// BUTTON ---------------------------------- // BUTTON ----------------------------------
LinearLayout buttonLayout = card.findViewById(R.id.downloads_download_button_layout); LinearLayout buttonLayout = card.findViewById(R.id.downloads_download_button_layout);
MaterialButton btn = buttonLayout.findViewById(R.id.downloads_download_button_type); MaterialButton btn = buttonLayout.findViewById(R.id.downloads_download_button_type);
// PROGRESS BAR ----------------------------------------------------
LinearProgressIndicator progressBar = card.findViewById(R.id.download_progress);
progressBar.setTag(video.getURL()+video.getDownloadedType()+"##progress");
boolean filePresent = true; boolean filePresent = true;
if (video.isQueuedDownload()){ //IS IN THE FILE SYSTEM?
progressBar.setVisibility(View.VISIBLE); String path = video.getDownloadPath();
btn.setOnClickListener(view -> onItemClickListener.onButtonClick(position)); File file = new File(path);
btn.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_cancel)); if(!file.exists() && !path.isEmpty()){
}else { filePresent = false;
progressBar.setVisibility(View.GONE); thumbnail.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(){{setSaturation(0f);}}));
progressBar.setIndeterminate(true); thumbnail.setAlpha(0.7f);
//IS IN THE FILE SYSTEM?
String path = video.getDownloadPath();
File file = new File(path);
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);
} }
if(!video.getType().isEmpty()){
if(video.getType().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);
if(checkedVideos.contains(position)){ if(checkedVideos.contains(position)){
card.setChecked(true); card.setChecked(true);
card.setStrokeWidth(5); card.setStrokeWidth(5);
@ -174,6 +163,12 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
}); });
} }
public void setVideoList(List<HistoryItem> list){
videoList.clear();
videoList.addAll(list);
notifyDataSetChanged();
}
private void checkCard(MaterialCardView card, int position){ private void checkCard(MaterialCardView card, int position){
if(card.isChecked()){ if(card.isChecked()){
card.setStrokeWidth(0); card.setStrokeWidth(0);
@ -203,7 +198,7 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
public void updateWebsiteList(){ public void updateWebsiteList(){
websites = new ArrayList<>(); websites = new ArrayList<>();
for (Video video : videoList){ for (HistoryItem video : videoList){
if (!websites.contains(video.getWebsite())) websites.add(video.getWebsite()); if (!websites.contains(video.getWebsite())) websites.add(video.getWebsite());
} }
} }
@ -224,7 +219,7 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter<Downloads
checkedVideos.clear(); checkedVideos.clear();
} }
public void add(ArrayList<Video> vids){ public void add(ArrayList<HistoryItem> vids){
int position = videoList.size() + 1; int position = videoList.size() + 1;
videoList.addAll(vids); videoList.addAll(vids);
notifyItemRangeInserted(position, vids.size()); notifyItemRangeInserted(position, vids.size());

View file

@ -12,7 +12,7 @@ interface HistoryDao {
"CASE WHEN :sort = 'ASC' THEN id END ASC," + "CASE WHEN :sort = 'ASC' THEN id END ASC," +
"CASE WHEN :sort = 'DESC' THEN id END DESC," + "CASE WHEN :sort = 'DESC' THEN id END DESC," +
"CASE WHEN :sort = '' THEN id END DESC ") "CASE WHEN :sort = '' THEN id END DESC ")
suspend fun getHistory(query : String, format : String, site : String, sort : String) : LiveData<List<HistoryItem>> fun getHistory(query : String, format : String, site : String, sort : String) : LiveData<List<HistoryItem>>
@Query("SELECT * FROM history") @Query("SELECT * FROM history")
fun getAllHistory() : LiveData<List<HistoryItem>> fun getAllHistory() : LiveData<List<HistoryItem>>

View file

@ -2,6 +2,7 @@ package com.deniscerri.ytdlnis.database.models
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
@Entity(tableName = "results") @Entity(tableName = "results")
data class ResultItem( data class ResultItem(

View file

@ -14,7 +14,7 @@ import kotlinx.coroutines.launch
class HistoryViewModel(application: Application) : AndroidViewModel(application) { class HistoryViewModel(application: Application) : AndroidViewModel(application) {
private val repository : HistoryRepository private val repository : HistoryRepository
private val allHistory : LiveData<List<HistoryItem>> val allHistory : LiveData<List<HistoryItem>>
init { init {
val dao = DBManager.getInstance(application).historyDao val dao = DBManager.getInstance(application).historyDao

View file

@ -0,0 +1,49 @@
package com.deniscerri.ytdlnis.service
import androidx.room.Room
import com.deniscerri.ytdlnis.database.DBManager
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import retrofit2.Call
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
interface InvidiousService {
@GET("video/{id}")
suspend fun getVideo(
@Path("id") id : String
) : Call<ResultItem>
@GET("playlist/{id}")
suspend fun getPlaylist(
@Path("id") id: String
) : Response<JsonObject>
@GET("trending?type=music&region={regionCode}")
suspend fun getTrending(
@Path("regionCode") regionCode: String
) : Response<JsonArray>
@GET("search/suggestions?q={query}")
suspend fun getSearchSuggestions(
@Path("query") query: String
) : Response<JsonObject>
companion object {
var invidiousService : InvidiousService? = null
fun getInstance() : InvidiousService {
return invidiousService ?: run {
val retrofit = Retrofit.Builder()
.baseUrl("https://invidious.baczek.me/api/v1/")
.addConverterFactory(GsonConverterFactory.create())
.build()
invidiousService = retrofit.create(InvidiousService::class.java)
invidiousService!!
}
}
}
}

View file

@ -0,0 +1,71 @@
package com.deniscerri.ytdlnis.service
import androidx.room.Query
import androidx.room.Room
import com.deniscerri.ytdlnis.database.DBManager
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.util.InfoUtil
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
interface YoutubeAPIService {
@GET("videos?part=snippet,contentDetails&id={id}&key={apiKey}")
suspend fun getVideo(
@Path("id") id: String?
) : Response<JsonObject>
@GET("playlistItems?part=snippet&pageToken={nextPageToken}&maxResults=50&regionCode={regionCode}&playlistId={playlistId}&key={apiKey}")
suspend fun getPlaylist(
@Path("nextPageToken") nextPageToken: String,
@Path("playlistId") playlistId : String,
@Path("apiKey") apiKey : String
) : Response<JsonObject>
@GET("videos?part=snippet&chart=mostPopular&videoCategoryId=10&regionCode={regionCode}&maxResults=25&key={apiKey}")
suspend fun getTrending(
@Path("regionCode") regionCode: String,
@Path("apiKey") apiKey : String
) : Response<JsonArray>
@GET("videos?part=contentDetails&chart=mostPopular&videoCategoryId=10&regionCode={regionCode}&maxResults=25&key={apiKey}")
suspend fun getTrendingExtra(
@Path("regionCode") regionCode: String,
@Path("apiKey") apiKey : String
) : Response<JsonArray>
@GET("search?part=snippet&q={query}&maxResults=25&regionCode={regionCode}&key={apiKey}")
suspend fun search(
@Path("query") query: String,
@Path("regionCode") regionCode: String,
@Path("apiKey") apiKey: String
) : Response<JsonObject>
@GET("videos?id={ids}&part=contentDetails&regionCode={regionCode}&key={apiKey}")
suspend fun getExtraData(
@Path("ids") ids: String,
@Path("regionCode") regionCode: String,
@Path("apiKey") apiKey: String
) : Response<JsonObject>
companion object {
var invidiousService : YoutubeAPIService? = null
lateinit var apiKey : String
lateinit var regionCode: String
fun getInstance(key: String, regionCode: String) : YoutubeAPIService {
apiKey = key
return invidiousService ?: run {
val retrofit = Retrofit.Builder()
.baseUrl("https://www.googleapis.com/youtube/v3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
invidiousService = retrofit.create(YoutubeAPIService::class.java)
invidiousService!!
}
}
}
}

View file

@ -3,27 +3,33 @@ package com.deniscerri.ytdlnis.ui
import android.app.Activity import android.app.Activity
import android.content.* import android.content.*
import android.net.Uri import android.net.Uri
import android.os.Binder
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.InputType import android.text.InputType
import android.util.Log import android.util.Log
import android.view.* import android.view.*
import android.view.View.OnLongClickListener import android.view.View.*
import android.widget.* import android.widget.*
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter
import com.deniscerri.ytdlnis.database.DatabaseManager import com.deniscerri.ytdlnis.database.DatabaseManager
import com.deniscerri.ytdlnis.database.Video import com.deniscerri.ytdlnis.database.Video
import com.deniscerri.ytdlnis.database.models.HistoryItem
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel
import com.deniscerri.ytdlnis.databinding.FragmentDownloadsBinding
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.service.DownloadInfo import com.deniscerri.ytdlnis.service.DownloadInfo
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.facebook.shimmer.ShimmerFrameLayout import com.facebook.shimmer.ShimmerFrameLayout
@ -61,7 +67,7 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
private var no_results: RelativeLayout? = null private var no_results: RelativeLayout? = null
private var selectionChips: LinearLayout? = null private var selectionChips: LinearLayout? = null
private var websiteGroup: ChipGroup? = null private var websiteGroup: ChipGroup? = null
private var downloadsObjects: ArrayList<Video?>? = null private var downloadsObjects: List<HistoryItem?>? = null
var selectedObjects: ArrayList<Video?>? = null var selectedObjects: ArrayList<Video?>? = null
private var progressBar: LinearProgressIndicator? = null private var progressBar: LinearProgressIndicator? = null
private var deleteFab: ExtendedFloatingActionButton? = null private var deleteFab: ExtendedFloatingActionButton? = null
@ -71,6 +77,8 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
private var sort = "DESC" private var sort = "DESC"
private var searchQuery = "" private var searchQuery = ""
private var _binding : FragmentDownloadsBinding? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
@ -80,21 +88,24 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
_binding = FragmentDownloadsBinding.inflate(inflater, container, false)
fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false) fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false)
activity = getActivity() activity = getActivity()
mainActivity = activity as MainActivity? mainActivity = activity as MainActivity?
fragmentContext = context?.applicationContext
layoutinflater = LayoutInflater.from(context)
historyViewModel = ViewModelProvider(this)[HistoryViewModel::class.java] return fragmentView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
shimmerCards = this.view?.findViewById(R.id.shimmer_downloads_framelayout) fragmentContext = context
topAppBar = this.view?.findViewById(R.id.downloads_toolbar) shimmerCards = view.findViewById(R.id.shimmer_downloads_framelayout)
no_results = this.view?.findViewById(R.id.downloads_no_results) topAppBar = view.findViewById(R.id.downloads_toolbar)
selectionChips = this.view?.findViewById(R.id.downloads_selection_chips) no_results = view.findViewById(R.id.downloads_no_results)
websiteGroup = this.view?.findViewById(R.id.website_chip_group) selectionChips = view.findViewById(R.id.downloads_selection_chips)
deleteFab = this.view?.findViewById(R.id.delete_selected_fab) websiteGroup = view.findViewById(R.id.website_chip_group)
deleteFab = view.findViewById(R.id.delete_selected_fab)
fileUtil = FileUtil() fileUtil = FileUtil()
deleteFab?.tag = "deleteSelected" deleteFab?.tag = "deleteSelected"
deleteFab?.setOnClickListener(this) deleteFab?.setOnClickListener(this)
@ -102,57 +113,74 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
downloadsObjects = ArrayList() downloadsObjects = ArrayList()
selectedObjects = ArrayList() selectedObjects = ArrayList()
downloading = mainActivity!!.isDownloadServiceRunning() downloading = mainActivity!!.isDownloadServiceRunning()
recyclerView = this.view?.findViewById(R.id.recycler_view_downloads)
downloadsObjects = mutableListOf()
downloadsRecyclerViewAdapter = downloadsRecyclerViewAdapter =
DownloadsRecyclerViewAdapter(downloadsObjects, this, activity) DownloadsRecyclerViewAdapter(this, activity)
recyclerView = view.findViewById(R.id.recyclerviewdownloadss)
recyclerView?.layoutManager = LinearLayoutManager(context)
recyclerView?.adapter = downloadsRecyclerViewAdapter recyclerView?.adapter = downloadsRecyclerViewAdapter
recyclerView?.isNestedScrollingEnabled = false
initMenu()
initChips()
initCards()
return fragmentView
}
fun initCards() {
shimmerCards!!.startShimmer()
shimmerCards!!.visibility = View.VISIBLE
downloadsRecyclerViewAdapter!!.clear() downloadsRecyclerViewAdapter!!.clear()
no_results!!.visibility = View.GONE no_results?.visibility = GONE
selectionChips!!.visibility = View.VISIBLE selectionChips?.visibility = VISIBLE
databaseManager = DatabaseManager(context) shimmerCards?.visibility = GONE
try {
val thread = Thread {
if (!downloading) databaseManager!!.clearDownloadingHistory() historyViewModel = ViewModelProvider(this)[HistoryViewModel::class.java]
downloadsObjects = databaseManager!!.getHistory("", format, website, sort) historyViewModel.allHistory.observe(viewLifecycleOwner) {
uiHandler!!.post { downloadsRecyclerViewAdapter!!.setVideoList(it);
downloadsRecyclerViewAdapter!!.add(downloadsObjects) Toast.makeText(context, "CHANGED", Toast.LENGTH_SHORT).show()
shimmerCards!!.stopShimmer()
shimmerCards!!.visibility = View.GONE
updateWebsiteChips()
}
if ((downloadsObjects as ArrayList<Video>?)?.size == 0) {
uiHandler!!.post {
no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE
websiteGroup!!.removeAllViews()
}
}
databaseManager!!.close()
}
thread.start()
} catch (e: Exception) {
Log.e(TAG, e.toString())
} }
initMenu()
//initChips()
// initCards()
} }
// fun initCards() {
// shimmerCards!!.startShimmer()
// shimmerCards!!.visibility = View.VISIBLE
// downloadsRecyclerViewAdapter!!.clear()
// no_results!!.visibility = View.GONE
// selectionChips!!.visibility = View.VISIBLE
// databaseManager = DatabaseManager(context)
// try {
// val thread = Thread {
// if (!downloading) databaseManager!!.clearDownloadingHistory()
// downloadsObjects = databaseManager!!.getHistory("", format, website, sort)
// uiHandler!!.post {
// downloadsRecyclerViewAdapter!!.add(downloadsObjects)
// shimmerCards!!.stopShimmer()
// shimmerCards!!.visibility = View.GONE
// updateWebsiteChips()
// }
// if ((downloadsObjects as ArrayList<Video>?)?.size == 0) {
// uiHandler!!.post {
// no_results!!.visibility = View.VISIBLE
// selectionChips!!.visibility = View.GONE
// websiteGroup!!.removeAllViews()
// }
// }
// databaseManager!!.close()
// }
// thread.start()
// } catch (e: Exception) {
// Log.e(TAG, e.toString())
// }
// }
//
fun scrollToTop() { fun scrollToTop() {
recyclerView!!.scrollToPosition(0) // recyclerView!!.scrollToPosition(0)
Handler(Looper.getMainLooper()).post { // Handler(Looper.getMainLooper()).post {
(topAppBar!!.parent as AppBarLayout).setExpanded( // (topAppBar!!.parent as AppBarLayout).setExpanded(
true, // true,
true // true
) // )
} // }
} }
private fun initMenu() { private fun initMenu() {
@ -175,31 +203,31 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
databaseManager = DatabaseManager(context) databaseManager = DatabaseManager(context)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean { override fun onQueryTextSubmit(query: String): Boolean {
searchQuery = query // searchQuery = query
topAppBar!!.menu.findItem(R.id.search_downloads).collapseActionView() // topAppBar!!.menu.findItem(R.id.search_downloads).collapseActionView()
downloadsObjects = databaseManager!!.getHistory(query, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(query, format, website, sort)
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
if ((downloadsObjects as ArrayList<Video>?)?.size == 0) { // if ((downloadsObjects as ArrayList<Video>?)?.size == 0) {
no_results!!.visibility = View.VISIBLE // no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE // selectionChips!!.visibility = View.GONE
websiteGroup!!.removeAllViews() // websiteGroup!!.removeAllViews()
} // }
return true return true
} }
override fun onQueryTextChange(newText: String): Boolean { override fun onQueryTextChange(newText: String): Boolean {
searchQuery = newText // searchQuery = newText
downloadsObjects = databaseManager!!.getHistory(newText, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(newText, format, website, sort)
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
if ((downloadsObjects as ArrayList<Video>?)?.size == 0) { // if ((downloadsObjects as ArrayList<Video>?)?.size == 0) {
no_results!!.visibility = View.VISIBLE // no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE // selectionChips!!.visibility = View.GONE
} else { // } else {
no_results!!.visibility = View.GONE // no_results!!.visibility = View.GONE
selectionChips!!.visibility = View.VISIBLE // selectionChips!!.visibility = View.VISIBLE
} // }
return true return true
} }
}) })
@ -207,266 +235,266 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
topAppBar!!.setOnMenuItemClickListener { m: MenuItem -> topAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
val itemID = m.itemId val itemID = m.itemId
if (itemID == R.id.remove_downloads) { if (itemID == R.id.remove_downloads) {
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show() // Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show()
return@setOnMenuItemClickListener true // return@setOnMenuItemClickListener true
} // }
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.confirm_delete_history)) // delete_dialog.setTitle(getString(R.string.confirm_delete_history))
delete_dialog.setMessage(getString(R.string.confirm_delete_history_desc)) // delete_dialog.setMessage(getString(R.string.confirm_delete_history_desc))
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
databaseManager!!.clearHistory() // databaseManager!!.clearHistory()
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsObjects!!.clear() // downloadsObjects!!.clear()
no_results!!.visibility = View.VISIBLE // no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE // selectionChips!!.visibility = View.GONE
websiteGroup!!.removeAllViews() // websiteGroup!!.removeAllViews()
} // }
delete_dialog.show() // delete_dialog.show()
} else if (itemID == R.id.remove_deleted_downloads) { } else if (itemID == R.id.remove_deleted_downloads) {
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show() // Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show()
return@setOnMenuItemClickListener true // return@setOnMenuItemClickListener true
} // }
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.confirm_delete_history)) // delete_dialog.setTitle(getString(R.string.confirm_delete_history))
delete_dialog.setMessage(getString(R.string.confirm_delete_history_deleted_desc)) // delete_dialog.setMessage(getString(R.string.confirm_delete_history_deleted_desc))
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
databaseManager!!.clearDeletedHistory() // databaseManager!!.clearDeletedHistory()
initCards() // initCards()
} // }
delete_dialog.show() // delete_dialog.show()
} else if (itemID == R.id.remove_duplicates) { } else if (itemID == R.id.remove_duplicates) {
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show() // Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show()
return@setOnMenuItemClickListener true // return@setOnMenuItemClickListener true
} // }
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.confirm_delete_history)) // delete_dialog.setTitle(getString(R.string.confirm_delete_history))
delete_dialog.setMessage(getString(R.string.confirm_delete_history_duplicates_desc)) // delete_dialog.setMessage(getString(R.string.confirm_delete_history_duplicates_desc))
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
databaseManager!!.clearDuplicateHistory() // databaseManager!!.clearDuplicateHistory()
initCards() // initCards()
} // }
delete_dialog.show() // delete_dialog.show()
} else if (itemID == R.id.remove_downloading) { } else if (itemID == R.id.remove_downloading) {
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show() // Toast.makeText(context, R.string.history_is_empty, Toast.LENGTH_SHORT).show()
return@setOnMenuItemClickListener true // return@setOnMenuItemClickListener true
} // }
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.confirm_delete_history)) // delete_dialog.setTitle(getString(R.string.confirm_delete_history))
delete_dialog.setMessage(getString(R.string.confirm_delete_downloading_desc)) // delete_dialog.setMessage(getString(R.string.confirm_delete_downloading_desc))
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
databaseManager!!.clearDownloadingHistory() // databaseManager!!.clearDownloadingHistory()
mainActivity!!.cancelDownloadService() // mainActivity!!.cancelDownloadService()
initCards() // initCards()
} // }
delete_dialog.show() // delete_dialog.show()
} }
true true
} }
} }
private fun initChips() { // private fun initChips() {
//sort and history/downloading switch // //sort and history/downloading switch
val sortChip = fragmentView!!.findViewById<Chip>(R.id.sort_chip) // val sortChip = fragmentView!!.findViewById<Chip>(R.id.sort_chip)
sortChip.setOnClickListener { view: View? -> // sortChip.setOnClickListener { view: View? ->
sortSheet = BottomSheetDialog(fragmentContext!!) // sortSheet = BottomSheetDialog(fragmentContext!!)
sortSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE) // sortSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
sortSheet!!.setContentView(R.layout.downloads_sort_sheet) // sortSheet!!.setContentView(R.layout.downloads_sort_sheet)
val newest = sortSheet!!.findViewById<TextView>(R.id.newest) // val newest = sortSheet!!.findViewById<TextView>(R.id.newest)
val oldest = sortSheet!!.findViewById<TextView>(R.id.oldest) // val oldest = sortSheet!!.findViewById<TextView>(R.id.oldest)
newest!!.setOnClickListener { view1: View? -> // newest!!.setOnClickListener { view1: View? ->
sort = "DESC" // sort = "DESC"
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
sortSheet!!.cancel() // sortSheet!!.cancel()
} // }
oldest!!.setOnClickListener { view1: View? -> // oldest!!.setOnClickListener { view1: View? ->
sort = "ASC" // sort = "ASC"
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
sortSheet!!.cancel() // sortSheet!!.cancel()
} // }
val cancel = sortSheet!!.findViewById<TextView>(R.id.cancel) // val cancel = sortSheet!!.findViewById<TextView>(R.id.cancel)
cancel!!.setOnClickListener { view1: View? -> sortSheet!!.cancel() } // cancel!!.setOnClickListener { view1: View? -> sortSheet!!.cancel() }
sortSheet!!.show() // sortSheet!!.show()
sortSheet!!.window!!.setLayout( // sortSheet!!.window!!.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT, // ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT // ViewGroup.LayoutParams.MATCH_PARENT
) // )
} // }
//
//format // //format
val audio = fragmentView!!.findViewById<Chip>(R.id.audio_chip) // val audio = fragmentView!!.findViewById<Chip>(R.id.audio_chip)
audio.setOnClickListener { view: View? -> // audio.setOnClickListener { view: View? ->
if (audio.isChecked) { // if (audio.isChecked) {
format = "audio" // format = "audio"
if (recyclerView!!.visibility == View.GONE) { // if (recyclerView!!.visibility == View.GONE) {
} // }
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
audio.isChecked = true // audio.isChecked = true
} else { // } else {
format = "" // format = ""
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
audio.isChecked = false // audio.isChecked = false
} // }
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
} // }
val video = fragmentView!!.findViewById<Chip>(R.id.video_chip) // val video = fragmentView!!.findViewById<Chip>(R.id.video_chip)
video.setOnClickListener { view: View? -> // video.setOnClickListener { view: View? ->
if (video.isChecked) { // if (video.isChecked) {
format = "video" // format = "video"
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
video.isChecked = true // video.isChecked = true
} else { // } else {
format = "" // format = ""
downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort) // downloadsObjects = databaseManager!!.getHistory(searchQuery, format, website, sort)
video.isChecked = false // video.isChecked = false
} // }
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
} // }
} // }
//
private fun updateWebsiteChips() { // private fun updateWebsiteChips() {
websiteGroup!!.removeAllViews() // websiteGroup!!.removeAllViews()
val websites = downloadsRecyclerViewAdapter!!.websites // val websites = downloadsRecyclerViewAdapter!!.websites
for (i in websites.indices) { // for (i in websites.indices) {
val w = websites[i] // val w = websites[i]
val tmp = layoutinflater!!.inflate(R.layout.filter_chip, websiteGroup, false) as Chip // val tmp = layoutinflater!!.inflate(R.layout.filter_chip, websiteGroup, false) as Chip
tmp.text = w // tmp.text = w
tmp.id = i // tmp.id = i
tmp.setOnClickListener { view: View -> // tmp.setOnClickListener { view: View ->
if (tmp.isChecked) { // if (tmp.isChecked) {
website = tmp.text as String // website = tmp.text as String
downloadsObjects = // downloadsObjects =
databaseManager!!.getHistory(searchQuery, format, website, sort) // databaseManager!!.getHistory(searchQuery, format, website, sort)
websiteGroup!!.check(view.id) // websiteGroup!!.check(view.id)
} else { // } else {
website = "" // website = ""
downloadsObjects = // downloadsObjects =
databaseManager!!.getHistory(searchQuery, format, website, sort) // databaseManager!!.getHistory(searchQuery, format, website, sort)
websiteGroup!!.clearCheck() // websiteGroup!!.clearCheck()
} // }
downloadsRecyclerViewAdapter!!.clear() // downloadsRecyclerViewAdapter!!.clear()
downloadsRecyclerViewAdapter!!.add(downloadsObjects) // downloadsRecyclerViewAdapter!!.add(downloadsObjects)
} // }
websiteGroup!!.addView(tmp) // websiteGroup!!.addView(tmp)
} // }
} // }
override fun onClick(v: View) { override fun onClick(v: View) {
val id = v.id // val id = v.id
if (id == R.id.bottomsheet_remove_button) { // if (id == R.id.bottomsheet_remove_button) {
removedownloadsItem(v.tag as Int) // removedownloadsItem(v.tag as Int)
} else if (id == R.id.bottom_sheet_link) { // } else if (id == R.id.bottom_sheet_link) {
openLinkIntent(v.tag as Int) // openLinkIntent(v.tag as Int)
} else if (id == R.id.bottomsheet_open_file_button) { // } else if (id == R.id.bottomsheet_open_file_button) {
openFileIntent(v.tag as Int) // openFileIntent(v.tag as Int)
} else if (id == R.id.delete_selected_fab) { // } else if (id == R.id.delete_selected_fab) {
removeSelectedItems() // removeSelectedItems()
} // }
} }
override fun onLongClick(v: View): Boolean { override fun onLongClick(v: View): Boolean {
val id = v.id // val id = v.id
if (id == R.id.bottom_sheet_link) { // if (id == R.id.bottom_sheet_link) {
copyLinkToClipBoard(v.tag as Int) // copyLinkToClipBoard(v.tag as Int)
return true // return true
} // }
return false return false
} }
private fun removeSelectedItems() { // private fun removeSelectedItems() {
if (bottomSheet != null) bottomSheet!!.hide() // if (bottomSheet != null) bottomSheet!!.hide()
val delete_file = booleanArrayOf(false) // val delete_file = booleanArrayOf(false)
databaseManager = DatabaseManager(context) // databaseManager = DatabaseManager(context)
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items)) // delete_dialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items))
delete_dialog.setMultiChoiceItems( // delete_dialog.setMultiChoiceItems(
arrayOf(getString(R.string.delete_files_too)), // arrayOf(getString(R.string.delete_files_too)),
booleanArrayOf(false) // booleanArrayOf(false)
) { dialogInterface: DialogInterface?, i: Int, b: Boolean -> delete_file[0] = b } // ) { dialogInterface: DialogInterface?, i: Int, b: Boolean -> delete_file[0] = b }
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
for (j in selectedObjects!!.indices) { // for (j in selectedObjects!!.indices) {
val v = selectedObjects!![j] // val v = selectedObjects!![j]
val position = downloadsObjects!!.indexOf(v) // val position = downloadsObjects!!.indexOf(v)
downloadsObjects!!.remove(v) // downloadsObjects!!.remove(v)
downloadsRecyclerViewAdapter!!.remove(position) // downloadsRecyclerViewAdapter!!.remove(position)
databaseManager!!.clearHistoryItem(v, delete_file[0]) // databaseManager!!.clearHistoryItem(v, delete_file[0])
} // }
updateWebsiteChips() // updateWebsiteChips()
databaseManager!!.close() // databaseManager!!.close()
selectedObjects = ArrayList() // selectedObjects = ArrayList()
downloadsRecyclerViewAdapter!!.clearCheckedVideos() // downloadsRecyclerViewAdapter!!.clearCheckedVideos()
deleteFab!!.visibility = View.GONE // deleteFab!!.visibility = View.GONE
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
uiHandler!!.post { // uiHandler!!.post {
no_results!!.visibility = View.VISIBLE // no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE // selectionChips!!.visibility = View.GONE
websiteGroup!!.removeAllViews() // websiteGroup!!.removeAllViews()
} // }
} // }
} // }
delete_dialog.show() // delete_dialog.show()
} // }
//
private fun removedownloadsItem(position: Int) { // private fun removedownloadsItem(position: Int) {
if (bottomSheet != null) bottomSheet!!.hide() // if (bottomSheet != null) bottomSheet!!.hide()
val delete_file = booleanArrayOf(false) // val delete_file = booleanArrayOf(false)
databaseManager = DatabaseManager(context) // databaseManager = DatabaseManager(context)
val v = downloadsObjects!![position] // val v = downloadsObjects!![position]
val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!) // val delete_dialog = MaterialAlertDialogBuilder(fragmentContext!!)
delete_dialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + v!!.title + "\"!") // delete_dialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + v!!.title + "\"!")
delete_dialog.setMultiChoiceItems( // delete_dialog.setMultiChoiceItems(
arrayOf(getString(R.string.delete_file_too)), // arrayOf(getString(R.string.delete_file_too)),
booleanArrayOf(false) // booleanArrayOf(false)
) { dialogInterface: DialogInterface?, i: Int, b: Boolean -> delete_file[0] = b } // ) { dialogInterface: DialogInterface?, i: Int, b: Boolean -> delete_file[0] = b }
delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() } // delete_dialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, i: Int -> dialogInterface.cancel() }
delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int -> // delete_dialog.setPositiveButton(getString(R.string.ok)) { dialogInterface: DialogInterface?, i: Int ->
downloadsObjects!!.removeAt(position) // downloadsObjects!!.removeAt(position)
downloadsRecyclerViewAdapter!!.remove(position) // downloadsRecyclerViewAdapter!!.remove(position)
updateWebsiteChips() // updateWebsiteChips()
databaseManager!!.clearHistoryItem(v, delete_file[0]) // databaseManager!!.clearHistoryItem(v, delete_file[0])
databaseManager!!.close() // databaseManager!!.close()
if (downloadsObjects!!.size == 0) { // if (downloadsObjects!!.size == 0) {
uiHandler!!.post { // uiHandler!!.post {
no_results!!.visibility = View.VISIBLE // no_results!!.visibility = View.VISIBLE
selectionChips!!.visibility = View.GONE // selectionChips!!.visibility = View.GONE
websiteGroup!!.removeAllViews() // websiteGroup!!.removeAllViews()
} // }
} // }
} // }
delete_dialog.show() // delete_dialog.show()
} // }
//
private fun copyLinkToClipBoard(position: Int) { // private fun copyLinkToClipBoard(position: Int) {
val url = downloadsObjects!![position]!!.getURL() // val url = downloadsObjects!![position]!!.getURL()
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager // val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(getString(R.string.url), url) // val clip = ClipData.newPlainText(getString(R.string.url), url)
clipboard.setPrimaryClip(clip) // clipboard.setPrimaryClip(clip)
if (bottomSheet != null) bottomSheet!!.hide() // if (bottomSheet != null) bottomSheet!!.hide()
Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT) // Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT)
.show() // .show()
} // }
//
private fun openLinkIntent(position: Int) { // private fun openLinkIntent(position: Int) {
val url = downloadsObjects!![position]!!.getURL() // val url = downloadsObjects!![position]!!.getURL()
val i = Intent(Intent.ACTION_VIEW) // val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(url) // i.data = Uri.parse(url)
if (bottomSheet != null) bottomSheet!!.hide() // if (bottomSheet != null) bottomSheet!!.hide()
startActivity(i) // startActivity(i)
} // }
private fun openFileIntent(position: Int) { private fun openFileIntent(position: Int) {
val downloadPath = downloadsObjects!![position]!!.downloadPath val downloadPath = downloadsObjects!![position]!!.downloadPath
@ -493,7 +521,7 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
val author = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_author) val author = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_author)
author!!.text = video.author author!!.text = video.author
val link = bottomSheet!!.findViewById<Button>(R.id.bottom_sheet_link) val link = bottomSheet!!.findViewById<Button>(R.id.bottom_sheet_link)
val url = video.getURL() val url = video.url
link!!.text = url link!!.text = url
link.tag = position link.tag = position
link.setOnClickListener(this) link.setOnClickListener(this)
@ -504,7 +532,7 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button) val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button)
openFile!!.tag = position openFile!!.tag = position
openFile.setOnClickListener(this) openFile.setOnClickListener(this)
if (!isFilePresent) openFile.visibility = View.GONE if (!isFilePresent) openFile.visibility = GONE
bottomSheet!!.show() bottomSheet!!.show()
bottomSheet!!.window!!.setLayout( bottomSheet!!.window!!.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
@ -513,30 +541,30 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi
} }
override fun onCardSelect(position: Int, add: Boolean) { override fun onCardSelect(position: Int, add: Boolean) {
val video = downloadsObjects!![position] // val video = downloadsObjects!![position]
if (add) selectedObjects!!.add(video) else selectedObjects!!.remove(video) // if (add) selectedObjects!!.add(video) else selectedObjects!!.remove(video)
if (selectedObjects!!.size > 1) { // if (selectedObjects!!.size > 1) {
deleteFab!!.visibility = View.VISIBLE // deleteFab!!.visibility = View.VISIBLE
} else { // } else {
deleteFab!!.visibility = View.GONE // deleteFab!!.visibility = View.GONE
} // }
} }
//
override fun onButtonClick(position: Int) { override fun onButtonClick(position: Int) {
val vid = downloadsObjects!![position] // val vid = downloadsObjects!![position]
try { // try {
mainActivity!!.removeItemFromDownloadQueue(vid, vid!!.downloadedType) // mainActivity!!.removeItemFromDownloadQueue(vid, vid!!.downloadedType)
} catch (e: Exception) { // } catch (e: Exception) {
val info = DownloadInfo() // val info = DownloadInfo()
info.video = vid // info.video = vid
info.downloadType = vid!!.downloadedType // info.downloadType = vid!!.downloadedType
} // }
} }
//
fun findVideo(url: String, type: String): Video? { fun findVideo(url: String, type: String): HistoryItem? {
for (i in downloadsObjects!!.indices) { for (i in downloadsObjects!!.indices) {
val v = downloadsObjects!![i] val v = downloadsObjects!![i]
if (v!!.getURL() == url && v.downloadedType == type && v.isQueuedDownload) { if (v!!.url == url && v.type == type) {
return v return v
} }
} }

View file

@ -100,7 +100,7 @@
</HorizontalScrollView> </HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_downloads" android:id="@+id/recyclerviewdownloadss"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/chips_recycler_horizontalscrollview" android:layout_below="@+id/chips_recycler_horizontalscrollview"

View file

@ -5,7 +5,7 @@ buildscript {
def versionMajor = 1 def versionMajor = 1
def versionMinor = 4 def versionMinor = 4
def versionPatch = 8 def versionPatch = 9
def versionBuild = 0 // bump for dogfood builds, public betas, etc. def versionBuild = 0 // bump for dogfood builds, public betas, etc.
ext { ext {

View file

@ -8,7 +8,7 @@
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true android.enableJetifier=true
android.useAndroidX=true android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects