From b330a5ba08627a8142e13e9bc1336cea4200bb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C3=87erri?= <64997243+deniscerri@users.noreply.github.com> Date: Sun, 8 Jan 2023 16:50:57 +0100 Subject: [PATCH] dev init --- app/build.gradle | 8 +- app/src/main/AndroidManifest.xml | 4 +- .../deniscerri/ytdlnis/DownloaderService.kt | 8 +- .../com/deniscerri/ytdlnis/MainActivity.kt | 8 +- .../deniscerri/ytdlnis/database/DBManager.kt | 42 + .../ytdlnis/database/dao/DownloadDao.kt | 29 + .../ytdlnis/database/dao/HistoryDao.kt | 37 + .../ytdlnis/database/dao/ResultDao.kt | 21 + .../ytdlnis/database/models/DownloadItem.kt | 18 + .../ytdlnis/database/models/HistoryItem.kt | 20 + .../ytdlnis/database/models/ResultItem.kt | 17 + .../database/repository/DownloadRepository.kt | 23 + .../database/repository/HistoryRepository.kt | 50 ++ .../database/repository/ResultRepository.kt | 27 + .../database/viewmodel/DownloadViewModel.kt | 34 + .../database/viewmodel/HistoryViewModel.kt | 48 ++ .../database/viewmodel/ResultViewModel.kt | 36 + .../ytdlnis/page/DownloadsFragment.java | 738 ------------------ .../{page => ui}/CustomCommandActivity.java | 4 +- .../ytdlnis/ui/DownloadsFragment.kt | 554 +++++++++++++ .../ytdlnis/{page => ui}/HomeFragment.java | 2 +- .../ytdlnis/{page => ui}/MoreFragment.java | 2 +- .../settings/SettingsActivity.java | 2 +- .../{page => ui}/settings/SettingsFragment.kt | 2 +- .../ytdlnis/work/DownloadWorker.java | 36 + .../ytdlnis/work/FileTransferWorker.kt | 1 - .../res/layout/activity_custom_command.xml | 2 +- app/src/main/res/layout/activity_settings.xml | 2 +- build.gradle | 2 + settings.gradle | 1 + 30 files changed, 1016 insertions(+), 762 deletions(-) create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/DBManager.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/dao/DownloadDao.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/dao/ResultDao.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/repository/ResultRepository.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt delete mode 100644 app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java rename app/src/main/java/com/deniscerri/ytdlnis/{page => ui}/CustomCommandActivity.java (98%) create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadsFragment.kt rename app/src/main/java/com/deniscerri/ytdlnis/{page => ui}/HomeFragment.java (99%) rename app/src/main/java/com/deniscerri/ytdlnis/{page => ui}/MoreFragment.java (91%) rename app/src/main/java/com/deniscerri/ytdlnis/{page => ui}/settings/SettingsActivity.java (96%) rename app/src/main/java/com/deniscerri/ytdlnis/{page => ui}/settings/SettingsFragment.kt (99%) create mode 100644 app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.java diff --git a/app/build.gradle b/app/build.gradle index a32a83dc..b5754782 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -113,7 +113,7 @@ dependencies { implementation "com.devbrackets.android:exomedia:4.3.0" implementation("androidx.cardview:cardview:1.0.0") - implementation("com.squareup.picasso:picasso:2.8") + implementation("com.squareup.picasso:picasso:2.71828") implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' @@ -131,4 +131,10 @@ dependencies { api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVer" api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVer" + + implementation "com.squareup.retrofit2:retrofit:$retrofitVer" + implementation "com.squareup.retrofit2:converter-gson:$retrofitVer" + + implementation "org.kodein.di:kodein-di-generic-jvm:6.4.0" + implementation "org.kodein.di:kodein-di-framework-android-x:$kodeinVer" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f5d5794c..886e4b13 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,7 +39,7 @@ @@ -48,7 +48,7 @@ > + + @Query("SELECT * FROM downloads WHERE id=:id LIMIT 1") + suspend fun getDownloadById(id: Int) : DownloadItem + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insert(item: DownloadItem) + + @Query("DELETE FROM downloads") + suspend fun deleteAll() + + @Delete + suspend fun delete(item: DownloadItem) + + @Update(onConflict = OnConflictStrategy.REPLACE) + suspend fun update(item: DownloadItem) +} \ No newline at end of file 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 new file mode 100644 index 00000000..78e1dccb --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt @@ -0,0 +1,37 @@ +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 { + + @Query("SELECT * FROM history WHERE title LIKE '%'||:query||'%' AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " + + "CASE WHEN :sort = 'ASC' THEN id END ASC," + + "CASE WHEN :sort = 'DESC' THEN id END DESC," + + "CASE WHEN :sort = '' THEN id END DESC ") + suspend fun getHistory(query : String, format : String, site : String, sort : String) : LiveData> + + @Query("SELECT * FROM history") + fun getAllHistory() : LiveData> + + @Query("SELECT * FROM history WHERE id=:id LIMIT 1") + suspend fun getHistoryItem(id: Int) : HistoryItem + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(item: HistoryItem) + + @Delete + suspend fun delete(item: HistoryItem) + + @Query("DELETE FROM history") + suspend fun deleteAll() + + @Query("DELETE FROM history WHERE id > (SELECT MIN(h.id) FROM history h WHERE h.url = history.url AND h.type = history.type)") + suspend fun deleteDuplicates() + + @Update + suspend fun update(item: HistoryItem) +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/ResultDao.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/ResultDao.kt new file mode 100644 index 00000000..1aa7f5b4 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/ResultDao.kt @@ -0,0 +1,21 @@ +package com.deniscerri.ytdlnis.database.dao + +import androidx.lifecycle.LiveData +import androidx.room.* +import com.deniscerri.ytdlnis.database.models.ResultItem +import com.deniscerri.ytdlnis.util.FileUtil + +@Dao +interface ResultDao { + @Query("SELECT * FROM results") + fun getResults() : LiveData> + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(item: ResultItem) + + @Update(onConflict = OnConflictStrategy.REPLACE) + suspend fun update(item: ResultItem) + + @Query("DELETE FROM results") + suspend fun deleteAll() +} \ No newline at end of file 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 new file mode 100644 index 00000000..17aaaddb --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt @@ -0,0 +1,18 @@ +package com.deniscerri.ytdlnis.database.models + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "downloads") +data class DownloadItem( + @PrimaryKey(autoGenerate = true) + val id: Int, + val url: String, + val title: String, + val author: String, + val duration: String, + val thumb: String, + val type: String, + val downloadPath: String, + val website: 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 new file mode 100644 index 00000000..7df81c78 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/HistoryItem.kt @@ -0,0 +1,20 @@ +package com.deniscerri.ytdlnis.database.models + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "history") +data class HistoryItem( + @PrimaryKey(autoGenerate = true) + val id: Int, + val url: String, + val title: String, + val author: String, + val duration: String, + val thumb: String, + val type: String, + val time: String, + val downloadPath: String, + val website: String + //val isQueuedDownload: Int +) \ No newline at end of file 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 new file mode 100644 index 00000000..28950f67 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt @@ -0,0 +1,17 @@ +package com.deniscerri.ytdlnis.database.models + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "results") +data class ResultItem( + @PrimaryKey(autoGenerate = true) + val id: Int, + val url: String, + val title: String, + val author: String, + val duration: String, + val thumb: String, + val website: String, + val playlistTitle: String +) \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt new file mode 100644 index 00000000..e9538190 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt @@ -0,0 +1,23 @@ +package com.deniscerri.ytdlnis.database.repository + +import androidx.lifecycle.LiveData +import com.deniscerri.ytdlnis.database.dao.DownloadDao +import com.deniscerri.ytdlnis.database.models.DownloadItem + +class DownloadRepository(private val downloadDao: DownloadDao) { + val allDownloads : LiveData> = downloadDao.getAllDownloads() + + suspend fun insert(item: DownloadItem){ + downloadDao.insert(item) + } + + suspend fun delete(item: DownloadItem){ + downloadDao.delete(item) + } + + suspend fun update(item: DownloadItem){ + downloadDao.update(item) + } + + +} \ No newline at end of file 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 new file mode 100644 index 00000000..ac63be7c --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt @@ -0,0 +1,50 @@ +package com.deniscerri.ytdlnis.database.repository + +import androidx.lifecycle.LiveData +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 + +class HistoryRepository(private val historyDao: HistoryDao) { + val allHistory : LiveData> = historyDao.getAllHistory() + + suspend fun getItem(id: Int) : HistoryItem?{ + return historyDao.getHistoryItem(id) + } + + suspend fun insert(item: HistoryItem){ + historyDao.insert(item) + } + + suspend fun delete(item: HistoryItem){ + historyDao.delete(item) + } + + suspend fun deleteAll(){ + historyDao.deleteAll() + } + + suspend fun deleteDuplicates(){ + historyDao.deleteDuplicates() + } + + suspend fun update(item: HistoryItem){ + historyDao.update(item) + } + + suspend fun clearDeletedHistory(){ + val fileUtil = FileUtil() + allHistory.value?.forEach { item -> + if (!fileUtil.exists(item.downloadPath)){ + delete(item) + } + } + } + + suspend fun checkDownloaded(){ + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/ResultRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/ResultRepository.kt new file mode 100644 index 00000000..73b589e1 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/ResultRepository.kt @@ -0,0 +1,27 @@ +package com.deniscerri.ytdlnis.database.repository + +import androidx.lifecycle.LiveData +import com.deniscerri.ytdlnis.database.dao.DownloadDao +import com.deniscerri.ytdlnis.database.dao.ResultDao +import com.deniscerri.ytdlnis.database.models.DownloadItem +import com.deniscerri.ytdlnis.database.models.ResultItem + +class ResultRepository(private val resultDao: ResultDao) { + val allResults : LiveData> = resultDao.getResults() + + suspend fun insert(items: List){ + items.forEach { + resultDao.insert(it) + } + } + + suspend fun deleteAll(){ + resultDao.deleteAll() + } + + suspend fun update(item: ResultItem){ + resultDao.update(item) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt new file mode 100644 index 00000000..420e5dad --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt @@ -0,0 +1,34 @@ +package com.deniscerri.ytdlnis.database.viewmodel + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.viewModelScope +import com.deniscerri.ytdlnis.database.DBManager +import com.deniscerri.ytdlnis.database.models.DownloadItem +import com.deniscerri.ytdlnis.database.repository.DownloadRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class DownloadViewModel(application: Application) : AndroidViewModel(application) { + private val repository : DownloadRepository + private val allDownloads : LiveData> + + init { + val dao = DBManager.getInstance(application).downloadDao + repository = DownloadRepository(dao) + allDownloads = repository.allDownloads + } + + fun insertDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO){ + repository.insert(item) + } + + fun deleteDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO) { + repository.delete(item) + } + + fun updateDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO){ + repository.update(item); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..fc6fc7f1 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt @@ -0,0 +1,48 @@ +package com.deniscerri.ytdlnis.database.viewmodel + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +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 kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class HistoryViewModel(application: Application) : AndroidViewModel(application) { + private val repository : HistoryRepository + private val allHistory : LiveData> + + init { + val dao = DBManager.getInstance(application).historyDao + repository = HistoryRepository(dao) + allHistory = repository.allHistory + } + + fun insert(item: HistoryItem) = viewModelScope.launch(Dispatchers.IO){ + repository.insert(item) + } + + fun delete(item: HistoryItem) = viewModelScope.launch(Dispatchers.IO){ + repository.delete(item) + } + + fun deleteAll() = viewModelScope.launch(Dispatchers.IO) { + repository.deleteAll() + } + + fun deleteDuplicates() = viewModelScope.launch(Dispatchers.IO) { + repository.deleteDuplicates() + } + + fun update(item: HistoryItem) = viewModelScope.launch(Dispatchers.IO){ + repository.update(item); + } + + fun clearDeleted() = viewModelScope.launch(Dispatchers.IO) { + repository.clearDeletedHistory() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt new file mode 100644 index 00000000..f9de4230 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt @@ -0,0 +1,36 @@ +package com.deniscerri.ytdlnis.database.viewmodel + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.viewModelScope +import com.deniscerri.ytdlnis.database.DBManager +import com.deniscerri.ytdlnis.database.models.DownloadItem +import com.deniscerri.ytdlnis.database.models.ResultItem +import com.deniscerri.ytdlnis.database.repository.DownloadRepository +import com.deniscerri.ytdlnis.database.repository.ResultRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class ResultViewModel(application: Application) : AndroidViewModel(application) { + private val repository : ResultRepository + private val allResults : LiveData> + + init { + val dao = DBManager.getInstance(application).resultDao + repository = ResultRepository(dao) + allResults = repository.allResults + } + + fun insert(items: List) = viewModelScope.launch(Dispatchers.IO){ + repository.insert(items) + } + + fun deleteAll() = viewModelScope.launch(Dispatchers.IO) { + repository.deleteAll() + } + + fun update(item: ResultItem) = viewModelScope.launch(Dispatchers.IO){ + repository.update(item); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java b/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java deleted file mode 100644 index 46d38c76..00000000 --- a/app/src/main/java/com/deniscerri/ytdlnis/page/DownloadsFragment.java +++ /dev/null @@ -1,738 +0,0 @@ -package com.deniscerri.ytdlnis.page; - -import android.app.Activity; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.media.MediaScannerConnection; -import android.net.Uri; -import android.os.Bundle; -import androidx.appcompat.widget.SearchView; -import androidx.core.content.FileProvider; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.RecyclerView; -import android.os.Handler; -import android.os.Looper; -import android.text.InputType; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; -import com.deniscerri.ytdlnis.MainActivity; -import com.deniscerri.ytdlnis.R; -import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter; -import com.deniscerri.ytdlnis.database.DatabaseManager; -import com.deniscerri.ytdlnis.database.Video; -import com.deniscerri.ytdlnis.service.DownloadInfo; -import com.deniscerri.ytdlnis.service.IDownloaderListener; -import com.deniscerri.ytdlnis.util.FileUtil; -import com.facebook.shimmer.ShimmerFrameLayout; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.MaterialToolbar; -import com.google.android.material.bottomsheet.BottomSheetDialog; -import com.google.android.material.chip.Chip; -import com.google.android.material.chip.ChipGroup; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; -import com.google.android.material.progressindicator.LinearProgressIndicator; -import java.io.File; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; - -/** - * A fragment representing a list of Items. - */ -public class DownloadsFragment extends Fragment implements DownloadsRecyclerViewAdapter.OnItemClickListener, View.OnClickListener, View.OnLongClickListener{ - private boolean downloading = false; - private View fragmentView; - private DatabaseManager databaseManager; - Context context; - Activity activity; - MainActivity mainActivity; - Context fragmentContext; - private LayoutInflater layoutinflater; - private ShimmerFrameLayout shimmerCards; - private MaterialToolbar topAppBar; - private RecyclerView recyclerView; - private DownloadsRecyclerViewAdapter downloadsRecyclerViewAdapter; - private BottomSheetDialog bottomSheet; - private BottomSheetDialog sortSheet; - private Handler uiHandler; - private RelativeLayout no_results; - private LinearLayout selectionChips; - private ChipGroup websiteGroup; - private ArrayList