From 542121d44668fc98190bd83419a20d6af34d5e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C3=87erri?= <64997243+deniscerri@users.noreply.github.com> Date: Sun, 15 Jan 2023 16:48:51 +0100 Subject: [PATCH] implemented diffutil on history recyclerview --- .idea/assetWizardSettings.xml | 4 +- .../1.json | 26 +- .../7.json | 192 ------ ...r.java => HistoryRecyclerViewAdapter.java} | 132 ++-- .../ytdlnis/database/dao/HistoryDao.kt | 7 +- .../ytdlnis/database/models/DownloadItem.kt | 6 +- .../ytdlnis/database/models/HistoryItem.kt | 4 +- .../ytdlnis/database/models/ResultItem.kt | 2 + .../database/repository/HistoryRepository.kt | 27 +- .../database/viewmodel/HistoryViewModel.kt | 67 +- .../ytdlnis/ui/DownloadsFragment.kt | 648 +++++++----------- app/src/main/res/drawable/ic_downloads.xml | 2 +- .../main/res/layout/fragment_downloads.xml | 7 +- 13 files changed, 440 insertions(+), 684 deletions(-) delete mode 100644 app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json rename app/src/main/java/com/deniscerri/ytdlnis/adapter/{DownloadsRecyclerViewAdapter.java => HistoryRecyclerViewAdapter.java} (64%) diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml index 41f999de..617fae3e 100644 --- a/.idea/assetWizardSettings.xml +++ b/.idea/assetWizardSettings.xml @@ -320,7 +320,7 @@ @@ -331,7 +331,7 @@ diff --git a/app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json b/app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json index 2f703f46..66043b63 100644 --- a/app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json +++ b/app/schemas/com.deniscerri.ytdlnis.database.DBManager/1.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "12ee531d801d7e6e3fd888f4907adc81", + "identityHash": "1709c1d446102722d4dc7f2cb96cd40e", "entities": [ { "tableName": "results", @@ -68,7 +68,7 @@ }, { "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)", + "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` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL)", "fields": [ { "fieldPath": "id", @@ -115,7 +115,7 @@ { "fieldPath": "time", "columnName": "time", - "affinity": "TEXT", + "affinity": "INTEGER", "notNull": true }, { @@ -142,7 +142,7 @@ }, { "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)", + "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, `formatId` INTEGER NOT NULL, `formatDesc` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL)", "fields": [ { "fieldPath": "id", @@ -181,8 +181,14 @@ "notNull": true }, { - "fieldPath": "type", - "columnName": "type", + "fieldPath": "formatId", + "columnName": "formatId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "formatDesc", + "columnName": "formatDesc", "affinity": "TEXT", "notNull": true }, @@ -197,6 +203,12 @@ "columnName": "website", "affinity": "TEXT", "notNull": true + }, + { + "fieldPath": "downloadSize", + "columnName": "downloadSize", + "affinity": "TEXT", + "notNull": true } ], "primaryKey": { @@ -212,7 +224,7 @@ "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')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1709c1d446102722d4dc7f2cb96cd40e')" ] } } \ No newline at end of file diff --git a/app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json b/app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json deleted file mode 100644 index 3bb96a5e..00000000 --- a/app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 7, - "identityHash": "9951239671c916d8805c4156bb69cb6b", - "entities": [ - { - "tableName": "results", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `videoId` TEXT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `downloadedAudio` INTEGER NOT NULL, `downloadedVideo` INTEGER NOT NULL, `isPlaylistItem` INTEGER NOT NULL, `website` TEXT NOT NULL, `downloadingAudio` INTEGER NOT NULL, `downloadingVideo` INTEGER NOT NULL, `playlistTitle` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "videoId", - "columnName": "videoId", - "affinity": "TEXT", - "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": "downloadedAudio", - "columnName": "downloadedAudio", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "downloadedVideo", - "columnName": "downloadedVideo", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPlaylistItem", - "columnName": "isPlaylistItem", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "website", - "columnName": "website", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "downloadingAudio", - "columnName": "downloadingAudio", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "downloadingVideo", - "columnName": "downloadingVideo", - "affinity": "INTEGER", - "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, `isQueuedDownload` INTEGER 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 - }, - { - "fieldPath": "isQueuedDownload", - "columnName": "isQueuedDownload", - "affinity": "INTEGER", - "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, '9951239671c916d8805c4156bb69cb6b')" - ] - } -} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadsRecyclerViewAdapter.java b/app/src/main/java/com/deniscerri/ytdlnis/adapter/HistoryRecyclerViewAdapter.java similarity index 64% rename from app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadsRecyclerViewAdapter.java rename to app/src/main/java/com/deniscerri/ytdlnis/adapter/HistoryRecyclerViewAdapter.java index 76d3b1f2..627bed4d 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadsRecyclerViewAdapter.java +++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/HistoryRecyclerViewAdapter.java @@ -1,7 +1,6 @@ package com.deniscerri.ytdlnis.adapter; import android.app.Activity; -import android.content.Context; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; @@ -14,40 +13,51 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.cardview.widget.CardView; import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ListAdapter; import androidx.recyclerview.widget.RecyclerView; import com.deniscerri.ytdlnis.R; -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.card.MaterialCardView; -import com.google.android.material.progressindicator.LinearProgressIndicator; import com.squareup.picasso.Picasso; import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.List; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; -public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter { - private List videoList; - private ArrayList checkedVideos; - private ArrayList websites; +public class HistoryRecyclerViewAdapter extends ListAdapter { + private ArrayList checkedItems; private final OnItemClickListener onItemClickListener; private Activity activity; - public DownloadsRecyclerViewAdapter(OnItemClickListener onItemClickListener, Activity activity){ - this.videoList = new ArrayList<>(); - this.websites = new ArrayList<>(); - this.checkedVideos = new ArrayList<>(); + public HistoryRecyclerViewAdapter(OnItemClickListener onItemClickListener, Activity activity) { + super(DIFF_CALLBACK); + this.checkedItems = new ArrayList<>(); this.onItemClickListener = onItemClickListener; this.activity = activity; } + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull HistoryItem oldItem, @NonNull HistoryItem newItem) { + return oldItem.getId() == newItem.getId(); + } + + @Override + public boolean areContentsTheSame(@NonNull HistoryItem oldItem, @NonNull HistoryItem newItem) { + return oldItem.getTime() == newItem.getTime(); + } + }; + @Override public int getItemViewType(int position) { return super.getItemViewType(position); @@ -68,27 +78,25 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter Picasso.get().load(imageURL).into(thumbnail)); - thumbnail.setColorFilter(Color.argb(70, 0, 0, 0)); }else { - Handler uiHandler = new Handler(Looper.getMainLooper()); uiHandler.post(() -> Picasso.get().load(R.color.black).into(thumbnail)); - thumbnail.setColorFilter(Color.argb(70, 0, 0, 0)); } + thumbnail.setColorFilter(Color.argb(95, 0, 0, 0)); // TITLE ---------------------------------- TextView videoTitle = card.findViewById(R.id.downloads_title); @@ -110,8 +118,22 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter { - if(checkedVideos.size() > 0){ - checkCard(card, position); + if(checkedItems.size() > 0){ + checkCard(card, video.getId()); }else{ - onItemClickListener.onCardClick(position, finalFilePresent); + onItemClickListener.onCardClick(video.getId(), finalFilePresent); } }); } - public void setVideoList(List list){ - videoList.clear(); - videoList.addAll(list); - notifyDataSetChanged(); - } - private void checkCard(MaterialCardView card, int position){ + private void checkCard(MaterialCardView card, int videoID){ if(card.isChecked()){ card.setStrokeWidth(0); - checkedVideos.remove(Integer.valueOf(position)); + checkedItems.remove(videoID); }else{ card.setStrokeWidth(5); - checkedVideos.add(position); + checkedItems.add(videoID); } card.setChecked(!card.isChecked()); - onItemClickListener.onCardSelect(position, card.isChecked()); - } - - @Override - public int getItemCount() { - return videoList.size(); + onItemClickListener.onCardSelect(videoID, card.isChecked()); } public interface OnItemClickListener { @@ -192,44 +204,12 @@ public class DownloadsRecyclerViewAdapter extends RecyclerView.Adapter getWebsites(){ - return websites; - } - - public void updateWebsiteList(){ - websites = new ArrayList<>(); - for (HistoryItem 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); - } - public void clearCheckedVideos(){ - int size = checkedVideos.size(); + int size = checkedItems.size(); for (int i = 0; i < size; i++){ - int position = checkedVideos.get(i); + int position = checkedItems.get(i); notifyItemChanged(position); } - checkedVideos.clear(); + checkedItems.clear(); } - - public void add(ArrayList vids){ - int position = videoList.size() + 1; - videoList.addAll(vids); - notifyItemRangeInserted(position, vids.size()); - updateWebsiteList(); - } - - public void remove(int index){ - videoList.remove(index); - notifyItemRemoved(index); - updateWebsiteList(); - } - } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt index 5de6b6ef..9f50d408 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt @@ -3,7 +3,6 @@ package com.deniscerri.ytdlnis.database.dao import androidx.lifecycle.LiveData import androidx.room.* import com.deniscerri.ytdlnis.database.models.HistoryItem -import com.deniscerri.ytdlnis.util.FileUtil @Dao interface HistoryDao { @@ -12,7 +11,7 @@ interface HistoryDao { "CASE WHEN :sort = 'ASC' THEN id END ASC," + "CASE WHEN :sort = 'DESC' THEN id END DESC," + "CASE WHEN :sort = '' THEN id END DESC ") - fun getHistory(query : String, format : String, site : String, sort : String) : LiveData> + fun getHistory(query : String, format : String, site : String, sort : String) : List @Query("SELECT * FROM history") fun getAllHistory() : LiveData> @@ -23,8 +22,8 @@ interface HistoryDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(item: HistoryItem) - @Delete - suspend fun delete(item: HistoryItem) + @Query("DELETE FROM history WHERE id=:id") + suspend fun delete(id: Int) @Query("DELETE FROM history") suspend fun deleteAll() diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt index 17aaaddb..c3187615 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt @@ -12,7 +12,9 @@ data class DownloadItem( val author: String, val duration: String, val thumb: String, - val type: String, + val formatId: Int, + val formatDesc: String, val downloadPath: String, - val website: String + val website: String, + val downloadSize: String ) \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt index 7df81c78..3a841663 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt @@ -6,14 +6,14 @@ import androidx.room.PrimaryKey @Entity(tableName = "history") data class HistoryItem( @PrimaryKey(autoGenerate = true) - val id: Int, + var id: Int, val url: String, val title: String, val author: String, val duration: String, val thumb: String, val type: String, - val time: String, + val time: Long, val downloadPath: String, val website: String //val isQueuedDownload: Int diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt index d396ce38..9560b64b 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt @@ -3,6 +3,8 @@ package com.deniscerri.ytdlnis.database.models import androidx.room.Entity import androidx.room.PrimaryKey import com.google.gson.annotations.SerializedName +import com.yausername.youtubedl_android.mapper.VideoFormat +import com.yausername.youtubedl_android.mapper.VideoInfo @Entity(tableName = "results") data class ResultItem( diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt index ac63be7c..6dde90da 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt @@ -1,26 +1,41 @@ package com.deniscerri.ytdlnis.database.repository +import android.util.Log import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.room.Transaction import com.deniscerri.ytdlnis.database.dao.DownloadDao import com.deniscerri.ytdlnis.database.dao.HistoryDao import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.HistoryItem import com.deniscerri.ytdlnis.util.FileUtil +import java.io.File class HistoryRepository(private val historyDao: HistoryDao) { - val allHistory : LiveData> = historyDao.getAllHistory() + val items : LiveData> = historyDao.getAllHistory() + enum class HistorySort{ + DESC, ASC + } - suspend fun getItem(id: Int) : HistoryItem?{ + suspend fun getItem(id: Int) : HistoryItem { return historyDao.getHistoryItem(id) } + fun getFiltered(query : String, format : String, site : String, sort: HistorySort) : List { + return historyDao.getHistory(query, format, site, sort.toString()) + } + suspend fun insert(item: HistoryItem){ historyDao.insert(item) } - suspend fun delete(item: HistoryItem){ - historyDao.delete(item) + suspend fun delete(item: HistoryItem, deleteFile: Boolean){ + Log.e("ASd", item.id.toString()) + historyDao.delete(item.id) + if (deleteFile){ + val fileUtil = FileUtil() + fileUtil.deleteFile(item.downloadPath) + } } suspend fun deleteAll(){ @@ -37,9 +52,9 @@ class HistoryRepository(private val historyDao: HistoryDao) { suspend fun clearDeletedHistory(){ val fileUtil = FileUtil() - allHistory.value?.forEach { item -> + items.value?.forEach { item -> if (!fileUtil.exists(item.downloadPath)){ - delete(item) + delete(item, false) } } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt index 2f54192f..77698401 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt @@ -1,33 +1,88 @@ package com.deniscerri.ytdlnis.database.viewmodel import android.app.Application +import android.util.Log +import android.widget.Toast import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer import androidx.lifecycle.viewModelScope import com.deniscerri.ytdlnis.database.DBManager -import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.HistoryItem -import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.repository.HistoryRepository +import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class HistoryViewModel(application: Application) : AndroidViewModel(application) { private val repository : HistoryRepository - val allHistory : LiveData> + private val sortType = MutableLiveData(HistorySort.DESC) + private val websiteFilter = MutableLiveData("") + private val queryFilter = MutableLiveData("") + private val formatFilter = MutableLiveData("") + val allItems : LiveData> + private var _items = MediatorLiveData>() init { val dao = DBManager.getInstance(application).historyDao repository = HistoryRepository(dao) - allHistory = repository.allHistory + allItems = repository.items + + _items.addSource(allItems, Observer { + filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!) + }) + _items.addSource(formatFilter, Observer { + Log.e("aa", "audio"); + filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!) + }) + _items.addSource(sortType, Observer { + Log.e("aa", "asssssssssssss"); + filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!) + }) + _items.addSource(websiteFilter, Observer { + Log.e("Aa", "website") + filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!) + }) + _items.addSource(queryFilter, Observer { + filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!) + }) + + } + + fun getFilteredList() : LiveData>{ + return _items; + } + + fun setSorting(sort: HistorySort){ + Log.e("aa", "asssssssssssss"); + sortType.value = sort + } + + fun setWebsiteFilter(filter : String){ + websiteFilter.value = filter + } + + fun setQueryFilter(filter: String){ + queryFilter.value = filter + } + + fun setFormatFilter(filter: String){ + Log.e("aa", "audio"); + formatFilter.value = filter + } + + fun filter(query : String, format : String, site : String, sort: HistorySort) = viewModelScope.launch(Dispatchers.IO){ + _items.postValue(repository.getFiltered(query, format, site, sort)) } fun insert(item: HistoryItem) = viewModelScope.launch(Dispatchers.IO){ repository.insert(item) } - fun delete(item: HistoryItem) = viewModelScope.launch(Dispatchers.IO){ - repository.delete(item) + fun delete(item: HistoryItem, deleteFile: Boolean) = viewModelScope.launch(Dispatchers.IO){ + repository.delete(item, deleteFile) } fun deleteAll() = viewModelScope.launch(Dispatchers.IO) { diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadsFragment.kt index 8bc3e589..d012af98 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadsFragment.kt @@ -3,7 +3,6 @@ package com.deniscerri.ytdlnis.ui import android.app.Activity import android.content.* import android.net.Uri -import android.os.Binder import android.os.Bundle import android.os.Handler import android.os.Looper @@ -15,22 +14,17 @@ import android.widget.* import androidx.appcompat.widget.SearchView import androidx.core.content.FileProvider import androidx.fragment.app.Fragment -import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.R -import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter +import com.deniscerri.ytdlnis.adapter.HistoryRecyclerViewAdapter import com.deniscerri.ytdlnis.database.DatabaseManager -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.repository.HistoryRepository.HistorySort 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.util.FileUtil import com.facebook.shimmer.ShimmerFrameLayout import com.google.android.material.appbar.AppBarLayout @@ -40,50 +34,40 @@ import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton -import com.google.android.material.progressindicator.LinearProgressIndicator import java.io.File /** * A fragment representing a list of Items. */ -class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickListener, - View.OnClickListener, OnLongClickListener { +class DownloadsFragment : Fragment(), HistoryRecyclerViewAdapter.OnItemClickListener, + OnClickListener, OnLongClickListener { private lateinit var historyViewModel : HistoryViewModel private var downloading = false private var fragmentView: View? = null private var databaseManager: DatabaseManager? = null - var activity: Activity? = null - var mainActivity: MainActivity? = null - var fragmentContext: Context? = null + private var activity: Activity? = null + private var mainActivity: MainActivity? = null + private var fragmentContext: Context? = null private var layoutinflater: LayoutInflater? = null private var shimmerCards: ShimmerFrameLayout? = null private var topAppBar: MaterialToolbar? = null private var recyclerView: RecyclerView? = null - private var downloadsRecyclerViewAdapter: DownloadsRecyclerViewAdapter? = null + private var historyRecyclerViewAdapter: HistoryRecyclerViewAdapter? = null private var bottomSheet: BottomSheetDialog? = null private var sortSheet: BottomSheetDialog? = null private var uiHandler: Handler? = null - private var no_results: RelativeLayout? = null + private var noResults: RelativeLayout? = null private var selectionChips: LinearLayout? = null private var websiteGroup: ChipGroup? = null - private var downloadsObjects: List? = null - var selectedObjects: ArrayList? = null - private var progressBar: LinearProgressIndicator? = null + private var downloadsList: List? = null + private var allDownloadsList: List? = null + private var selectedObjects: ArrayList? = null private var deleteFab: ExtendedFloatingActionButton? = null private var fileUtil: FileUtil? = null - private var format = "" - private var website = "" - private var sort = "DESC" - private var searchQuery = "" private var _binding : FragmentDownloadsBinding? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -100,9 +84,10 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi super.onViewCreated(view, savedInstanceState) fragmentContext = context + layoutinflater = LayoutInflater.from(context) shimmerCards = view.findViewById(R.id.shimmer_downloads_framelayout) topAppBar = view.findViewById(R.id.downloads_toolbar) - no_results = view.findViewById(R.id.downloads_no_results) + noResults = view.findViewById(R.id.downloads_no_results) selectionChips = view.findViewById(R.id.downloads_selection_chips) websiteGroup = view.findViewById(R.id.website_chip_group) deleteFab = view.findViewById(R.id.delete_selected_fab) @@ -110,77 +95,58 @@ class DownloadsFragment : Fragment(), DownloadsRecyclerViewAdapter.OnItemClickLi deleteFab?.tag = "deleteSelected" deleteFab?.setOnClickListener(this) uiHandler = Handler(Looper.getMainLooper()) - downloadsObjects = ArrayList() selectedObjects = ArrayList() downloading = mainActivity!!.isDownloadServiceRunning() - downloadsObjects = mutableListOf() + downloadsList = mutableListOf() + allDownloadsList = mutableListOf() - downloadsRecyclerViewAdapter = - DownloadsRecyclerViewAdapter(this, activity) + historyRecyclerViewAdapter = + HistoryRecyclerViewAdapter( + this, + activity + ) recyclerView = view.findViewById(R.id.recyclerviewdownloadss) recyclerView?.layoutManager = LinearLayoutManager(context) - recyclerView?.adapter = downloadsRecyclerViewAdapter + recyclerView?.adapter = historyRecyclerViewAdapter - downloadsRecyclerViewAdapter!!.clear() - no_results?.visibility = GONE + noResults?.visibility = GONE selectionChips?.visibility = VISIBLE shimmerCards?.visibility = GONE historyViewModel = ViewModelProvider(this)[HistoryViewModel::class.java] - historyViewModel.allHistory.observe(viewLifecycleOwner) { - downloadsRecyclerViewAdapter!!.setVideoList(it); - Toast.makeText(context, "CHANGED", Toast.LENGTH_SHORT).show() + historyViewModel.allItems.observe(viewLifecycleOwner) { + allDownloadsList = it + if(it.isEmpty()){ + noResults!!.visibility = VISIBLE + selectionChips!!.visibility = GONE + websiteGroup!!.removeAllViews() + }else{ + noResults!!.visibility = GONE + selectionChips!!.visibility = VISIBLE + updateWebsiteChips(it) + } } + historyViewModel.getFilteredList().observe(viewLifecycleOwner) { + historyRecyclerViewAdapter!!.submitList(it) + downloadsList = it + } initMenu() - //initChips() -// initCards() + initChips() } -// 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