added search history

This commit is contained in:
Denis Çerri 2023-02-25 20:32:26 +01:00
parent 0047f8a833
commit 1adba854e8
No known key found for this signature in database
GPG key ID: 95C43D517D830350
10 changed files with 124 additions and 100 deletions

View file

@ -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')"
]
}
}

View file

@ -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

View file

@ -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()
}

View file

@ -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
)

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -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"
}

View file

@ -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()

View file

@ -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"

View file

@ -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>