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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="1.8" />
|
<bytecodeTargetLevel target="11" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -167,7 +167,7 @@
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</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" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
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()
|
def properties = new Properties()
|
||||||
|
|
@ -20,7 +20,7 @@ android {
|
||||||
keyPassword properties["signingConfig.keyPassword"]
|
keyPassword properties["signingConfig.keyPassword"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileSdkVersion 31
|
compileSdkVersion 33
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.deniscerri.ytdl"
|
applicationId "com.deniscerri.ytdl"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
|
|
@ -32,8 +32,22 @@ android {
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
||||||
}
|
}
|
||||||
|
vectorDrawables {
|
||||||
|
useSupportLibrary true
|
||||||
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
arguments {
|
||||||
|
arg("room.schemaLocation", "$projectDir/schemas")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
|
|
@ -53,6 +67,9 @@ android {
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
splits {
|
splits {
|
||||||
abi {
|
abi {
|
||||||
|
|
@ -62,9 +79,9 @@ android {
|
||||||
universalApk true
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
composeOptions {
|
||||||
|
kotlinCompilerExtensionVersion composeVer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,13 +97,14 @@ dependencies {
|
||||||
|
|
||||||
implementation "androidx.appcompat:appcompat:$appCompatVer"
|
implementation "androidx.appcompat:appcompat:$appCompatVer"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
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.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.recyclerview:recyclerview:1.2.1'
|
||||||
implementation 'androidx.preference:preference:1.2.0'
|
implementation 'androidx.preference:preference:1.2.0'
|
||||||
implementation 'androidx.navigation:navigation-fragment:2.5.2'
|
implementation 'androidx.navigation:navigation-fragment:2.5.3'
|
||||||
implementation 'androidx.navigation:navigation-ui:2.5.2'
|
implementation 'androidx.navigation:navigation-ui:2.5.3'
|
||||||
|
implementation 'androidx.core:core-ktx:1.9.0'
|
||||||
testImplementation "junit:junit:$junitVer"
|
testImplementation "junit:junit:$junitVer"
|
||||||
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer"
|
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer"
|
||||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer"
|
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer"
|
||||||
|
|
@ -102,4 +120,14 @@ dependencies {
|
||||||
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime:$workVer"
|
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() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
DynamicColors.applyToActivitiesIfAvailable(this);
|
DynamicColors.applyToActivitiesIfAvailable(this);
|
||||||
|
|
||||||
notificationUtil = new NotificationUtil(this);
|
notificationUtil = new NotificationUtil(this);
|
||||||
createNotificationChannels();
|
createNotificationChannels();
|
||||||
|
|
||||||
PreferenceManager.setDefaultValues(this, "root_preferences", this.MODE_PRIVATE, R.xml.root_preferences, false);
|
PreferenceManager.setDefaultValues(this, "root_preferences", this.MODE_PRIVATE, R.xml.root_preferences, false);
|
||||||
configureRxJavaErrorHandler();
|
configureRxJavaErrorHandler();
|
||||||
Completable.fromAction(this::initLibraries).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new DisposableCompletableObserver() {
|
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.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.graphics.ColorMatrix;
|
|
||||||
import android.graphics.ColorMatrixColorFilter;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.R;
|
import com.deniscerri.ytdlnis.R;
|
||||||
|
|
@ -16,7 +13,7 @@ import com.deniscerri.ytdlnis.R;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class DBManager extends SQLiteOpenHelper {
|
public class DatabaseManager extends SQLiteOpenHelper {
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
public static final String db_name = "ytdlnis_db";
|
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 playlistTitle = "playlistTitle";
|
||||||
public static final String isQueuedDownload = "isQueuedDownload";
|
public static final String isQueuedDownload = "isQueuedDownload";
|
||||||
|
|
||||||
public DBManager(Context context){
|
public DatabaseManager(Context context){
|
||||||
super(context, db_name, null, db_version);
|
super(context, db_name, null, db_version);
|
||||||
this.context = context;
|
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.MainActivity;
|
||||||
import com.deniscerri.ytdlnis.R;
|
import com.deniscerri.ytdlnis.R;
|
||||||
import com.deniscerri.ytdlnis.adapter.DownloadsRecyclerViewAdapter;
|
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.database.Video;
|
||||||
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
||||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
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{
|
public class DownloadsFragment extends Fragment implements DownloadsRecyclerViewAdapter.OnItemClickListener, View.OnClickListener, View.OnLongClickListener{
|
||||||
private boolean downloading = false;
|
private boolean downloading = false;
|
||||||
private View fragmentView;
|
private View fragmentView;
|
||||||
private DBManager dbManager;
|
private DatabaseManager databaseManager;
|
||||||
Context context;
|
Context context;
|
||||||
Activity activity;
|
Activity activity;
|
||||||
MainActivity mainActivity;
|
MainActivity mainActivity;
|
||||||
|
|
@ -118,8 +118,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
String type = info.getDownloadType();
|
String type = info.getDownloadType();
|
||||||
Video v = findVideo(url, type);
|
Video v = findVideo(url, type);
|
||||||
Log.e(TAG, v.toString());
|
Log.e(TAG, v.toString());
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
dbManager.clearHistoryItem(v, false);
|
databaseManager.clearHistoryItem(v, false);
|
||||||
int position = downloadsObjects.indexOf(v);
|
int position = downloadsObjects.indexOf(v);
|
||||||
downloadsObjects.remove(v);
|
downloadsObjects.remove(v);
|
||||||
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
|
downloadsRecyclerViewAdapter.notifyItemRemoved(position);
|
||||||
|
|
@ -174,13 +174,13 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
try {
|
try {
|
||||||
item.setDownloadedTime(downloadedTime);
|
item.setDownloadedTime(downloadedTime);
|
||||||
item.setDownloadPath(downloadPath);
|
item.setDownloadPath(downloadPath);
|
||||||
item.setQueuedDownload(false);
|
item.setQueuedDownload(false);
|
||||||
dbManager.updateHistoryItem(item);
|
databaseManager.updateHistoryItem(item);
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
downloadsRecyclerViewAdapter.notifyItemChanged(downloadsObjects.indexOf(item));
|
downloadsRecyclerViewAdapter.notifyItemChanged(downloadsObjects.indexOf(item));
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
downloading = false;
|
downloading = false;
|
||||||
|
|
@ -193,9 +193,9 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
v = findVideo(v.getURL(), v.getDownloadedType());
|
v = findVideo(v.getURL(), v.getDownloadedType());
|
||||||
try {
|
try {
|
||||||
downloadsObjects.remove(v);
|
downloadsObjects.remove(v);
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
dbManager.clearHistoryItem(v,false);
|
databaseManager.clearHistoryItem(v,false);
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
downloadsRecyclerViewAdapter.notifyItemRemoved(downloadsObjects.indexOf(v));
|
downloadsRecyclerViewAdapter.notifyItemRemoved(downloadsObjects.indexOf(v));
|
||||||
|
|
||||||
if (downloadsObjects.isEmpty()) initCards();
|
if (downloadsObjects.isEmpty()) initCards();
|
||||||
|
|
@ -206,9 +206,9 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadCancelAll(DownloadInfo downloadInfo){
|
public void onDownloadCancelAll(DownloadInfo downloadInfo){
|
||||||
try {
|
try {
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
dbManager.clearDownloadingHistory();
|
databaseManager.clearDownloadingHistory();
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
initCards();
|
initCards();
|
||||||
downloading = false;
|
downloading = false;
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
|
|
@ -283,11 +283,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
no_results.setVisibility(View.GONE);
|
no_results.setVisibility(View.GONE);
|
||||||
selectionChips.setVisibility(View.VISIBLE);
|
selectionChips.setVisibility(View.VISIBLE);
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
try{
|
try{
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
if (!downloading) dbManager.clearDownloadingHistory();
|
if (!downloading) databaseManager.clearDownloadingHistory();
|
||||||
downloadsObjects = dbManager.getHistory("", format,website,sort);
|
downloadsObjects = databaseManager.getHistory("", format,website,sort);
|
||||||
uiHandler.post(() -> {
|
uiHandler.post(() -> {
|
||||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||||
shimmerCards.stopShimmer();
|
shimmerCards.stopShimmer();
|
||||||
|
|
@ -302,7 +302,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
websiteGroup.removeAllViews();
|
websiteGroup.removeAllViews();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
|
@ -336,14 +336,14 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
|
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
searchView.setQueryHint(getString(R.string.search_history_hint));
|
searchView.setQueryHint(getString(R.string.search_history_hint));
|
||||||
|
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
|
|
||||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextSubmit(String query) {
|
public boolean onQueryTextSubmit(String query) {
|
||||||
searchQuery = query;
|
searchQuery = query;
|
||||||
topAppBar.getMenu().findItem(R.id.search_downloads).collapseActionView();
|
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.clear();
|
||||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||||
|
|
||||||
|
|
@ -358,7 +358,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextChange(String newText) {
|
public boolean onQueryTextChange(String newText) {
|
||||||
searchQuery = newText;
|
searchQuery = newText;
|
||||||
downloadsObjects = dbManager.getHistory(newText, format,website,sort);
|
downloadsObjects = databaseManager.getHistory(newText, format,website,sort);
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||||
|
|
||||||
|
|
@ -391,7 +391,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
dialogInterface.cancel();
|
dialogInterface.cancel();
|
||||||
});
|
});
|
||||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||||
dbManager.clearHistory();
|
databaseManager.clearHistory();
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
downloadsObjects.clear();
|
downloadsObjects.clear();
|
||||||
no_results.setVisibility(View.VISIBLE);
|
no_results.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -412,7 +412,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
dialogInterface.cancel();
|
dialogInterface.cancel();
|
||||||
});
|
});
|
||||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||||
dbManager.clearDeletedHistory();
|
databaseManager.clearDeletedHistory();
|
||||||
initCards();
|
initCards();
|
||||||
});
|
});
|
||||||
delete_dialog.show();
|
delete_dialog.show();
|
||||||
|
|
@ -429,7 +429,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
dialogInterface.cancel();
|
dialogInterface.cancel();
|
||||||
});
|
});
|
||||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||||
dbManager.clearDuplicateHistory();
|
databaseManager.clearDuplicateHistory();
|
||||||
initCards();
|
initCards();
|
||||||
});
|
});
|
||||||
delete_dialog.show();
|
delete_dialog.show();
|
||||||
|
|
@ -446,7 +446,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
dialogInterface.cancel();
|
dialogInterface.cancel();
|
||||||
});
|
});
|
||||||
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
delete_dialog.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
|
||||||
dbManager.clearDownloadingHistory();
|
databaseManager.clearDownloadingHistory();
|
||||||
mainActivity.cancelDownloadService();
|
mainActivity.cancelDownloadService();
|
||||||
initCards();
|
initCards();
|
||||||
});
|
});
|
||||||
|
|
@ -470,7 +470,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
|
|
||||||
newest.setOnClickListener(view1 -> {
|
newest.setOnClickListener(view1 -> {
|
||||||
sort = "DESC";
|
sort = "DESC";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery, format,website,sort);
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||||
sortSheet.cancel();
|
sortSheet.cancel();
|
||||||
|
|
@ -478,7 +478,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
|
|
||||||
oldest.setOnClickListener(view1 -> {
|
oldest.setOnClickListener(view1 -> {
|
||||||
sort = "ASC";
|
sort = "ASC";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery, format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery, format,website,sort);
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
downloadsRecyclerViewAdapter.add(downloadsObjects);
|
||||||
sortSheet.cancel();
|
sortSheet.cancel();
|
||||||
|
|
@ -501,11 +501,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
if (recyclerView.getVisibility() == View.GONE){
|
if (recyclerView.getVisibility() == View.GONE){
|
||||||
|
|
||||||
}
|
}
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
audio.setChecked(true);
|
audio.setChecked(true);
|
||||||
}else {
|
}else {
|
||||||
format = "";
|
format = "";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
audio.setChecked(false);
|
audio.setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -517,11 +517,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
video.setOnClickListener(view -> {
|
video.setOnClickListener(view -> {
|
||||||
if (video.isChecked()) {
|
if (video.isChecked()) {
|
||||||
format = "video";
|
format = "video";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
video.setChecked(true);
|
video.setChecked(true);
|
||||||
}else {
|
}else {
|
||||||
format = "";
|
format = "";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
video.setChecked(false);
|
video.setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -545,11 +545,11 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
tmp.setOnClickListener(view -> {
|
tmp.setOnClickListener(view -> {
|
||||||
if (tmp.isChecked()){
|
if (tmp.isChecked()){
|
||||||
website = (String) tmp.getText();
|
website = (String) tmp.getText();
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
websiteGroup.check(view.getId());
|
websiteGroup.check(view.getId());
|
||||||
}else{
|
}else{
|
||||||
website = "";
|
website = "";
|
||||||
downloadsObjects = dbManager.getHistory(searchQuery,format,website,sort);
|
downloadsObjects = databaseManager.getHistory(searchQuery,format,website,sort);
|
||||||
websiteGroup.clearCheck();
|
websiteGroup.clearCheck();
|
||||||
}
|
}
|
||||||
downloadsRecyclerViewAdapter.clear();
|
downloadsRecyclerViewAdapter.clear();
|
||||||
|
|
@ -586,7 +586,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
private void removeSelectedItems(){
|
private void removeSelectedItems(){
|
||||||
if(bottomSheet != null) bottomSheet.hide();
|
if(bottomSheet != null) bottomSheet.hide();
|
||||||
final boolean[] delete_file = {false};
|
final boolean[] delete_file = {false};
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
|
|
||||||
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
||||||
delete_dialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items));
|
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);
|
int position = downloadsObjects.indexOf(v);
|
||||||
downloadsObjects.remove(v);
|
downloadsObjects.remove(v);
|
||||||
downloadsRecyclerViewAdapter.remove(position);
|
downloadsRecyclerViewAdapter.remove(position);
|
||||||
dbManager.clearHistoryItem(v, delete_file[0]);
|
databaseManager.clearHistoryItem(v, delete_file[0]);
|
||||||
}
|
}
|
||||||
updateWebsiteChips();
|
updateWebsiteChips();
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
selectedObjects = new ArrayList<>();
|
selectedObjects = new ArrayList<>();
|
||||||
downloadsRecyclerViewAdapter.clearCheckedVideos();
|
downloadsRecyclerViewAdapter.clearCheckedVideos();
|
||||||
deleteFab.setVisibility(View.GONE);
|
deleteFab.setVisibility(View.GONE);
|
||||||
|
|
@ -622,7 +622,7 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
private void removedownloadsItem(int position){
|
private void removedownloadsItem(int position){
|
||||||
if(bottomSheet != null) bottomSheet.hide();
|
if(bottomSheet != null) bottomSheet.hide();
|
||||||
final boolean[] delete_file = {false};
|
final boolean[] delete_file = {false};
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
|
|
||||||
Video v = downloadsObjects.get(position);
|
Video v = downloadsObjects.get(position);
|
||||||
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
MaterialAlertDialogBuilder delete_dialog = new MaterialAlertDialogBuilder(fragmentContext);
|
||||||
|
|
@ -635,8 +635,8 @@ public class DownloadsFragment extends Fragment implements DownloadsRecyclerView
|
||||||
downloadsObjects.remove(position);
|
downloadsObjects.remove(position);
|
||||||
downloadsRecyclerViewAdapter.remove(position);
|
downloadsRecyclerViewAdapter.remove(position);
|
||||||
updateWebsiteChips();
|
updateWebsiteChips();
|
||||||
dbManager.clearHistoryItem(v, delete_file[0]);
|
databaseManager.clearHistoryItem(v, delete_file[0]);
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
|
|
||||||
if(downloadsObjects.size() == 0){
|
if(downloadsObjects.size() == 0){
|
||||||
uiHandler.post(() -> {
|
uiHandler.post(() -> {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
@ -36,7 +35,7 @@ import com.deniscerri.ytdlnis.MainActivity;
|
||||||
import com.deniscerri.ytdlnis.R;
|
import com.deniscerri.ytdlnis.R;
|
||||||
import com.deniscerri.ytdlnis.adapter.HomeRecyclerViewAdapter;
|
import com.deniscerri.ytdlnis.adapter.HomeRecyclerViewAdapter;
|
||||||
import com.deniscerri.ytdlnis.util.InfoUtil;
|
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.database.Video;
|
||||||
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
||||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
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.floatingactionbutton.FloatingActionButton;
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
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.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
@ -84,7 +81,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
|
|
||||||
private ArrayList<Video> resultObjects;
|
private ArrayList<Video> resultObjects;
|
||||||
public ArrayList<Video> selectedObjects;
|
public ArrayList<Video> selectedObjects;
|
||||||
private DBManager dbManager;
|
private DatabaseManager databaseManager;
|
||||||
private InfoUtil infoUtil;
|
private InfoUtil infoUtil;
|
||||||
private ArrayList<Video> downloadQueue;
|
private ArrayList<Video> downloadQueue;
|
||||||
MainActivity mainActivity;
|
MainActivity mainActivity;
|
||||||
|
|
@ -257,9 +254,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
download_all_fab.setOnClickListener(this);
|
download_all_fab.setOnClickListener(this);
|
||||||
|
|
||||||
if (inputQueries != null) {
|
if (inputQueries != null) {
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
dbManager.clearResults();
|
databaseManager.clearResults();
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
inputQueriesLength = inputQueries.size();
|
inputQueriesLength = inputQueries.size();
|
||||||
homeRecyclerViewAdapter.clear();
|
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) {
|
if ((resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) || inputQueriesLength > 1) {
|
||||||
downloadAllFab.setVisibility(View.VISIBLE);
|
downloadAllFab.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
dbManager.clearResults();
|
databaseManager.clearResults();
|
||||||
for (Video v : resultObjects) v.setIsPlaylistItem(1);
|
for (Video v : resultObjects) v.setIsPlaylistItem(1);
|
||||||
dbManager.addToResults(resultObjects);
|
databaseManager.addToResults(resultObjects);
|
||||||
});
|
});
|
||||||
}catch (Exception ignored){}
|
}catch (Exception ignored){}
|
||||||
});
|
});
|
||||||
|
|
@ -298,8 +295,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
Handler uiHandler = new Handler(Looper.getMainLooper());
|
Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||||
try {
|
try {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
resultObjects = dbManager.getResults();
|
resultObjects = databaseManager.getResults();
|
||||||
Log.e(TAG, resultObjects.toString());
|
Log.e(TAG, resultObjects.toString());
|
||||||
String playlistTitle = "";
|
String playlistTitle = "";
|
||||||
try {
|
try {
|
||||||
|
|
@ -307,14 +304,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
}catch(Exception ignored){}
|
}catch(Exception ignored){}
|
||||||
if (resultObjects.size() == 0 || (playlistTitle.equals(getString(R.string.trendingPlaylist)) && !downloading)) {
|
if (resultObjects.size() == 0 || (playlistTitle.equals(getString(R.string.trendingPlaylist)) && !downloading)) {
|
||||||
try {
|
try {
|
||||||
dbManager.clearResults();
|
databaseManager.clearResults();
|
||||||
uiHandler.post(() -> {
|
uiHandler.post(() -> {
|
||||||
shimmerCards.startShimmer();
|
shimmerCards.startShimmer();
|
||||||
shimmerCards.setVisibility(View.VISIBLE);
|
shimmerCards.setVisibility(View.VISIBLE);
|
||||||
});
|
});
|
||||||
infoUtil = new InfoUtil(context);
|
infoUtil = new InfoUtil(context);
|
||||||
resultObjects = infoUtil.getTrending(context);
|
resultObjects = infoUtil.getTrending(context);
|
||||||
dbManager.addToResults(resultObjects);
|
databaseManager.addToResults(resultObjects);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString());
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +334,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
shimmerCards.setVisibility(View.GONE);
|
shimmerCards.setVisibility(View.GONE);
|
||||||
});
|
});
|
||||||
|
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
if (resultObjects != null) {
|
if (resultObjects != null) {
|
||||||
uiHandler.post(this::scrollToTop);
|
uiHandler.post(this::scrollToTop);
|
||||||
if (resultObjects.size() > 1 && resultObjects.get(1).getIsPlaylistItem() == 1) {
|
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.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
|
||||||
searchView.setQueryHint(getString(R.string.search_hint));
|
searchView.setQueryHint(getString(R.string.search_hint));
|
||||||
|
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
infoUtil = new InfoUtil(context);
|
infoUtil = new InfoUtil(context);
|
||||||
|
|
||||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
|
|
@ -437,8 +434,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
|
topAppBar.setOnMenuItemClickListener((MenuItem m) -> {
|
||||||
int itemId = m.getItemId();
|
int itemId = m.getItemId();
|
||||||
if(itemId == R.id.delete_results){
|
if(itemId == R.id.delete_results){
|
||||||
dbManager.clearResults();
|
databaseManager.clearResults();
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
selectedObjects = new ArrayList<>();
|
selectedObjects = new ArrayList<>();
|
||||||
downloadAllFab.setVisibility(View.GONE);
|
downloadAllFab.setVisibility(View.GONE);
|
||||||
downloadFabs.setVisibility(View.GONE);
|
downloadFabs.setVisibility(View.GONE);
|
||||||
|
|
@ -477,7 +474,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseQuery(boolean resetResults) {
|
private void parseQuery(boolean resetResults) {
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
infoUtil = new InfoUtil(context);
|
infoUtil = new InfoUtil(context);
|
||||||
new Handler(Looper.getMainLooper()).post(this::scrollToTop);
|
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);
|
ArrayList<Video> res = infoUtil.search(inputQuery);
|
||||||
resultObjects.addAll(res);
|
resultObjects.addAll(res);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> {
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
if (resetResults) dbManager.clearResults();
|
if (resetResults) databaseManager.clearResults();
|
||||||
dbManager.addToResults(resultObjects);
|
databaseManager.addToResults(resultObjects);
|
||||||
homeRecyclerViewAdapter.add(res);
|
homeRecyclerViewAdapter.add(res);
|
||||||
shimmerCards.stopShimmer();
|
shimmerCards.stopShimmer();
|
||||||
shimmerCards.setVisibility(View.GONE);
|
shimmerCards.setVisibility(View.GONE);
|
||||||
|
|
@ -539,8 +536,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
res.add(v);
|
res.add(v);
|
||||||
resultObjects.add(v);
|
resultObjects.add(v);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> {
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
if (resetResults) dbManager.clearResults();
|
if (resetResults) databaseManager.clearResults();
|
||||||
dbManager.addToResults(resultObjects);
|
databaseManager.addToResults(resultObjects);
|
||||||
homeRecyclerViewAdapter.add(res);
|
homeRecyclerViewAdapter.add(res);
|
||||||
shimmerCards.stopShimmer();
|
shimmerCards.stopShimmer();
|
||||||
shimmerCards.setVisibility(View.GONE);
|
shimmerCards.setVisibility(View.GONE);
|
||||||
|
|
@ -557,7 +554,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
case "Playlist": {
|
case "Playlist": {
|
||||||
inputQuery = inputQuery.split("list=")[1];
|
inputQuery = inputQuery.split("list=")[1];
|
||||||
String nextPageToken = "";
|
String nextPageToken = "";
|
||||||
if (resetResults) dbManager.clearResults();
|
if (resetResults) databaseManager.clearResults();
|
||||||
if (resetResults){
|
if (resetResults){
|
||||||
resultObjects.clear();
|
resultObjects.clear();
|
||||||
homeRecyclerViewAdapter.clear();
|
homeRecyclerViewAdapter.clear();
|
||||||
|
|
@ -568,7 +565,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
String tmp_token = tmp.getNextPageToken();
|
String tmp_token = tmp.getNextPageToken();
|
||||||
resultObjects.addAll(tmp_vids);
|
resultObjects.addAll(tmp_vids);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> {
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
dbManager.addToResults(tmp_vids);
|
databaseManager.addToResults(tmp_vids);
|
||||||
homeRecyclerViewAdapter.add(tmp_vids);
|
homeRecyclerViewAdapter.add(tmp_vids);
|
||||||
shimmerCards.stopShimmer();
|
shimmerCards.stopShimmer();
|
||||||
shimmerCards.setVisibility(View.GONE);
|
shimmerCards.setVisibility(View.GONE);
|
||||||
|
|
@ -586,9 +583,9 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
if (video != null) {
|
if (video != null) {
|
||||||
resultObjects.addAll(video);
|
resultObjects.addAll(video);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> {
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
if (resetResults) dbManager.clearResults();
|
if (resetResults) databaseManager.clearResults();
|
||||||
homeRecyclerViewAdapter.add(video);
|
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());
|
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) {
|
public void updateDownloadStatusOnResult(Video v, String type, boolean downloaded) {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
try {
|
try {
|
||||||
dbManager.updateDownloadStatusOnResult(v.getVideoId(), type, downloaded);
|
databaseManager.updateDownloadStatusOnResult(v.getVideoId(), type, downloaded);
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -680,10 +677,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
||||||
if (type.equals("audio")) v.setDownloadingAudio(isDownloading);
|
if (type.equals("audio")) v.setDownloadingAudio(isDownloading);
|
||||||
else if (type.equals("video")) v.setDownloadingVideo(isDownloading);
|
else if (type.equals("video")) v.setDownloadingVideo(isDownloading);
|
||||||
homeRecyclerViewAdapter.updateVideoListItem(v, resultObjects.indexOf(v));
|
homeRecyclerViewAdapter.updateVideoListItem(v, resultObjects.indexOf(v));
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
try {
|
try {
|
||||||
dbManager.updateDownloadingStatusOnResult(v.getVideoId(), type, isDownloading);
|
databaseManager.updateDownloadingStatusOnResult(v.getVideoId(), type, isDownloading);
|
||||||
dbManager.close();
|
databaseManager.close();
|
||||||
} catch (Exception ignored) {}
|
} 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.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.deniscerri.ytdlnis.R;
|
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.deniscerri.ytdlnis.database.Video;
|
||||||
import com.yausername.youtubedl_android.YoutubeDL;
|
import com.yausername.youtubedl_android.YoutubeDL;
|
||||||
import com.yausername.youtubedl_android.YoutubeDLRequest;
|
import com.yausername.youtubedl_android.YoutubeDLRequest;
|
||||||
|
|
@ -33,13 +29,13 @@ public class InfoUtil {
|
||||||
private ArrayList<Video> videos;
|
private ArrayList<Video> videos;
|
||||||
private String key;
|
private String key;
|
||||||
private boolean useInvidous;
|
private boolean useInvidous;
|
||||||
private DBManager dbManager;
|
private DatabaseManager databaseManager;
|
||||||
|
|
||||||
public InfoUtil(Context context) {
|
public InfoUtil(Context context) {
|
||||||
try{
|
try{
|
||||||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||||
key = sharedPreferences.getString("api_key", "");
|
key = sharedPreferences.getString("api_key", "");
|
||||||
dbManager = new DBManager(context);
|
databaseManager = new DatabaseManager(context);
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
//get Locale
|
//get Locale
|
||||||
JSONObject country = genericRequest("https://ipwho.is/");
|
JSONObject country = genericRequest("https://ipwho.is/");
|
||||||
|
|
@ -254,8 +250,8 @@ public class InfoUtil {
|
||||||
String thumb = obj.getString("thumb");
|
String thumb = obj.getString("thumb");
|
||||||
|
|
||||||
String url = "https://www.youtube.com/watch?v=" + id;
|
String url = "https://www.youtube.com/watch?v=" + id;
|
||||||
int downloadedAudio = dbManager.checkDownloaded(url, "audio");
|
int downloadedAudio = databaseManager.checkDownloaded(url, "audio");
|
||||||
int downloadedVideo = dbManager.checkDownloaded(url, "video");
|
int downloadedVideo = databaseManager.checkDownloaded(url, "video");
|
||||||
int isPlaylist = 0;
|
int isPlaylist = 0;
|
||||||
|
|
||||||
video = new Video(id, url, title, author, duration, thumb, downloadedAudio, downloadedVideo, isPlaylist, "youtube", 0, 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;
|
String url = "https://www.youtube.com/watch?v=" + id;
|
||||||
int downloadedAudio = dbManager.checkDownloaded(url, "audio");
|
int downloadedAudio = databaseManager.checkDownloaded(url, "audio");
|
||||||
int downloadedVideo = dbManager.checkDownloaded(url, "video");
|
int downloadedVideo = databaseManager.checkDownloaded(url, "video");
|
||||||
int isPlaylist = 0;
|
int isPlaylist = 0;
|
||||||
|
|
||||||
video = new Video(id, url, title, author, duration, thumb, downloadedAudio, downloadedVideo, isPlaylist, "youtube", 0, 0, "");
|
video = new Video(id, url, title, author, duration, thumb, downloadedAudio, downloadedVideo, isPlaylist, "youtube", 0, 0, "");
|
||||||
|
|
@ -514,8 +510,8 @@ public class InfoUtil {
|
||||||
author,
|
author,
|
||||||
duration,
|
duration,
|
||||||
thumb,
|
thumb,
|
||||||
dbManager.checkDownloaded(url, "audio"),
|
databaseManager.checkDownloaded(url, "audio"),
|
||||||
dbManager.checkDownloaded(url, "video"),
|
databaseManager.checkDownloaded(url, "video"),
|
||||||
isPlaylist,
|
isPlaylist,
|
||||||
website,
|
website,
|
||||||
0,
|
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.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
|
||||||
buildscript {
|
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 {
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
google()
|
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
|
plugins {
|
||||||
def versionMinor = 4
|
id 'com.android.application' version '7.3.1' apply false
|
||||||
def versionPatch = 6
|
id 'com.android.library' version '7.3.1' apply false
|
||||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
|
||||||
group = 'com.github.deniscerri'
|
|
||||||
version = versionName
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
maven { url 'https://jitpack.io' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
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
|
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
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
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'
|
include ':common', ':app', ':library', ':ffmpeg'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue