added search history
This commit is contained in:
parent
0047f8a833
commit
1adba854e8
10 changed files with 124 additions and 100 deletions
|
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "ae6989cdbd101bb25c22cc38d8ec456d",
|
||||
"identityHash": "2a124f7c327413ab152e18a9e4a66ef7",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "results",
|
||||
|
|
@ -313,12 +313,38 @@
|
|||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "searchHistory",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `query` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "query",
|
||||
"columnName": "query",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"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, 'ae6989cdbd101bb25c22cc38d8ec456d')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2a124f7c327413ab152e18a9e4a66ef7')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ import com.deniscerri.ytdlnis.database.models.*
|
|||
|
||||
@TypeConverters(Converters::class)
|
||||
@Database(
|
||||
entities = [ResultItem::class, HistoryItem::class, DownloadItem::class, CommandTemplate::class],
|
||||
entities = [ResultItem::class, HistoryItem::class, DownloadItem::class, CommandTemplate::class, SearchHistoryItem::class],
|
||||
version = 1,
|
||||
autoMigrations = []
|
||||
)
|
||||
|
|
@ -19,6 +19,7 @@ abstract class DBManager : RoomDatabase(){
|
|||
abstract val historyDao : HistoryDao
|
||||
abstract val downloadDao : DownloadDao
|
||||
abstract val commandTemplateDao : CommandTemplateDao
|
||||
abstract val searchHistoryDao: SearchHistoryDao
|
||||
|
||||
companion object {
|
||||
//prevents multiple instances of db getting created at the same time
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.deniscerri.ytdlnis.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import com.deniscerri.ytdlnis.database.models.SearchHistoryItem
|
||||
|
||||
@Dao
|
||||
interface SearchHistoryDao {
|
||||
@Query("SELECT * from searchHistory ORDER BY id DESC LIMIT 10")
|
||||
fun getAll() : List<SearchHistoryItem>
|
||||
|
||||
@Query("SELECT * from searchHistory WHERE query COLLATE NOCASE ='%'||:keyword||'%'")
|
||||
fun getAllByKeyword(keyword: String) : List<SearchHistoryItem>
|
||||
|
||||
@Insert
|
||||
suspend fun insert(new: SearchHistoryItem)
|
||||
|
||||
@Query("DELETE FROM searchHistory")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
|
||||
@Entity(tableName = "searchHistory")
|
||||
data class SearchHistoryItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
val query: String
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.deniscerri.ytdlnis.database.repository
|
||||
|
||||
import com.deniscerri.ytdlnis.database.dao.SearchHistoryDao
|
||||
import com.deniscerri.ytdlnis.database.models.SearchHistoryItem
|
||||
|
||||
class SearchHistoryRepository(private val searchHistoryDao: SearchHistoryDao) {
|
||||
fun getAll() : List<SearchHistoryItem> {
|
||||
return searchHistoryDao.getAll()
|
||||
}
|
||||
|
||||
fun getAllByKeyword(keyword: String) : List<SearchHistoryItem> {
|
||||
return searchHistoryDao.getAllByKeyword(keyword)
|
||||
}
|
||||
|
||||
suspend fun insert(query: String){
|
||||
searchHistoryDao.insert(SearchHistoryItem(0, query))
|
||||
}
|
||||
|
||||
suspend fun deleteAll(){
|
||||
searchHistoryDao.deleteAll()
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ import com.deniscerri.ytdlnis.App
|
|||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.models.SearchHistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
||||
import com.deniscerri.ytdlnis.database.repository.SearchHistoryRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.regex.Pattern
|
||||
|
|
@ -15,6 +17,7 @@ import java.util.regex.Pattern
|
|||
class ResultViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private val tag: String = "ResultViewModel"
|
||||
private val repository : ResultRepository
|
||||
private val searchHistoryRepository : SearchHistoryRepository
|
||||
val items : LiveData<List<ResultItem>>
|
||||
val loadingItems = MutableLiveData<Boolean>()
|
||||
var itemCount : LiveData<Int>
|
||||
|
|
@ -23,6 +26,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
val dao = DBManager.getInstance(application).resultDao
|
||||
val commandDao = DBManager.getInstance(application).commandTemplateDao
|
||||
repository = ResultRepository(dao, commandDao, getApplication<Application>().applicationContext)
|
||||
searchHistoryRepository = SearchHistoryRepository(DBManager.getInstance(application).searchHistoryDao)
|
||||
items = repository.allResults
|
||||
loadingItems.postValue(false)
|
||||
itemCount = repository.itemCount
|
||||
|
|
@ -99,4 +103,16 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
fun getItemByURL(url: String) : ResultItem {
|
||||
return repository.getItemByURL(url)
|
||||
}
|
||||
|
||||
fun addSearchQueryToHistory(query: String) = viewModelScope.launch(Dispatchers.IO) {
|
||||
searchHistoryRepository.insert(query)
|
||||
}
|
||||
|
||||
fun deleteAllSearchQueryHistory() = viewModelScope.launch(Dispatchers.IO){
|
||||
searchHistoryRepository.deleteAll()
|
||||
}
|
||||
|
||||
fun getSearchHistory() : List<SearchHistoryItem> {
|
||||
return searchHistoryRepository.getAll()
|
||||
}
|
||||
}
|
||||
|
|
@ -251,6 +251,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_URI
|
||||
searchView.queryHint = getString(R.string.search_hint)
|
||||
infoUtil = InfoUtil(requireContext())
|
||||
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
topAppBar!!.menu.findItem(R.id.search).collapseActionView()
|
||||
|
|
@ -258,6 +259,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
downloadFabs!!.visibility = GONE
|
||||
selectedObjects = ArrayList()
|
||||
inputQuery = query.trim { it <= ' ' }
|
||||
if(!sharedPreferences!!.getBoolean("incognito", false)){
|
||||
resultViewModel.addSearchQueryToHistory(inputQuery!!)
|
||||
}
|
||||
resultViewModel.deleteAll()
|
||||
val thread = Thread {
|
||||
resultViewModel.parseQuery(inputQuery!!, true)
|
||||
|
|
@ -268,9 +272,12 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
searchSuggestionsLinearLayout!!.removeAllViews()
|
||||
if (newText.isEmpty()) return false
|
||||
val thread = Thread {
|
||||
val suggestions = infoUtil!!.getSearchSuggestions(newText)
|
||||
val suggestions = if (newText.isEmpty()) {
|
||||
resultViewModel.getSearchHistory().map { it.query }
|
||||
}else{
|
||||
infoUtil!!.getSearchSuggestions(newText)
|
||||
}
|
||||
for (i in suggestions.indices) {
|
||||
val v = LayoutInflater.from(fragmentContext)
|
||||
.inflate(R.layout.search_suggestion_item, null)
|
||||
|
|
@ -307,15 +314,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
try {
|
||||
mainActivity!!.cancelAllDownloads()
|
||||
topAppBar!!.menu.findItem(itemId).isVisible = false
|
||||
// for (i in downloadInfo!!.downloadQueue.indices) {
|
||||
// val vid = downloadInfo!!.downloadQueue[i]
|
||||
// val type = vid.downloadedType
|
||||
// updateDownloadingStatusOnResult(vid, type, false)
|
||||
// }
|
||||
// downloadQueue = ArrayList()
|
||||
// downloading = false
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
} catch (ignored: Exception) {}
|
||||
} else if (itemId == R.id.delete_search){
|
||||
resultViewModel.deleteAllSearchQueryHistory()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
@ -351,29 +352,11 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
val item = resultsList!!.find { it?.url == videoURL }
|
||||
Log.e(TAG, resultsList!![0].toString() + " " + videoURL)
|
||||
val btn = recyclerView!!.findViewWithTag<MaterialButton>("""${item?.url}##$type""")
|
||||
// if (downloading) {
|
||||
// try {
|
||||
// if (btn.getTag(R.id.cancelDownload) == "true") {
|
||||
// mainActivity!!.removeItemFromDownloadQueue(vid, type)
|
||||
// return
|
||||
// }
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)) {
|
||||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.add(item!!)
|
||||
//showConfigureSingleDownloadCard(createDownloadItem(item!!, type), item)
|
||||
showSingleDownloadSheet(item!!, type!!)
|
||||
} else {
|
||||
val downloadItem = downloadViewModel.createDownloadItemFromResult(item!!, type!!)
|
||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||
// downloadQueue!!.add(vid)
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,32 +365,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
}
|
||||
|
||||
|
||||
fun updateDownloadStatusOnResult(v: ResultItem?, type: String?, downloaded: Boolean) {
|
||||
// if (v != null) {
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// try {
|
||||
// databaseManager!!.updateDownloadStatusOnResult(v.videoId, type, downloaded)
|
||||
// databaseManager!!.close()
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateDownloadingStatusOnResult(v: ResultItem?, type: String, isDownloading: Boolean) {
|
||||
// if (v != null) {
|
||||
// if (type == "audio") v.isDownloadingAudio =
|
||||
// isDownloading else if (type == "video") v.isDownloadingVideo = isDownloading
|
||||
// homeAdapter!!.updateVideoListItem(v, resultsList!!.indexOf(v))
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// try {
|
||||
// databaseManager!!.updateDownloadingStatusOnResult(v.videoId, type, isDownloading)
|
||||
// databaseManager!!.close()
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onCardClick(videoURL: String, add: Boolean) {
|
||||
val item = resultsList?.find { it -> it?.url == videoURL }
|
||||
if (add) selectedObjects!!.add(item!!) else selectedObjects!!.remove(item)
|
||||
|
|
@ -460,47 +417,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
private fun initDownloadAll(
|
||||
bottomSheet: BottomSheetDialog,
|
||||
start: Int,
|
||||
end: Int,
|
||||
type: String
|
||||
) {
|
||||
// var start = start
|
||||
// var end = end
|
||||
// if (start > end) {
|
||||
// val first = bottomSheet.findViewById<TextInputLayout>(R.id.first_textinput)
|
||||
// first!!.error = getString(R.string.first_cant_be_larger_than_last)
|
||||
// val last = bottomSheet.findViewById<TextInputLayout>(R.id.last_textinput)
|
||||
// last!!.error = getString(R.string.last_cant_be_smaller_than_first)
|
||||
// return
|
||||
// }
|
||||
// bottomSheet.cancel()
|
||||
// start--
|
||||
// end--
|
||||
// if (start <= 1) start = 0
|
||||
// val sharedPreferences =
|
||||
// requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
// if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.addAll(resultsList!!.subList(start, end + 1) as ArrayList<ResultItem>)
|
||||
// showConfigureDownloadCard(type)
|
||||
// } else {
|
||||
// for (i in start..end) {
|
||||
// val vid = findVideo(
|
||||
// resultsList!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ import android.app.Activity
|
|||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.repository.SearchHistoryRepository
|
||||
import com.google.gson.Gson
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
|
|
@ -21,6 +23,7 @@ import java.util.*
|
|||
import kotlin.collections.ArrayList
|
||||
|
||||
class InfoUtil(context: Context) {
|
||||
private var searchHistoryRepository = SearchHistoryRepository(DBManager.getInstance(context).searchHistoryDao)
|
||||
private var items: ArrayList<ResultItem?>
|
||||
private var key: String? = null
|
||||
private var useInvidous = false
|
||||
|
|
@ -532,7 +535,8 @@ class InfoUtil(context: Context) {
|
|||
val suggestionList = ArrayList<String>()
|
||||
try {
|
||||
for (i in 0 until res.getJSONArray(1).length()) {
|
||||
suggestionList.add(res.getJSONArray(1).getString(i))
|
||||
val item = res.getJSONArray(1).getString(i)
|
||||
suggestionList.add(item)
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
ignored.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@
|
|||
android:title="@string/remove_results"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_search"
|
||||
android:title="@string/remove_search_history"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/cancel_download"
|
||||
android:title="@string/cancel_download"
|
||||
|
|
|
|||
|
|
@ -173,4 +173,5 @@
|
|||
<string name="format">Format</string>
|
||||
<string name="select_format">Select Format</string>
|
||||
<string name="please_wait">Please Wait</string>
|
||||
<string name="remove_search_history">Clear Search History</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue