kotlin-migration init
This commit is contained in:
parent
f2c4fc33a3
commit
604fd300c8
22 changed files with 981 additions and 507 deletions
1
.idea/.name
Normal file
1
.idea/.name
Normal file
|
|
@ -0,0 +1 @@
|
|||
YTDLnis
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8" />
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import java.util.regex.Pattern
|
||||
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'com.google.secrets_gradle_plugin' version '0.4'
|
||||
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'kotlin-kapt'
|
||||
}
|
||||
|
||||
def properties = new Properties()
|
||||
|
|
@ -20,7 +20,7 @@ android {
|
|||
keyPassword properties["signingConfig.keyPassword"]
|
||||
}
|
||||
}
|
||||
compileSdkVersion 31
|
||||
compileSdkVersion 33
|
||||
defaultConfig {
|
||||
applicationId "com.deniscerri.ytdl"
|
||||
minSdkVersion 23
|
||||
|
|
@ -32,8 +32,22 @@ android {
|
|||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
||||
}
|
||||
vectorDrawables {
|
||||
useSupportLibrary true
|
||||
}
|
||||
|
||||
kapt {
|
||||
arguments {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
|
|
@ -53,6 +67,9 @@ android {
|
|||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
splits {
|
||||
abi {
|
||||
|
|
@ -62,9 +79,9 @@ android {
|
|||
universalApk true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion composeVer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -80,13 +97,14 @@ dependencies {
|
|||
|
||||
implementation "androidx.appcompat:appcompat:$appCompatVer"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.7.0'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.core:core:1.8.0'
|
||||
implementation 'androidx.core:core:1.9.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.5.2'
|
||||
implementation 'androidx.navigation:navigation-ui:2.5.2'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.5.3'
|
||||
implementation 'androidx.navigation:navigation-ui:2.5.3'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
testImplementation "junit:junit:$junitVer"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer"
|
||||
|
|
@ -102,4 +120,14 @@ dependencies {
|
|||
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
||||
|
||||
implementation "androidx.work:work-runtime:$workVer"
|
||||
|
||||
implementation "androidx.room:room-runtime:2.4.3"
|
||||
implementation "androidx.room:room-ktx:2.4.3"
|
||||
kapt "androidx.room:room-compiler:2.4.3"
|
||||
androidTestImplementation "androidx.room:room-testing:2.4.3"
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
|
||||
implementation "androidx.compose.runtime:runtime:$composeVer"
|
||||
|
||||
|
||||
androidTestImplementation "com.google.truth:truth:1.1.3"
|
||||
}
|
||||
192
app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json
Normal file
192
app/schemas/com.deniscerri.ytdlnis.database.DBManager/7.json
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
{
|
||||
"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')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -26,10 +26,8 @@ public class App extends Application {
|
|||
public void onCreate() {
|
||||
super.onCreate();
|
||||
DynamicColors.applyToActivitiesIfAvailable(this);
|
||||
|
||||
notificationUtil = new NotificationUtil(this);
|
||||
createNotificationChannels();
|
||||
|
||||
PreferenceManager.setDefaultValues(this, "root_preferences", this.MODE_PRIVATE, R.xml.root_preferences, false);
|
||||
configureRxJavaErrorHandler();
|
||||
Completable.fromAction(this::initLibraries).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new DisposableCompletableObserver() {
|
||||
|
|
|
|||
|
|
@ -1,359 +0,0 @@
|
|||
package com.deniscerri.ytdlnis;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.DBManager;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding;
|
||||
import com.deniscerri.ytdlnis.page.DownloadsFragment;
|
||||
import com.deniscerri.ytdlnis.page.HomeFragment;
|
||||
import com.deniscerri.ytdlnis.page.MoreFragment;
|
||||
import com.deniscerri.ytdlnis.page.settings.SettingsActivity;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService;
|
||||
import com.deniscerri.ytdlnis.util.UpdateUtil;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends AppCompatActivity{
|
||||
|
||||
ActivityMainBinding binding;
|
||||
Context context;
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
private HomeFragment homeFragment;
|
||||
private DownloadsFragment downloadsFragment;
|
||||
private MoreFragment moreFragment;
|
||||
|
||||
private Fragment lastFragment;
|
||||
private FragmentManager fm;
|
||||
|
||||
private boolean isDownloadServiceRunning = false;
|
||||
public DownloaderService downloaderService;
|
||||
private ArrayList<IDownloaderListener> listeners = null;
|
||||
private IDownloaderService iDownloaderService;
|
||||
|
||||
public final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
downloaderService = ((DownloaderService.LocalBinder) service).getService();
|
||||
iDownloaderService = (IDownloaderService) service;
|
||||
isDownloadServiceRunning = true;
|
||||
try{
|
||||
iDownloaderService.addActivity(MainActivity.this, listeners);
|
||||
for (int i = 0; i < listeners.size(); i++){
|
||||
IDownloaderListener listener = listeners.get(i);
|
||||
listener.onDownloadStart(iDownloaderService.getDownloadInfo());
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
downloaderService = null;
|
||||
iDownloaderService = null;
|
||||
isDownloadServiceRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
setContentView(binding.getRoot());
|
||||
context = getBaseContext();
|
||||
reconnectDownloadService();
|
||||
checkUpdate();
|
||||
|
||||
fm = getSupportFragmentManager();
|
||||
|
||||
homeFragment = new HomeFragment();
|
||||
downloadsFragment = new DownloadsFragment();
|
||||
moreFragment = new MoreFragment();
|
||||
|
||||
initFragments();
|
||||
|
||||
binding.bottomNavigationView.setOnItemSelectedListener(item -> {
|
||||
int id = item.getItemId();
|
||||
if(id == R.id.home){
|
||||
if(lastFragment == homeFragment){
|
||||
homeFragment.scrollToTop();
|
||||
}else{
|
||||
this.setTitle(R.string.app_name);;
|
||||
}
|
||||
replaceFragment(homeFragment);
|
||||
}else if(id == R.id.downloads){
|
||||
if(lastFragment == downloadsFragment){
|
||||
downloadsFragment.scrollToTop();
|
||||
}else {
|
||||
this.setTitle(getString(R.string.downloads));
|
||||
}
|
||||
replaceFragment(downloadsFragment);
|
||||
}else if(id == R.id.more){
|
||||
if(lastFragment == moreFragment){
|
||||
Intent intent = new Intent(context, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
}else{
|
||||
this.setTitle(getString(R.string.more));
|
||||
}
|
||||
replaceFragment(moreFragment);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
getWindow().getDecorView().setOnApplyWindowInsetsListener((view, windowInsets) -> {
|
||||
WindowInsetsCompat windowInsetsCompat = WindowInsetsCompat.toWindowInsetsCompat(windowInsets, view);
|
||||
boolean isImeVisible = windowInsetsCompat.isVisible(WindowInsetsCompat.Type.ime());
|
||||
binding.bottomNavigationView.setVisibility(isImeVisible ? View.GONE : View.VISIBLE);
|
||||
view.onApplyWindowInsets(windowInsets);
|
||||
return windowInsets;
|
||||
});
|
||||
|
||||
askPermissions();
|
||||
|
||||
Intent intent = getIntent();
|
||||
handleIntents(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
try {
|
||||
iDownloaderService.removeActivity(this);
|
||||
context.getApplicationContext().unbindService(serviceConnection);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
handleIntents(intent);
|
||||
}
|
||||
|
||||
public void handleIntents(Intent intent){
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
if(Intent.ACTION_SEND.equals(action) && type != null){
|
||||
Log.e(TAG, action);
|
||||
|
||||
homeFragment = new HomeFragment();
|
||||
downloadsFragment = new DownloadsFragment();
|
||||
moreFragment = new MoreFragment();
|
||||
if (type.equalsIgnoreCase("application/txt")){
|
||||
try{
|
||||
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
InputStream is = getContentResolver().openInputStream(uri);
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
Reader reader = new BufferedReader(new InputStreamReader
|
||||
(is, Charset.forName(StandardCharsets.UTF_8.name())));
|
||||
int c = 0;
|
||||
while ((c = reader.read()) != -1) {
|
||||
textBuilder.append((char) c);
|
||||
}
|
||||
List<String> l = Arrays.asList(textBuilder.toString().split("\n"));
|
||||
LinkedList<String> lines = new LinkedList<>(l);
|
||||
homeFragment.handleFileIntent(lines);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else{
|
||||
homeFragment.handleIntent(intent);
|
||||
}
|
||||
initFragments();
|
||||
}
|
||||
}
|
||||
|
||||
private void initFragments(){
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, downloadsFragment)
|
||||
.add(R.id.frame_layout, moreFragment)
|
||||
.hide(downloadsFragment)
|
||||
.hide(moreFragment)
|
||||
.commit();
|
||||
|
||||
lastFragment = homeFragment;
|
||||
|
||||
listeners = new ArrayList<>();
|
||||
listeners.add(homeFragment.listener);
|
||||
listeners.add(downloadsFragment.listener);
|
||||
}
|
||||
|
||||
private void replaceFragment(Fragment f){
|
||||
fm.beginTransaction().hide(lastFragment).show(f).commit();
|
||||
lastFragment = f;
|
||||
}
|
||||
|
||||
public void startDownloadService(ArrayList<Video> downloadQueue, IDownloaderListener awaitingListener){
|
||||
addQueueToDownloads(downloadQueue);
|
||||
if(isDownloadServiceRunning){
|
||||
iDownloaderService.updateQueue(downloadQueue);
|
||||
return;
|
||||
}
|
||||
if(!listeners.contains(awaitingListener)) listeners.add(awaitingListener);
|
||||
Intent serviceIntent = new Intent(context, DownloaderService.class);
|
||||
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue);
|
||||
context.getApplicationContext().startService(serviceIntent);
|
||||
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public void addQueueToDownloads(ArrayList<Video> downloadQueue) {
|
||||
try {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
if (!sharedPreferences.getBoolean("incognito", false)) {
|
||||
DBManager dbManager = new DBManager(context);
|
||||
for (int i = downloadQueue.size() - 1; i >= 0; i--){
|
||||
Video v = downloadQueue.get(i);
|
||||
v.setQueuedDownload(true);
|
||||
dbManager.addToHistory(v);
|
||||
}
|
||||
dbManager.close();
|
||||
downloadsFragment.setDownloading(true);
|
||||
downloadsFragment.initCards();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDownloadService(){
|
||||
if(!isDownloadServiceRunning) return;
|
||||
try {
|
||||
iDownloaderService.removeActivity(this);
|
||||
context.getApplicationContext().unbindService(serviceConnection);
|
||||
context.getApplicationContext().stopService(new Intent(context.getApplicationContext(), DownloaderService.class));
|
||||
}catch (Exception ignored){}
|
||||
isDownloadServiceRunning = false;
|
||||
}
|
||||
|
||||
public void cancelDownloadService(){
|
||||
if(!isDownloadServiceRunning) return;
|
||||
iDownloaderService.cancelDownload(true);
|
||||
stopDownloadService();
|
||||
}
|
||||
|
||||
public void removeItemFromDownloadQueue(Video video, String type){
|
||||
iDownloaderService.removeItemFromDownloadQueue(video, type);
|
||||
}
|
||||
|
||||
public boolean isDownloadServiceRunning() {
|
||||
ActivityManager.RunningServiceInfo service = getService(DownloaderService.class);
|
||||
if(service != null){
|
||||
if (service.foreground) {
|
||||
isDownloadServiceRunning = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void reconnectDownloadService(){
|
||||
ActivityManager.RunningServiceInfo service = getService(DownloaderService.class);
|
||||
if(service != null){
|
||||
Intent serviceIntent = new Intent(context.getApplicationContext(), DownloaderService.class);
|
||||
serviceIntent.putExtra("rebind", true);
|
||||
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
isDownloadServiceRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
private ActivityManager.RunningServiceInfo getService(Class className){
|
||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (className.getName().equals(service.service.getClassName())) {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkUpdate(){
|
||||
SharedPreferences preferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
if(preferences.getBoolean("update_app", false)){
|
||||
UpdateUtil updateUtil = new UpdateUtil(this);
|
||||
updateUtil.updateApp();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void askPermissions(){
|
||||
if(!checkFilePermission()){
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
Log.e(TAG, String.valueOf(grantResults[0]));
|
||||
for(int i = 0; i < permissions.length; i++){
|
||||
if(grantResults[i] == PackageManager.PERMISSION_DENIED){
|
||||
createPermissionRequestDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void exit(){
|
||||
this.finishAffinity();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private boolean checkFilePermission(){
|
||||
return ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private void createPermissionRequestDialog(){
|
||||
MaterialAlertDialogBuilder dialog = new MaterialAlertDialogBuilder(this);
|
||||
dialog.setTitle(getString(R.string.warning));
|
||||
dialog.setMessage(getString(R.string.request_permission_desc));
|
||||
dialog.setOnCancelListener(dialogInterface -> exit());
|
||||
dialog.setNegativeButton(getString(R.string.exit_app), (dialogInterface, i) -> exit());
|
||||
dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", getPackageName(), null));
|
||||
startActivity(intent);
|
||||
System.exit(0);
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
}
|
||||
363
app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
Normal file
363
app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
package com.deniscerri.ytdlnis
|
||||
|
||||
import android.Manifest
|
||||
import android.app.ActivityManager
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.Video
|
||||
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding
|
||||
import com.deniscerri.ytdlnis.page.DownloadsFragment
|
||||
import com.deniscerri.ytdlnis.page.HomeFragment
|
||||
import com.deniscerri.ytdlnis.page.MoreFragment
|
||||
import com.deniscerri.ytdlnis.page.settings.SettingsActivity
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||
import com.deniscerri.ytdlnis.util.UpdateUtil
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.io.Reader
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.*
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
lateinit var context: Context
|
||||
private lateinit var homeFragment: HomeFragment
|
||||
private lateinit var downloadsFragment: DownloadsFragment
|
||||
private lateinit var moreFragment: MoreFragment
|
||||
private lateinit var lastFragment: Fragment
|
||||
private lateinit var fm: FragmentManager
|
||||
private var isDownloadServiceRunning = false
|
||||
var downloaderService: DownloaderService? = null
|
||||
private lateinit var listeners: ArrayList<IDownloaderListener>
|
||||
private var iDownloaderService: IDownloaderService? = null
|
||||
|
||||
private val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
downloaderService = (service as LocalBinder).service
|
||||
iDownloaderService = service
|
||||
isDownloadServiceRunning = true
|
||||
try {
|
||||
iDownloaderService!!.addActivity(this@MainActivity, listeners)
|
||||
for (i in listeners.indices) {
|
||||
val listener = listeners[i]
|
||||
listener.onDownloadStart(iDownloaderService!!.downloadInfo)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(componentName: ComponentName) {
|
||||
downloaderService = null
|
||||
iDownloaderService = null
|
||||
isDownloadServiceRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
setContentView(binding.root)
|
||||
context = baseContext
|
||||
reconnectDownloadService()
|
||||
checkUpdate()
|
||||
fm = supportFragmentManager
|
||||
homeFragment = HomeFragment()
|
||||
downloadsFragment = DownloadsFragment()
|
||||
moreFragment = MoreFragment()
|
||||
initFragments()
|
||||
binding.bottomNavigationView.setOnItemSelectedListener { item: MenuItem ->
|
||||
when (item.itemId) {
|
||||
R.id.home -> {
|
||||
if (lastFragment === homeFragment) {
|
||||
homeFragment.scrollToTop()
|
||||
} else {
|
||||
this.setTitle(R.string.app_name)
|
||||
}
|
||||
replaceFragment(homeFragment)
|
||||
}
|
||||
R.id.downloads -> {
|
||||
if (lastFragment === downloadsFragment) {
|
||||
downloadsFragment.scrollToTop()
|
||||
} else {
|
||||
this.title = getString(R.string.downloads)
|
||||
}
|
||||
replaceFragment(downloadsFragment)
|
||||
}
|
||||
R.id.more -> {
|
||||
if (lastFragment === moreFragment) {
|
||||
val intent = Intent(context, SettingsActivity::class.java)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
this.title = getString(R.string.more)
|
||||
}
|
||||
replaceFragment(moreFragment)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
window.decorView.setOnApplyWindowInsetsListener { view: View, windowInsets: WindowInsets? ->
|
||||
val windowInsetsCompat = WindowInsetsCompat.toWindowInsetsCompat(
|
||||
windowInsets!!, view
|
||||
)
|
||||
val isImeVisible = windowInsetsCompat.isVisible(WindowInsetsCompat.Type.ime())
|
||||
binding.bottomNavigationView.visibility =
|
||||
if (isImeVisible) View.GONE else View.VISIBLE
|
||||
view.onApplyWindowInsets(windowInsets)
|
||||
windowInsets
|
||||
}
|
||||
askPermissions()
|
||||
val intent = intent
|
||||
handleIntents(intent)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
try {
|
||||
iDownloaderService!!.removeActivity(this)
|
||||
context.applicationContext.unbindService(serviceConnection)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntents(intent)
|
||||
}
|
||||
|
||||
private fun handleIntents(intent: Intent) {
|
||||
val action = intent.action
|
||||
val type = intent.type
|
||||
if (Intent.ACTION_SEND == action && type != null) {
|
||||
Log.e(TAG, action)
|
||||
homeFragment = HomeFragment()
|
||||
downloadsFragment = DownloadsFragment()
|
||||
moreFragment = MoreFragment()
|
||||
if (type.equals("application/txt", ignoreCase = true)) {
|
||||
try {
|
||||
val uri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
|
||||
val `is` = contentResolver.openInputStream(uri!!)
|
||||
val textBuilder = StringBuilder()
|
||||
val reader: Reader = BufferedReader(
|
||||
InputStreamReader(
|
||||
`is`, Charset.forName(
|
||||
StandardCharsets.UTF_8.name()
|
||||
)
|
||||
)
|
||||
)
|
||||
var c: Int
|
||||
while (reader.read().also { c = it } != -1) {
|
||||
textBuilder.append(c.toChar())
|
||||
}
|
||||
val l = listOf(*textBuilder.toString().split("\n").toTypedArray())
|
||||
val lines = LinkedList(l)
|
||||
homeFragment.handleFileIntent(lines)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
homeFragment.handleIntent(intent)
|
||||
}
|
||||
initFragments()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initFragments() {
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, downloadsFragment)
|
||||
.add(R.id.frame_layout, moreFragment)
|
||||
.hide(downloadsFragment)
|
||||
.hide(moreFragment)
|
||||
.commit()
|
||||
lastFragment = homeFragment
|
||||
listeners = ArrayList()
|
||||
listeners.add(homeFragment.listener)
|
||||
listeners.add(downloadsFragment.listener)
|
||||
}
|
||||
|
||||
private fun replaceFragment(f: Fragment) {
|
||||
fm.beginTransaction().hide(lastFragment).show(f).commit()
|
||||
lastFragment = f
|
||||
}
|
||||
|
||||
fun startDownloadService(
|
||||
downloadQueue: ArrayList<Video>,
|
||||
awaitingListener: IDownloaderListener
|
||||
) {
|
||||
addQueueToDownloads(downloadQueue)
|
||||
if (isDownloadServiceRunning) {
|
||||
iDownloaderService?.updateQueue(downloadQueue)
|
||||
return
|
||||
}
|
||||
if (!listeners.contains(awaitingListener)) listeners.add(awaitingListener)
|
||||
val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue)
|
||||
context.applicationContext.startService(serviceIntent)
|
||||
context.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||
}
|
||||
|
||||
private fun addQueueToDownloads(downloadQueue: ArrayList<Video>) {
|
||||
try {
|
||||
val sharedPreferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
if (!sharedPreferences.getBoolean("incognito", false)) {
|
||||
val databaseManager = DatabaseManager(context)
|
||||
for (i in downloadQueue.indices.reversed()) {
|
||||
val v = downloadQueue[i]
|
||||
v.isQueuedDownload = true
|
||||
databaseManager.addToHistory(v)
|
||||
}
|
||||
databaseManager.close()
|
||||
downloadsFragment.setDownloading(true)
|
||||
downloadsFragment.initCards()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun stopDownloadService() {
|
||||
if (!isDownloadServiceRunning) return
|
||||
try {
|
||||
iDownloaderService!!.removeActivity(this)
|
||||
context.applicationContext.unbindService(serviceConnection)
|
||||
context.applicationContext.stopService(
|
||||
Intent(
|
||||
context.applicationContext,
|
||||
DownloaderService::class.java
|
||||
)
|
||||
)
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
isDownloadServiceRunning = false
|
||||
}
|
||||
|
||||
fun cancelDownloadService() {
|
||||
if (!isDownloadServiceRunning) return
|
||||
iDownloaderService!!.cancelDownload(true)
|
||||
stopDownloadService()
|
||||
}
|
||||
|
||||
fun removeItemFromDownloadQueue(video: Video?, type: String?) {
|
||||
iDownloaderService!!.removeItemFromDownloadQueue(video, type)
|
||||
}
|
||||
|
||||
fun isDownloadServiceRunning(): Boolean {
|
||||
val service = getService(DownloaderService::class.java)
|
||||
if (service != null) {
|
||||
if (service.foreground) {
|
||||
isDownloadServiceRunning = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun reconnectDownloadService() {
|
||||
val service = getService(DownloaderService::class.java)
|
||||
if (service != null) {
|
||||
val serviceIntent = Intent(context.applicationContext, DownloaderService::class.java)
|
||||
serviceIntent.putExtra("rebind", true)
|
||||
context.applicationContext.bindService(
|
||||
serviceIntent,
|
||||
serviceConnection,
|
||||
BIND_AUTO_CREATE
|
||||
)
|
||||
isDownloadServiceRunning = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun getService(className: Class<*>): ActivityManager.RunningServiceInfo? {
|
||||
val manager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
|
||||
for (service in manager.getRunningServices(Int.MAX_VALUE)) {
|
||||
if (className.name == service.service.className) {
|
||||
return service
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun checkUpdate() {
|
||||
val preferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
if (preferences.getBoolean("update_app", false)) {
|
||||
val updateUtil = UpdateUtil(this)
|
||||
updateUtil.updateApp()
|
||||
}
|
||||
}
|
||||
|
||||
private fun askPermissions() {
|
||||
if (!checkFilePermission()) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
Log.e(TAG, grantResults[0].toString())
|
||||
for (i in permissions.indices) {
|
||||
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
|
||||
createPermissionRequestDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exit() {
|
||||
finishAffinity()
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
private fun checkFilePermission(): Boolean {
|
||||
return (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED)
|
||||
}
|
||||
|
||||
private fun createPermissionRequestDialog() {
|
||||
val dialog = MaterialAlertDialogBuilder(this)
|
||||
dialog.setTitle(getString(R.string.warning))
|
||||
dialog.setMessage(getString(R.string.request_permission_desc))
|
||||
dialog.setOnCancelListener { exit() }
|
||||
dialog.setNegativeButton(getString(R.string.exit_app)) { _: DialogInterface?, _: Int -> exit() }
|
||||
dialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
val intent = Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.fromParts("package", packageName, null)
|
||||
)
|
||||
startActivity(intent)
|
||||
exitProcess(0)
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MainActivity"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.deniscerri.ytdlnis.database
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.deniscerri.ytdlnis.database.dao.HistoryDao
|
||||
import com.deniscerri.ytdlnis.database.dao.ResultDao
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
|
||||
@Database(
|
||||
entities = [ResultItem::class, HistoryItem::class],
|
||||
version = 7,
|
||||
autoMigrations = []
|
||||
)
|
||||
abstract class DBManager : RoomDatabase(){
|
||||
abstract val resultDao : ResultDao
|
||||
abstract val historyDao : HistoryDao
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance : DBManager? = null
|
||||
|
||||
fun getInstance(context: Context) : DBManager {
|
||||
if (instance == null){
|
||||
synchronized(this){
|
||||
instance = buildDatabase(context)
|
||||
}
|
||||
}
|
||||
return instance!!
|
||||
}
|
||||
|
||||
private fun buildDatabase(context: Context) : DBManager {
|
||||
return Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
DBManager::class.java, "ytdlnis_db"
|
||||
)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,9 +6,6 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
|
|
@ -16,7 +13,7 @@ import com.deniscerri.ytdlnis.R;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DBManager extends SQLiteOpenHelper {
|
||||
public class DatabaseManager extends SQLiteOpenHelper {
|
||||
Context context;
|
||||
|
||||
public static final String db_name = "ytdlnis_db";
|
||||
|
|
@ -42,7 +39,7 @@ public class DBManager extends SQLiteOpenHelper {
|
|||
public static final String playlistTitle = "playlistTitle";
|
||||
public static final String isQueuedDownload = "isQueuedDownload";
|
||||
|
||||
public DBManager(Context context){
|
||||
public DatabaseManager(Context context){
|
||||
super(context, db_name, null, db_version);
|
||||
this.context = context;
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.deniscerri.ytdlnis.database.dao
|
||||
|
||||
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) : List<HistoryItem>
|
||||
|
||||
@Query("SELECT * FROM history WHERE url=:url AND type=:type LIMIT 1")
|
||||
suspend fun getHistoryItemByURLAndType(url: String, type: String) : HistoryItem
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun addToHistory(results: ArrayList<HistoryItem>)
|
||||
|
||||
@Query("DELETE FROM history")
|
||||
suspend fun clearHistory()
|
||||
|
||||
@Query("DELETE FROM history where id=:id")
|
||||
suspend fun deleteItem(id: Int)
|
||||
|
||||
@Transaction
|
||||
suspend fun clearDeletedHistory(){
|
||||
val fileUtil = FileUtil()
|
||||
val items : List<HistoryItem> = getHistory("","","","")
|
||||
items.forEach { item ->
|
||||
if (!fileUtil.exists(item.downloadPath)){
|
||||
clearHistoryItem(item, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transaction
|
||||
suspend fun clearDownloadingHistory(){
|
||||
val items : List<HistoryItem> = getHistory("","","","")
|
||||
items.forEach { item ->
|
||||
if (item.isQueuedDownload == 1){
|
||||
clearHistoryItem(item, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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 clearDuplicates()
|
||||
|
||||
@Query("UPDATE results SET downloadedAudio=0, downloadedVideo=0 WHERE downloadedAudio=1 OR downloadedVideo=1")
|
||||
suspend fun removeAllDownloadStatusesFromResults()
|
||||
|
||||
@Query("UPDATE results SET downloadedAudio=0 WHERE downloadedAudio=1 AND url=:url")
|
||||
suspend fun removeAudioDownloadStatusFromOneResult(url: String)
|
||||
|
||||
@Query("UPDATE results SET downloadedVideo=0 WHERE downloadedVideo=1 AND url=:url")
|
||||
suspend fun removeVideoDownloadStatusFromOneResult(url: String)
|
||||
|
||||
@Transaction
|
||||
suspend fun clearDuplicateHistory(){
|
||||
clearDuplicates()
|
||||
removeAllDownloadStatusesFromResults()
|
||||
}
|
||||
|
||||
|
||||
@Transaction
|
||||
suspend fun clearHistoryItem(video: HistoryItem, delete_file : Boolean){
|
||||
if (delete_file){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.deleteFile(video.downloadPath)
|
||||
}
|
||||
deleteItem(video.id)
|
||||
when(video.type){
|
||||
"audio" -> removeAudioDownloadStatusFromOneResult(video.url)
|
||||
"video" -> removeVideoDownloadStatusFromOneResult(video.url)
|
||||
}
|
||||
}
|
||||
|
||||
@Update
|
||||
suspend fun updateHistoryItem(item: HistoryItem)
|
||||
|
||||
@Transaction
|
||||
suspend fun checkDownloaded(url: String, type: String) : Boolean {
|
||||
val historyItem = getHistoryItemByURLAndType(url, type)
|
||||
val fileUtil = FileUtil()
|
||||
return fileUtil.exists(historyItem.downloadPath)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.deniscerri.ytdlnis.database.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
|
||||
@Dao
|
||||
interface ResultDao {
|
||||
|
||||
@Query("SELECT * FROM results")
|
||||
suspend fun getResults() : List<ResultItem>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun addToResults(results: ArrayList<ResultItem>)
|
||||
|
||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun updateResult(item: ResultItem)
|
||||
|
||||
@Query("DELETE FROM results")
|
||||
suspend fun clearResults()
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
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 videoId: String,
|
||||
val url: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
val duration: String,
|
||||
val thumb: String,
|
||||
val downloadedAudio: Int,
|
||||
val downloadedVideo: Int,
|
||||
val isPlaylistItem: Int,
|
||||
val website: String,
|
||||
val downloadingAudio: Int,
|
||||
val downloadingVideo: Int,
|
||||
val playlistTitle: String
|
||||
)
|
||||
|
|
@ -29,7 +29,7 @@ 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.DBManager;
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
||||
|
|
@ -56,7 +56,7 @@ import java.util.Locale;
|
|||
public class DownloadsFragment extends Fragment implements DownloadsRecyclerViewAdapter.OnItemClickListener, View.OnClickListener, View.OnLongClickListener{
|
||||
private boolean downloading = false;
|
||||
private View fragmentView;
|
||||
private DBManager dbManager;
|
||||
private DatabaseManager databaseManager;
|
||||
Context context;
|
||||
Activity activity;
|
||||
MainActivity mainActivity;
|
||||
|
|
@ -118,8 +118,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
String type = info.getDownloadType();
|
||||
Video v = findVideo(url, type);
|
||||
Log.e(TAG, v.toString());
|
||||
dbManager = new DBManager(context);
|
||||
dbManager.clearHistoryItem(v, false);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
databaseManager.clearHistoryItem(v, false);
|
||||
int position = downloadsObjects.indexOf(v);
|
||||
downloadsObjects.remove(v);
|
||||
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
|
||||
|
|
@ -174,13 +174,13 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
try {
|
||||
item.setDownloadedTime(downloadedTime);
|
||||
item.setDownloadPath(downloadPath);
|
||||
item.setQueuedDownload(false);
|
||||
dbManager.updateHistoryItem(item);
|
||||
dbManager.close();
|
||||
databaseManager.updateHistoryItem(item);
|
||||
databaseManager.close();
|
||||
downloadsRecyclerViewAdapter.notifyItemChanged(downloadsObjects.indexOf(item));
|
||||
} catch (Exception ignored) {}
|
||||
downloading = false;
|
||||
|
|
@ -193,9 +193,9 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
v = findVideo(v.getURL(), v.getDownloadedType());
|
||||
try {
|
||||
downloadsObjects.remove(v);
|
||||
dbManager = new DBManager(context);
|
||||
dbManager.clearHistoryItem(v,false);
|
||||
dbManager.close();
|
||||
databaseManager = new DatabaseManager(context);
|
||||
databaseManager.clearHistoryItem(v,false);
|
||||
databaseManager.close();
|
||||
downloadsRecyclerViewAdapter.notifyItemRemoved(downloadsObjects.indexOf(v));
|
||||
|
||||
if (downloadsObjects.isEmpty()) initCards();
|
||||
|
|
@ -206,9 +206,9 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
@Override
|
||||
public void onDownloadCancelAll(DownloadInfo downloadInfo){
|
||||
try {
|
||||
dbManager = new DBManager(context);
|
||||
dbManager.clearDownloadingHistory();
|
||||
dbManager.close();
|
||||
databaseManager = new DatabaseManager(context);
|
||||
databaseManager.clearDownloadingHistory();
|
||||
databaseManager.close();
|
||||
initCards();
|
||||
downloading = false;
|
||||
}catch (Exception e){
|
||||
|
|
@ -283,11 +283,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
downloadsRecyclerViewAdapter.clear();
|
||||
no_results.setVisibility(View.GONE);
|
||||
selectionChips.setVisibility(View.VISIBLE);
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
try{
|
||||
Thread thread = new Thread(() -> {
|
||||
if (!downloading) dbManager.clearDownloadingHistory();
|
||||
downloadsObjects = dbManager.getHistory("", format,website,sort);
|
||||
if (!downloading) databaseManager.clearDownloadingHistory();
|
||||
downloadsObjects = databaseManager.getHistory("", format,website,sort);
|
||||
uiHandler.post(() -> {
|
||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||
shimmerCards.stopShimmer();
|
||||
|
|
@ -302,7 +302,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
websiteGroup.removeAllViews();
|
||||
});
|
||||
}
|
||||
dbManager.close();
|
||||
databaseManager.close();
|
||||
});
|
||||
thread.start();
|
||||
}catch(Exception e){
|
||||
|
|
@ -336,14 +336,14 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
searchView.setQueryHint(getString(R.string.search_history_hint));
|
||||
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
searchQuery = query;
|
||||
topAppBar.getMenu().findItem(R.id.search_downloads).collapseActionView();
|
||||
downloadsObjects = dbManager.getHistory(query, format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(query, format,website,sort);
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
searchQuery = newText;
|
||||
downloadsObjects = dbManager.getHistory(newText, format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(newText, format,website,sort);
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||
|
||||
|
|
@ -391,7 +391,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
dialogInterface.cancel();
|
||||
});
|
||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
dbManager.clearHistory();
|
||||
databaseManager.clearHistory();
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
downloadsObjects.clear();
|
||||
no_results.setVisibility(View.VISIBLE);
|
||||
|
|
@ -412,7 +412,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
dialogInterface.cancel();
|
||||
});
|
||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
dbManager.clearDeletedHistory();
|
||||
databaseManager.clearDeletedHistory();
|
||||
initCards();
|
||||
});
|
||||
delete_dialog.show();
|
||||
|
|
@ -429,7 +429,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
dialogInterface.cancel();
|
||||
});
|
||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
dbManager.clearDuplicateHistory();
|
||||
databaseManager.clearDuplicateHistory();
|
||||
initCards();
|
||||
});
|
||||
delete_dialog.show();
|
||||
|
|
@ -446,7 +446,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
dialogInterface.cancel();
|
||||
});
|
||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||
dbManager.clearDownloadingHistory();
|
||||
databaseManager.clearDownloadingHistory();
|
||||
mainActivity.cancelDownloadService();
|
||||
initCards();
|
||||
});
|
||||
|
|
@ -470,7 +470,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
|
||||
newest.setOnClickListener(view1 -> {
|
||||
sort = "DESC";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery, format,website,sort);
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||
sortSheet.cancel();
|
||||
|
|
@ -478,7 +478,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
|
||||
oldest.setOnClickListener(view1 -> {
|
||||
sort = "ASC";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery, format,website,sort);
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||
sortSheet.cancel();
|
||||
|
|
@ -501,11 +501,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
if (recyclerView.getVisibility() == View.GONE){
|
||||
|
||||
}
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
audio.setChecked(true);
|
||||
}else {
|
||||
format = "";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
audio.setChecked(false);
|
||||
}
|
||||
|
||||
|
|
@ -517,11 +517,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
video.setOnClickListener(view -> {
|
||||
if (video.isChecked()) {
|
||||
format = "video";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
video.setChecked(true);
|
||||
}else {
|
||||
format = "";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
video.setChecked(false);
|
||||
}
|
||||
|
||||
|
|
@ -545,11 +545,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
tmp.setOnClickListener(view -> {
|
||||
if (tmp.isChecked()){
|
||||
website = (String) tmp.getText();
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
websiteGroup.check(view.getId());
|
||||
}else{
|
||||
website = "";
|
||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
||||
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||
websiteGroup.clearCheck();
|
||||
}
|
||||
downloadsRecyclerViewAdapter.clear();
|
||||
|
|
@ -586,7 +586,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
private void removeSelectedItems(){
|
||||
if(bottomSheet != null) bottomSheet.hide();
|
||||
final boolean[] delete_file = {false};
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
|
||||
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
||||
delete_dialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items));
|
||||
|
|
@ -600,10 +600,10 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
int position = downloadsObjects.indexOf(v);
|
||||
downloadsObjects.remove(v);
|
||||
downloadsRecyclerViewAdapter.remove(position);
|
||||
dbManager.clearHistoryItem(v, delete_file[0]);
|
||||
databaseManager.clearHistoryItem(v, delete_file[0]);
|
||||
}
|
||||
updateWebsiteChips();
|
||||
dbManager.close();
|
||||
databaseManager.close();
|
||||
selectedObjects = new ArrayList<>();
|
||||
downloadsRecyclerViewAdapter.clearCheckedVideos();
|
||||
deleteFab.setVisibility(View.GONE);
|
||||
|
|
@ -622,7 +622,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
private void removedownloadsItem(int position){
|
||||
if(bottomSheet != null) bottomSheet.hide();
|
||||
final boolean[] delete_file = {false};
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
|
||||
Video v = downloadsObjects.get(position);
|
||||
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
||||
|
|
@ -635,8 +635,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
|||
downloadsObjects.remove(position);
|
||||
downloadsRecyclerViewAdapter.remove(position);
|
||||
updateWebsiteChips();
|
||||
dbManager.clearHistoryItem(v, delete_file[0]);
|
||||
dbManager.close();
|
||||
databaseManager.clearHistoryItem(v, delete_file[0]);
|
||||
databaseManager.close();
|
||||
|
||||
if(downloadsObjects.size() == 0){
|
||||
uiHandler.post(() -> {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
|
@ -36,7 +35,7 @@ import com.deniscerri.ytdlnis.MainActivity;
|
|||
import com.deniscerri.ytdlnis.R;
|
||||
import com.deniscerri.ytdlnis.adapter.HomeRecyclerViewAdapter;
|
||||
import com.deniscerri.ytdlnis.util.InfoUtil;
|
||||
import com.deniscerri.ytdlnis.database.DBManager;
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
||||
|
|
@ -50,9 +49,7 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
|
|||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.regex.Matcher;
|
||||
|
|
@ -84,7 +81,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
|
||||
private ArrayList<Video> resultObjects;
|
||||
public ArrayList<Video> selectedObjects;
|
||||
private DBManager dbManager;
|
||||
private DatabaseManager databaseManager;
|
||||
private InfoUtil infoUtil;
|
||||
private ArrayList<Video> downloadQueue;
|
||||
MainActivity mainActivity;
|
||||
|
|
@ -257,9 +254,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
download_all_fab.setOnClickListener(this);
|
||||
|
||||
if (inputQueries != null) {
|
||||
dbManager = new DBManager(context);
|
||||
dbManager.clearResults();
|
||||
dbManager.close();
|
||||
databaseManager = new DatabaseManager(context);
|
||||
databaseManager.clearResults();
|
||||
databaseManager.close();
|
||||
inputQueriesLength = inputQueries.size();
|
||||
homeRecyclerViewAdapter.clear();
|
||||
|
||||
|
|
@ -277,10 +274,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
if ((resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) || inputQueriesLength > 1) {
|
||||
downloadAllFab.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dbManager = new DBManager(context);
|
||||
dbManager.clearResults();
|
||||
databaseManager = new DatabaseManager(context);
|
||||
databaseManager.clearResults();
|
||||
for (Video v : resultObjects) v.setIsPlaylistItem(1);
|
||||
dbManager.addToResults(resultObjects);
|
||||
databaseManager.addToResults(resultObjects);
|
||||
});
|
||||
}catch (Exception ignored){}
|
||||
});
|
||||
|
|
@ -298,8 +295,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
try {
|
||||
Thread thread = new Thread(() -> {
|
||||
dbManager = new DBManager(context);
|
||||
resultObjects = dbManager.getResults();
|
||||
databaseManager = new DatabaseManager(context);
|
||||
resultObjects = databaseManager.getResults();
|
||||
Log.e(TAG, resultObjects.toString());
|
||||
String playlistTitle = "";
|
||||
try {
|
||||
|
|
@ -307,14 +304,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}catch(Exception ignored){}
|
||||
if (resultObjects.size() == 0 || (playlistTitle.equals(getString(R.string.trendingPlaylist)) && !downloading)) {
|
||||
try {
|
||||
dbManager.clearResults();
|
||||
databaseManager.clearResults();
|
||||
uiHandler.post(() -> {
|
||||
shimmerCards.startShimmer();
|
||||
shimmerCards.setVisibility(View.VISIBLE);
|
||||
});
|
||||
infoUtil = new InfoUtil(context);
|
||||
resultObjects = infoUtil.getTrending(context);
|
||||
dbManager.addToResults(resultObjects);
|
||||
databaseManager.addToResults(resultObjects);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
|
@ -337,7 +334,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
shimmerCards.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
dbManager.close();
|
||||
databaseManager.close();
|
||||
if (resultObjects != null) {
|
||||
uiHandler.post(this::scrollToTop);
|
||||
if (resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) {
|
||||
|
|
@ -383,7 +380,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
searchView.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
|
||||
searchView.setQueryHint(getString(R.string.search_hint));
|
||||
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
infoUtil = new InfoUtil(context);
|
||||
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
|
|
@ -437,8 +434,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
|
||||
int itemId = m.getItemId();
|
||||
if(itemId == R.id.delete_results){
|
||||
dbManager.clearResults();
|
||||
dbManager.close();
|
||||
databaseManager.clearResults();
|
||||
databaseManager.close();
|
||||
selectedObjects = new ArrayList<>();
|
||||
downloadAllFab.setVisibility(View.GONE);
|
||||
downloadFabs.setVisibility(View.GONE);
|
||||
|
|
@ -477,7 +474,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}
|
||||
|
||||
private void parseQuery(boolean resetResults) {
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
infoUtil = new InfoUtil(context);
|
||||
new Handler(Looper.getMainLooper()).post(this::scrollToTop);
|
||||
|
||||
|
|
@ -504,8 +501,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
ArrayList<Video> res = infoUtil.search(inputQuery);
|
||||
resultObjects.addAll(res);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (resetResults) dbManager.clearResults();
|
||||
dbManager.addToResults(resultObjects);
|
||||
if (resetResults) databaseManager.clearResults();
|
||||
databaseManager.addToResults(resultObjects);
|
||||
homeRecyclerViewAdapter.add(res);
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
|
|
@ -539,8 +536,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
res.add(v);
|
||||
resultObjects.add(v);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (resetResults) dbManager.clearResults();
|
||||
dbManager.addToResults(resultObjects);
|
||||
if (resetResults) databaseManager.clearResults();
|
||||
databaseManager.addToResults(resultObjects);
|
||||
homeRecyclerViewAdapter.add(res);
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
|
|
@ -557,7 +554,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
case "Playlist": {
|
||||
inputQuery = inputQuery.split("list=")[1];
|
||||
String nextPageToken = "";
|
||||
if (resetResults) dbManager.clearResults();
|
||||
if (resetResults) databaseManager.clearResults();
|
||||
if (resetResults){
|
||||
resultObjects.clear();
|
||||
homeRecyclerViewAdapter.clear();
|
||||
|
|
@ -568,7 +565,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
String tmp_token = tmp.getNextPageToken();
|
||||
resultObjects.addAll(tmp_vids);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
dbManager.addToResults(tmp_vids);
|
||||
databaseManager.addToResults(tmp_vids);
|
||||
homeRecyclerViewAdapter.add(tmp_vids);
|
||||
shimmerCards.stopShimmer();
|
||||
shimmerCards.setVisibility(View.GONE);
|
||||
|
|
@ -586,9 +583,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
if (video != null) {
|
||||
resultObjects.addAll(video);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (resetResults) dbManager.clearResults();
|
||||
if (resetResults) databaseManager.clearResults();
|
||||
homeRecyclerViewAdapter.add(video);
|
||||
dbManager.addToResults(resultObjects);
|
||||
databaseManager.addToResults(resultObjects);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -607,7 +604,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
dbManager.close();
|
||||
databaseManager.close();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -666,10 +663,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
|
||||
public void updateDownloadStatusOnResult(Video v, String type, boolean downloaded) {
|
||||
if (v != null) {
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
try {
|
||||
dbManager.updateDownloadStatusOnResult(v.getVideoId(), type, downloaded);
|
||||
dbManager.close();
|
||||
databaseManager.updateDownloadStatusOnResult(v.getVideoId(), type, downloaded);
|
||||
databaseManager.close();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
|
@ -680,10 +677,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
if (type.equals("audio")) v.setDownloadingAudio(isDownloading);
|
||||
else if (type.equals("video")) v.setDownloadingVideo(isDownloading);
|
||||
homeRecyclerViewAdapter.updateVideoListItem(v, resultObjects.indexOf(v));
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
try {
|
||||
dbManager.updateDownloadingStatusOnResult(v.getVideoId(), type, isDownloading);
|
||||
dbManager.close();
|
||||
databaseManager.updateDownloadingStatusOnResult(v.getVideoId(), type, isDownloading);
|
||||
databaseManager.close();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package com.deniscerri.ytdlnis.util;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.work.ForegroundInfo;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import com.deniscerri.ytdlnis.MainActivity;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import kotlin.random.Random;
|
||||
|
||||
public class DownloadWorker extends Worker {
|
||||
private Context context;
|
||||
private WorkerParameters workerParams;
|
||||
public DownloadWorker(
|
||||
@NonNull Context appContext,
|
||||
@NonNull WorkerParameters workerParams) {
|
||||
super(appContext, workerParams);
|
||||
this.context = appContext;
|
||||
this.workerParams = workerParams;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
//TODO
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
18
app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt
Normal file
18
app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package com.deniscerri.ytdlnis.util
|
||||
|
||||
import java.io.File
|
||||
|
||||
class FileUtil {
|
||||
fun deleteFile(path: String){
|
||||
val file = File(path)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
|
||||
fun exists(path: String) : Boolean {
|
||||
val file = File(path)
|
||||
if (path.isEmpty()) return false
|
||||
return file.exists()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,15 +3,11 @@ package com.deniscerri.ytdlnis.util;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
import com.deniscerri.ytdlnis.database.DBManager;
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager;
|
||||
import com.deniscerri.ytdlnis.database.Video;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest;
|
||||
|
|
@ -33,13 +29,13 @@ public class InfoUtil {
|
|||
private ArrayList<Video> videos;
|
||||
private String key;
|
||||
private boolean useInvidous;
|
||||
private DBManager dbManager;
|
||||
private DatabaseManager databaseManager;
|
||||
|
||||
public InfoUtil(Context context) {
|
||||
try{
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
key = sharedPreferences.getString("api_key", "");
|
||||
dbManager = new DBManager(context);
|
||||
databaseManager = new DatabaseManager(context);
|
||||
Thread thread = new Thread(() -> {
|
||||
//get Locale
|
||||
JSONObject country = genericRequest("https://ipwho.is/");
|
||||
|
|
@ -254,8 +250,8 @@ public class InfoUtil {
|
|||
String thumb = obj.getString("thumb");
|
||||
|
||||
String url = "https://www.youtube.com/watch?v=" + id;
|
||||
int downloadedAudio = dbManager.checkDownloaded(url, "audio");
|
||||
int downloadedVideo = dbManager.checkDownloaded(url, "video");
|
||||
int downloadedAudio = databaseManager.checkDownloaded(url, "audio");
|
||||
int downloadedVideo = databaseManager.checkDownloaded(url, "video");
|
||||
int isPlaylist = 0;
|
||||
|
||||
video = new Video(id, url, title, author, duration, thumb, downloadedAudio, downloadedVideo, isPlaylist, "youtube", 0, 0, "");
|
||||
|
|
@ -279,8 +275,8 @@ public class InfoUtil {
|
|||
|
||||
|
||||
String url = "https://www.youtube.com/watch?v=" + id;
|
||||
int downloadedAudio = dbManager.checkDownloaded(url, "audio");
|
||||
int downloadedVideo = dbManager.checkDownloaded(url, "video");
|
||||
int downloadedAudio = databaseManager.checkDownloaded(url, "audio");
|
||||
int downloadedVideo = databaseManager.checkDownloaded(url, "video");
|
||||
int isPlaylist = 0;
|
||||
|
||||
video = new Video(id, url, title, author, duration, thumb, downloadedAudio, downloadedVideo, isPlaylist, "youtube", 0, 0, "");
|
||||
|
|
@ -514,8 +510,8 @@ public class InfoUtil {
|
|||
author,
|
||||
duration,
|
||||
thumb,
|
||||
dbManager.checkDownloaded(url, "audio"),
|
||||
dbManager.checkDownloaded(url, "video"),
|
||||
databaseManager.checkDownloaded(url, "audio"),
|
||||
databaseManager.checkDownloaded(url, "video"),
|
||||
isPlaylist,
|
||||
website,
|
||||
0,
|
||||
|
|
|
|||
71
build.gradle
71
build.gradle
|
|
@ -1,53 +1,44 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
|
||||
buildscript {
|
||||
|
||||
|
||||
def versionMajor = 1
|
||||
def versionMinor = 4
|
||||
def versionPatch = 6
|
||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||
|
||||
ext {
|
||||
versionCode = versionMajor * 100000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
|
||||
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||
// dependency versions
|
||||
appCompatVer = '1.5.1'
|
||||
junitVer = '4.13.2'
|
||||
androidJunitVer = '1.1.1'
|
||||
espressoVer = '3.2.0'
|
||||
jacksonVer = '2.9.8'
|
||||
// supports java 1.6
|
||||
commonsIoVer = '2.5'
|
||||
// supports java 1.6
|
||||
commonsCompressVer = '1.12'
|
||||
youtubedlAndroidVer = "master-SNAPSHOT"
|
||||
workVer = "2.7.1"
|
||||
composeVer = "1.3.2"
|
||||
kotlinVer = "1.7.20"
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
def versionMajor = 1
|
||||
def versionMinor = 4
|
||||
def versionPatch = 6
|
||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||
|
||||
ext {
|
||||
versionCode = versionMajor * 100000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
|
||||
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||
// dependency versions
|
||||
appCompatVer = '1.1.0'
|
||||
junitVer = '4.12'
|
||||
androidJunitVer = '1.1.1'
|
||||
espressoVer = '3.2.0'
|
||||
jacksonVer = '2.9.8'
|
||||
// supports java 1.6
|
||||
commonsIoVer = '2.5'
|
||||
// supports java 1.6
|
||||
commonsCompressVer = '1.12'
|
||||
youtubedlAndroidVer = "master-SNAPSHOT"
|
||||
workVer = "2.7.1"
|
||||
plugins {
|
||||
id 'com.android.application' version '7.3.1' apply false
|
||||
id 'com.android.library' version '7.3.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = 'com.github.deniscerri'
|
||||
version = versionName
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
}
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
#Wed Dec 07 20:51:43 CET 2022
|
||||
#Tue Jan 03 22:34:47 CET 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
|
|
@ -1 +1,20 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
rootProject.name = "YTDLnis"
|
||||
|
||||
include ':common', ':app', ':library', ':ffmpeg'
|
||||
|
|
|
|||
Loading…
Reference in a new issue