turned more files to kotlin
This commit is contained in:
parent
92d6b2f197
commit
6dc413cbd2
28 changed files with 578 additions and 855 deletions
|
|
@ -320,7 +320,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material/icons/materialicons/history/baseline_history_24.xml" />
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/drag_handle/baseline_drag_handle_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="outputName" value="ic_history" />
|
||||
<entry key="outputName" value="ic_handle" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -1,351 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.database;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem;
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DatabaseManager extends SQLiteOpenHelper {
|
||||
Context context;
|
||||
|
||||
public static final String db_name = "ytdlnis_db";
|
||||
public static final int db_version = 7;
|
||||
public static final String results_table_name = "results";
|
||||
public static final String history_table_name = "history";
|
||||
public static final String id = "id";
|
||||
public static final String videoId = "videoId";
|
||||
public static final String url = "url";
|
||||
public static final String title = "title";
|
||||
public static final String author = "author";
|
||||
public static final String duration = "duration";
|
||||
public static final String thumb = "thumb";
|
||||
public static final String downloadedAudio = "downloadedAudio";
|
||||
public static final String downloadedVideo = "downloadedVideo";
|
||||
public static final String type = "type";
|
||||
public static final String time = "time";
|
||||
public static final String isPlaylistItem = "isPlaylistItem";
|
||||
public static final String website = "website";
|
||||
public static final String downloadPath = "downloadPath";
|
||||
public static final String downloadingAudio = "downloadingAudio";
|
||||
public static final String downloadingVideo = "downloadingVideo";
|
||||
public static final String playlistTitle = "playlistTitle";
|
||||
public static final String isQueuedDownload = "isQueuedDownload";
|
||||
|
||||
public DatabaseManager(Context context){
|
||||
super(context, db_name, null, db_version);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase sqLiteDatabase) {
|
||||
String query = "CREATE TABLE " + results_table_name + " ("
|
||||
+ id + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ videoId + " TEXT,"
|
||||
+ url + " TEXT,"
|
||||
+ title + " TEXT,"
|
||||
+ author + " TEXT,"
|
||||
+ duration + " TEXT,"
|
||||
+ thumb + " TEXT,"
|
||||
+ downloadedAudio + " INTEGER,"
|
||||
+ downloadedVideo + " INTEGER,"
|
||||
+ isPlaylistItem + " INTENGER,"
|
||||
+ website + " TEXT,"
|
||||
+ downloadingAudio + " INTEGER,"
|
||||
+ downloadingVideo + " INTEGER,"
|
||||
+ playlistTitle + " TEXT)";
|
||||
|
||||
sqLiteDatabase.execSQL(query);
|
||||
|
||||
query = "CREATE TABLE " + history_table_name + " ("
|
||||
+ id + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ url + " TEXT,"
|
||||
+ title + " TEXT,"
|
||||
+ author + " TEXT,"
|
||||
+ duration + " TEXT,"
|
||||
+ thumb + " TEXT,"
|
||||
+ type + " TEXT,"
|
||||
+ time + " TEXT,"
|
||||
+ downloadPath + " TEXT,"
|
||||
+ website + " TEXT,"
|
||||
+ isQueuedDownload + " INTEGER)";
|
||||
|
||||
sqLiteDatabase.execSQL(query);
|
||||
}
|
||||
|
||||
public void clearHistory(){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.execSQL("DELETE FROM " + history_table_name);
|
||||
|
||||
//remove downloaded statuses from results
|
||||
db.execSQL("UPDATE "+results_table_name+ " SET downloadedAudio=0, downloadedVideo=0" +
|
||||
" WHERE downloadedAudio=1 OR downloadedVideo=1");
|
||||
}
|
||||
|
||||
@SuppressLint("Range")
|
||||
public void clearHistoryItem(HistoryItem video, boolean delete_file){
|
||||
// SQLiteDatabase db = this.getWritableDatabase();
|
||||
//
|
||||
// if (delete_file){
|
||||
// try{
|
||||
// Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
||||
// video.getURL() + "' AND type='"+video.getDownloadedType() + "' LIMIT 1", null);
|
||||
//
|
||||
// if(cursor.moveToFirst()){
|
||||
// String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
||||
// File file = new File(path);
|
||||
// if(file.exists()){
|
||||
// file.delete();
|
||||
// }
|
||||
// }
|
||||
// }catch (Exception e){
|
||||
// Toast.makeText(context, R.string.error_deleting_file, Toast.LENGTH_SHORT).show();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// db.execSQL("DELETE FROM " + history_table_name + " WHERE id=" + video.getId());
|
||||
//
|
||||
// String where = "";
|
||||
// switch(video.getDownloadedType()){
|
||||
// case "audio":
|
||||
// where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
|
||||
// break;
|
||||
// case "video":
|
||||
// where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// //remove downloaded status from results
|
||||
// db.execSQL("UPDATE "+results_table_name+ where);
|
||||
}
|
||||
|
||||
public void clearDeletedHistory(){
|
||||
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||
// for (int i = 0; i < videos.size(); i++){
|
||||
// ResultItem video = videos.get(i);
|
||||
// String path = video.getDownloadPath();
|
||||
// File file = new File(path);
|
||||
// if(!file.exists() && !path.isEmpty()){
|
||||
// clearHistoryItem(video, false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void clearDownloadingHistory(){
|
||||
// ArrayList<ResultItem> videos = getHistory("","","","");
|
||||
// for (int i = 0; i < videos.size(); i++){
|
||||
// ResultItem video = videos.get(i);
|
||||
// if(video.isQueuedDownload()){
|
||||
// clearHistoryItem(video, false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void clearDuplicateHistory(){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.execSQL(
|
||||
"DELETE FROM " + history_table_name +
|
||||
" WHERE id > (SELECT MIN(h.id) FROM history h WHERE h.url = " + history_table_name + ".url" +
|
||||
" AND h.type = " + history_table_name + ".type);"
|
||||
);
|
||||
|
||||
//remove downloaded statuses from results
|
||||
db.execSQL("UPDATE "+results_table_name+ " SET downloadedAudio=0, downloadedVideo=0" +
|
||||
" WHERE downloadedAudio=1 OR downloadedVideo=1");
|
||||
}
|
||||
|
||||
public void clearResults(){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.execSQL("DELETE FROM " + results_table_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVer, int newVer) {
|
||||
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + results_table_name);
|
||||
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + history_table_name);
|
||||
onCreate(sqLiteDatabase);
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("Range")
|
||||
public ArrayList<ResultItem> getResults(){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + results_table_name, null);
|
||||
ArrayList<ResultItem> list = new ArrayList<>();
|
||||
|
||||
// if(cursor.moveToFirst()){
|
||||
// do {
|
||||
// // on below line we are adding the data from cursor to our array list.
|
||||
// list.add(new ResultItem(cursor.getString(cursor.getColumnIndex(videoId)),
|
||||
// cursor.getString(cursor.getColumnIndex(url)),
|
||||
// cursor.getString(cursor.getColumnIndex(title)),
|
||||
// cursor.getString(cursor.getColumnIndex(author)),
|
||||
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedVideo)),
|
||||
// cursor.getInt(cursor.getColumnIndex(isPlaylistItem)),
|
||||
// cursor.getString(cursor.getColumnIndex(website)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadedAudio)),
|
||||
// cursor.getInt(cursor.getColumnIndex(downloadingVideo)),
|
||||
// cursor.getString(cursor.getColumnIndex(playlistTitle))));
|
||||
// } while (cursor.moveToNext());
|
||||
// }
|
||||
//
|
||||
// cursor.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressLint("Range")
|
||||
public ArrayList<ResultItem> getHistory(String query, String format, String site, String sort){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
|
||||
if (sort == null || sort.isEmpty()) sort = "DESC";
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name
|
||||
+ " WHERE title LIKE '%"+query+"%'"+
|
||||
" AND type LIKE '%"+format+"%'"+
|
||||
" AND website LIKE '%"+site+"%'"+
|
||||
" ORDER BY id "+sort,
|
||||
null);
|
||||
ArrayList<ResultItem> list = new ArrayList<>();
|
||||
//
|
||||
// if(cursor.moveToFirst()){
|
||||
// do {
|
||||
// // on below line we are adding the data from cursor to our array list.
|
||||
// list.add(new ResultItem(cursor.getInt(cursor.getColumnIndex(id)),
|
||||
// cursor.getString(cursor.getColumnIndex(url)),
|
||||
// cursor.getString(cursor.getColumnIndex(title)),
|
||||
// cursor.getString(cursor.getColumnIndex(author)),
|
||||
// cursor.getString(cursor.getColumnIndex(duration)),
|
||||
// cursor.getString(cursor.getColumnIndex(thumb)),
|
||||
// cursor.getString(cursor.getColumnIndex(type)),
|
||||
// cursor.getString(cursor.getColumnIndex(time)),
|
||||
// cursor.getString(cursor.getColumnIndex(downloadPath)),
|
||||
// cursor.getString(cursor.getColumnIndex(website)),
|
||||
// cursor.getInt(cursor.getColumnIndex(isQueuedDownload))));
|
||||
// } while (cursor.moveToNext());
|
||||
// }
|
||||
//
|
||||
// cursor.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addToResults(ArrayList<ResultItem> videot){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
// for(ResultItem v : videot){
|
||||
// values.put(videoId, v.getVideoId());
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(downloadedAudio, v.isAudioDownloaded());
|
||||
// values.put(downloadedVideo, v.isVideoDownloaded());
|
||||
// values.put(isPlaylistItem, v.getIsPlaylistItem());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(downloadingAudio, 0);
|
||||
// values.put(downloadingVideo, 0);
|
||||
// values.put(playlistTitle, v.getPlaylistTitle());
|
||||
//
|
||||
// db.insert(results_table_name, null, values);
|
||||
// }
|
||||
//
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void addToHistory(ResultItem v){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
//
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(type, v.getDownloadedType());
|
||||
// values.put(time, v.getDownloadedTime());
|
||||
// values.put(downloadPath, v.getDownloadPath());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
//
|
||||
// db.insert(history_table_name, null, values);
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void updateHistoryItem(ResultItem v){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
// values.put(url, v.getURL());
|
||||
// values.put(title, v.getTitle());
|
||||
// values.put(author, v.getAuthor());
|
||||
// values.put(duration, v.getDuration());
|
||||
// values.put(thumb, v.getThumb());
|
||||
// values.put(type, v.getDownloadedType());
|
||||
// values.put(time, v.getDownloadedTime());
|
||||
// values.put(downloadPath, v.getDownloadPath());
|
||||
// values.put(website, v.getWebsite());
|
||||
// values.put(isQueuedDownload, (v.isQueuedDownload()) ? 1 : 0);
|
||||
//
|
||||
// String where = url + "='"+v.getURL()+"' AND "+isQueuedDownload+"=1 AND "+type+"='"+v.getDownloadedType()+"'";
|
||||
// db.update(history_table_name, values, where, null);
|
||||
// db.close();
|
||||
}
|
||||
|
||||
public void updateDownloadStatusOnResult(String id, String type, boolean downloaded){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
switch (type){
|
||||
case "audio":
|
||||
if (downloaded) values.put(downloadedAudio, 1);
|
||||
values.put(downloadingAudio, 0);
|
||||
break;
|
||||
case "video":
|
||||
if (downloaded) values.put(downloadedVideo, 1);
|
||||
values.put(downloadingVideo, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
db.update(results_table_name, values, "videoId = ?", new String[]{id});
|
||||
}
|
||||
|
||||
public void updateDownloadingStatusOnResult(String id, String type, boolean downloading){
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
type = (type.equals("audio")) ? downloadingAudio : downloadingVideo;
|
||||
int value = (downloading) ? 1 : 0;
|
||||
values.put(type, value);
|
||||
|
||||
db.update(results_table_name, values, "videoId = ?", new String[]{id});
|
||||
}
|
||||
|
||||
@SuppressLint("Range")
|
||||
public int checkDownloaded(String url, String downloadType){
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + history_table_name + " WHERE url='" +
|
||||
url + "' AND type='"+downloadType + "' LIMIT 1", null);
|
||||
|
||||
if(cursor.moveToFirst()){
|
||||
String path = cursor.getString(cursor.getColumnIndex(downloadPath));
|
||||
File file = new File(path);
|
||||
if(!file.exists() && !path.isEmpty()){
|
||||
return 0;
|
||||
}else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class DownloadInfo {
|
||||
private ResultItem video;
|
||||
private int progress;
|
||||
private LinkedList<ResultItem> downloadQueue;
|
||||
private String outputLine;
|
||||
private String downloadStatus;
|
||||
private String downloadPath;
|
||||
private String downloadType;
|
||||
|
||||
public DownloadInfo(){}
|
||||
|
||||
public ResultItem getVideo() {
|
||||
return video;
|
||||
}
|
||||
|
||||
public void setVideo(ResultItem video) {
|
||||
this.video = video;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public LinkedList<ResultItem> getDownloadQueue() {
|
||||
return downloadQueue;
|
||||
}
|
||||
|
||||
public void setDownloadQueue(LinkedList<ResultItem> downloadQueue) {
|
||||
this.downloadQueue = downloadQueue;
|
||||
this.video = downloadQueue.peek();
|
||||
}
|
||||
|
||||
public String getOutputLine() {
|
||||
return outputLine;
|
||||
}
|
||||
|
||||
public void setOutputLine(String outputLine) {
|
||||
this.outputLine = outputLine;
|
||||
}
|
||||
|
||||
public String getDownloadStatus(){
|
||||
return downloadStatus;
|
||||
}
|
||||
|
||||
public void setDownloadStatus(String status){
|
||||
downloadStatus = status;
|
||||
}
|
||||
|
||||
public String getDownloadPath(){
|
||||
return downloadPath;
|
||||
}
|
||||
|
||||
public void setDownloadPath(String path){
|
||||
this.downloadPath = path;
|
||||
}
|
||||
|
||||
public String getDownloadType() {
|
||||
return downloadType;
|
||||
}
|
||||
|
||||
public void setDownloadType(String downloadType) {
|
||||
this.downloadType = downloadType;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.deniscerri.ytdlnis.service
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import java.util.*
|
||||
|
||||
class DownloadInfo {
|
||||
var video: ResultItem? = null
|
||||
var progress = 0
|
||||
var downloadQueue: LinkedList<ResultItem>? = null
|
||||
private set
|
||||
var outputLine: String? = null
|
||||
var downloadStatus: String? = null
|
||||
var downloadPath: String? = null
|
||||
var downloadType: String? = null
|
||||
fun setDownloadQueue(downloadQueue: LinkedList<ResultItem>) {
|
||||
this.downloadQueue = downloadQueue
|
||||
video = downloadQueue.peek()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
public interface IDownloaderListener {
|
||||
void onDownloadStart(DownloadInfo downloadInfo);
|
||||
void onDownloadProgress(DownloadInfo downloadInfo);
|
||||
void onDownloadError(DownloadInfo downloadInfo);
|
||||
void onDownloadEnd(DownloadInfo downloadInfo);
|
||||
void onDownloadCancel(DownloadInfo downloadInfo);
|
||||
void onDownloadCancelAll(DownloadInfo downloadInfo);
|
||||
void onDownloadServiceEnd();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.deniscerri.ytdlnis.service
|
||||
|
||||
interface IDownloaderListener {
|
||||
fun onDownloadStart(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadProgress(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadError(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadEnd(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadCancel(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadCancelAll(downloadInfo: DownloadInfo?)
|
||||
fun onDownloadServiceEnd()
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.service;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface IDownloaderService {
|
||||
DownloadInfo getInfo();
|
||||
void addActivity(Activity activity, ArrayList<IDownloaderListener> callback);
|
||||
void removeActivity(Activity activity);
|
||||
void updateQueue(ArrayList<ResultItem> queue);
|
||||
void cancelDownload(boolean cancelAll);
|
||||
void removeItemFromDownloadQueue(ResultItem video, String type);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.deniscerri.ytdlnis.service
|
||||
|
||||
import android.app.Activity
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
|
||||
interface IDownloaderService {
|
||||
val info: DownloadInfo?
|
||||
fun addActivity(activity: Activity?, callback: ArrayList<IDownloaderListener?>?)
|
||||
fun removeActivity(activity: Activity?)
|
||||
fun updateQueue(queue: ArrayList<ResultItem?>?)
|
||||
fun cancelDownload(cancelAll: Boolean)
|
||||
fun removeItemFromDownloadQueue(video: ResultItem?, type: String?)
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.service.api
|
||||
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
|
||||
interface InvidiousService {
|
||||
@GET("video/{id}")
|
||||
suspend fun getVideo(
|
||||
@Path("id") id : String
|
||||
) : Call<ResultItem>
|
||||
|
||||
@GET("playlist/{id}")
|
||||
suspend fun getPlaylist(
|
||||
@Path("id") id: String
|
||||
) : Response<JsonObject>
|
||||
|
||||
@GET("trending?type=music®ion={regionCode}")
|
||||
suspend fun getTrending(
|
||||
@Path("regionCode") regionCode: String
|
||||
) : Response<JsonArray>
|
||||
|
||||
@GET("search/suggestions?q={query}")
|
||||
suspend fun getSearchSuggestions(
|
||||
@Path("query") query: String
|
||||
) : Response<JsonObject>
|
||||
|
||||
companion object {
|
||||
var invidiousService : InvidiousService? = null
|
||||
fun getInstance() : InvidiousService {
|
||||
return invidiousService ?: run {
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl("https://invidious.baczek.me/api/v1/")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
invidiousService = retrofit.create(InvidiousService::class.java)
|
||||
invidiousService!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.service.api
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
|
||||
interface YoutubeAPIService {
|
||||
@GET("videos?part=snippet,contentDetails&id={id}&key={apiKey}")
|
||||
suspend fun getVideo(
|
||||
@Path("id") id: String?
|
||||
) : Response<JsonObject>
|
||||
|
||||
@GET("playlistItems?part=snippet&pageToken={nextPageToken}&maxResults=50®ionCode={regionCode}&playlistId={playlistId}&key={apiKey}")
|
||||
suspend fun getPlaylist(
|
||||
@Path("nextPageToken") nextPageToken: String,
|
||||
@Path("playlistId") playlistId : String,
|
||||
@Path("apiKey") apiKey : String
|
||||
) : Response<JsonObject>
|
||||
|
||||
@GET("videos?part=snippet&chart=mostPopular&videoCategoryId=10®ionCode={regionCode}&maxResults=25&key={apiKey}")
|
||||
suspend fun getTrending(
|
||||
@Path("regionCode") regionCode: String,
|
||||
@Path("apiKey") apiKey : String
|
||||
) : Response<JsonArray>
|
||||
|
||||
@GET("videos?part=contentDetails&chart=mostPopular&videoCategoryId=10®ionCode={regionCode}&maxResults=25&key={apiKey}")
|
||||
suspend fun getTrendingExtra(
|
||||
@Path("regionCode") regionCode: String,
|
||||
@Path("apiKey") apiKey : String
|
||||
) : Response<JsonArray>
|
||||
|
||||
@GET("search?part=snippet&q={query}&maxResults=25®ionCode={regionCode}&key={apiKey}")
|
||||
suspend fun search(
|
||||
@Path("query") query: String,
|
||||
@Path("regionCode") regionCode: String,
|
||||
@Path("apiKey") apiKey: String
|
||||
) : Response<JsonObject>
|
||||
|
||||
@GET("videos?id={ids}&part=contentDetails®ionCode={regionCode}&key={apiKey}")
|
||||
suspend fun getExtraData(
|
||||
@Path("ids") ids: String,
|
||||
@Path("regionCode") regionCode: String,
|
||||
@Path("apiKey") apiKey: String
|
||||
) : Response<JsonObject>
|
||||
|
||||
companion object {
|
||||
var invidiousService : YoutubeAPIService? = null
|
||||
lateinit var apiKey : String
|
||||
lateinit var regionCode: String
|
||||
fun getInstance(key: String, regionCode: String) : YoutubeAPIService {
|
||||
apiKey = key
|
||||
return invidiousService ?: run {
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl("https://www.googleapis.com/youtube/v3/")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
invidiousService = retrofit.create(YoutubeAPIService::class.java)
|
||||
invidiousService!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
import com.deniscerri.ytdlnis.DownloaderService;
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener;
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService;
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CustomCommandActivity extends AppCompatActivity {
|
||||
private static final String TAG = "CustomCommandActivity";
|
||||
private MaterialToolbar topAppBar;
|
||||
private boolean isDownloadServiceRunning = false;
|
||||
public DownloaderService downloaderService;
|
||||
private TextView output;
|
||||
private EditText input;
|
||||
private ExtendedFloatingActionButton fab;
|
||||
private ExtendedFloatingActionButton cancelFab;
|
||||
private IDownloaderService iDownloaderService;
|
||||
private ScrollView scrollView;
|
||||
Context context;
|
||||
|
||||
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
downloaderService = ((DownloaderService.LocalBinder) service).getService();
|
||||
iDownloaderService = (IDownloaderService) service;
|
||||
isDownloadServiceRunning = true;
|
||||
try{
|
||||
ArrayList<IDownloaderListener> listeners = new ArrayList<>();
|
||||
listeners.add(listener);
|
||||
iDownloaderService.addActivity(CustomCommandActivity.this, listeners);
|
||||
listener.onDownloadStart(iDownloaderService.getInfo());
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
downloaderService = null;
|
||||
iDownloaderService = null;
|
||||
isDownloadServiceRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
public IDownloaderListener listener = new IDownloaderListener() {
|
||||
|
||||
public void onDownloadStart(DownloadInfo info) {
|
||||
input.setEnabled(false);
|
||||
output.setText("");
|
||||
swapFabs();
|
||||
}
|
||||
|
||||
public void onDownloadProgress(DownloadInfo info) {
|
||||
String newInfo = info.getOutputLine();
|
||||
if (newInfo.contains("[download]")){
|
||||
String temp = output.getText().toString();
|
||||
output.setText(
|
||||
temp.substring(0, temp.lastIndexOf(System.getProperty("line.separator")) - 2)
|
||||
);
|
||||
}
|
||||
output.append(info.getOutputLine() + " \n");
|
||||
output.scrollTo(0, output.getHeight());
|
||||
scrollView.fullScroll(View.FOCUS_DOWN);
|
||||
}
|
||||
|
||||
public void onDownloadError(DownloadInfo info) {
|
||||
output.append("\n" + info.getOutputLine());
|
||||
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
|
||||
input.setText("yt-dlp ");
|
||||
input.setEnabled(true);
|
||||
swapFabs();
|
||||
}
|
||||
|
||||
public void onDownloadEnd(DownloadInfo info) {
|
||||
output.append(info.getOutputLine());
|
||||
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
|
||||
// MEDIA SCAN
|
||||
MediaScannerConnection.scanFile(context, new String[]{"/storage"}, null, null);
|
||||
input.setText("yt-dlp ");
|
||||
input.setEnabled(true);
|
||||
swapFabs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadCancel(DownloadInfo downloadInfo) {}
|
||||
|
||||
@Override
|
||||
public void onDownloadCancelAll(DownloadInfo downloadInfo){}
|
||||
|
||||
public void onDownloadServiceEnd() {
|
||||
stopDownloadService();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_custom_command);
|
||||
|
||||
context = getBaseContext();
|
||||
scrollView = findViewById(R.id.custom_command_scrollview);
|
||||
topAppBar = findViewById(R.id.custom_command_toolbar);
|
||||
topAppBar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
output = findViewById(R.id.custom_command_output);
|
||||
output.setTextIsSelectable(true);
|
||||
|
||||
input = findViewById(R.id.command_edittext);
|
||||
input.requestFocus();
|
||||
|
||||
fab = findViewById(R.id.command_fab);
|
||||
fab.setOnClickListener(view -> {
|
||||
if (isStoragePermissionGranted()){
|
||||
startDownloadService(input.getText().toString(), NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID);
|
||||
}
|
||||
});
|
||||
|
||||
cancelFab = findViewById(R.id.cancel_command_fab);
|
||||
cancelFab.setOnClickListener(view -> {
|
||||
cancelDownloadService();
|
||||
swapFabs();
|
||||
input.setEnabled(true);
|
||||
});
|
||||
handleIntent(getIntent());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
handleIntent(intent);
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent){
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
Log.e(TAG, action + " " + type);
|
||||
if (action.equals(Intent.ACTION_SEND) && type != null) {
|
||||
Log.e(TAG, action);
|
||||
String txt = "yt-dlp " + intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
input.setText(txt);
|
||||
}
|
||||
}
|
||||
|
||||
private void swapFabs(){
|
||||
int cancel = cancelFab.getVisibility();
|
||||
int start = fab.getVisibility();
|
||||
cancelFab.setVisibility(start);
|
||||
fab.setVisibility(cancel);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
|
||||
public void startDownloadService(String command, int id){
|
||||
if(isDownloadServiceRunning) return;
|
||||
Intent serviceIntent = new Intent(context, DownloaderService.class);
|
||||
serviceIntent.putExtra("command", command);
|
||||
serviceIntent.putExtra("id", id);
|
||||
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public void stopDownloadService(){
|
||||
if(!isDownloadServiceRunning) return;
|
||||
iDownloaderService.removeActivity(this);
|
||||
context.getApplicationContext().unbindService(serviceConnection);
|
||||
downloaderService.stopForeground(true);
|
||||
downloaderService.stopSelf();
|
||||
isDownloadServiceRunning = false;
|
||||
}
|
||||
|
||||
public void cancelDownloadService(){
|
||||
if(!isDownloadServiceRunning) return;
|
||||
iDownloaderService.cancelDownload(false);
|
||||
stopDownloadService();
|
||||
}
|
||||
|
||||
public boolean isStoragePermissionGranted() {
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}else{
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
package com.deniscerri.ytdlnis.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager
|
||||
import android.media.MediaScannerConnection
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.deniscerri.ytdlnis.DownloaderService
|
||||
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
|
||||
class CustomCommandActivity : AppCompatActivity() {
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
private var isDownloadServiceRunning = false
|
||||
var downloaderService: DownloaderService? = null
|
||||
private var output: TextView? = null
|
||||
private var input: EditText? = null
|
||||
private var fab: ExtendedFloatingActionButton? = null
|
||||
private var cancelFab: ExtendedFloatingActionButton? = null
|
||||
private var iDownloaderService: IDownloaderService? = null
|
||||
private var scrollView: ScrollView? = null
|
||||
var context: Context? = null
|
||||
private val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
downloaderService = (service as LocalBinder).service
|
||||
iDownloaderService = service
|
||||
isDownloadServiceRunning = true
|
||||
try {
|
||||
val listeners = ArrayList<IDownloaderListener>()
|
||||
listeners.add(listener)
|
||||
iDownloaderService!!.addActivity(this@CustomCommandActivity, listeners)
|
||||
listener.onDownloadStart(iDownloaderService!!.info)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(componentName: ComponentName) {
|
||||
downloaderService = null
|
||||
iDownloaderService = null
|
||||
isDownloadServiceRunning = false
|
||||
}
|
||||
}
|
||||
var listener: IDownloaderListener = object : IDownloaderListener {
|
||||
override fun onDownloadStart(info: DownloadInfo) {
|
||||
input!!.isEnabled = false
|
||||
output!!.text = ""
|
||||
swapFabs()
|
||||
}
|
||||
|
||||
override fun onDownloadProgress(info: DownloadInfo) {
|
||||
val newInfo = info.outputLine
|
||||
if (newInfo.contains("[download]")) {
|
||||
val temp = output!!.text.toString()
|
||||
output!!.text =
|
||||
temp.substring(0, temp.lastIndexOf(System.getProperty("line.separator")!!) - 2)
|
||||
}
|
||||
output!!.append(
|
||||
"""${info.outputLine}
|
||||
"""
|
||||
)
|
||||
output!!.scrollTo(0, output!!.height)
|
||||
scrollView!!.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onDownloadError(info: DownloadInfo) {
|
||||
output!!.append(
|
||||
"""
|
||||
|
||||
${info.outputLine}
|
||||
""".trimIndent()
|
||||
)
|
||||
scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount)
|
||||
input!!.setText("yt-dlp ")
|
||||
input!!.isEnabled = true
|
||||
swapFabs()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onDownloadEnd(info: DownloadInfo) {
|
||||
output!!.append(info.outputLine)
|
||||
scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount)
|
||||
// MEDIA SCAN
|
||||
MediaScannerConnection.scanFile(context, arrayOf("/storage"), null, null)
|
||||
input!!.setText("yt-dlp ")
|
||||
input!!.isEnabled = true
|
||||
swapFabs()
|
||||
}
|
||||
|
||||
override fun onDownloadCancel(downloadInfo: DownloadInfo) {}
|
||||
override fun onDownloadCancelAll(downloadInfo: DownloadInfo) {}
|
||||
override fun onDownloadServiceEnd() {
|
||||
stopDownloadService()
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_custom_command)
|
||||
context = baseContext
|
||||
scrollView = findViewById(R.id.custom_command_scrollview)
|
||||
topAppBar = findViewById(R.id.custom_command_toolbar)
|
||||
topAppBar!!.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
|
||||
output = findViewById(R.id.custom_command_output)
|
||||
output!!.setTextIsSelectable(true)
|
||||
input = findViewById(R.id.command_edittext)
|
||||
input!!.requestFocus()
|
||||
fab = findViewById(R.id.command_fab)
|
||||
fab!!.setOnClickListener {
|
||||
if (isStoragePermissionGranted) {
|
||||
startDownloadService(
|
||||
input!!.text.toString(),
|
||||
NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID
|
||||
)
|
||||
}
|
||||
}
|
||||
cancelFab = findViewById(R.id.cancel_command_fab)
|
||||
cancelFab!!.setOnClickListener {
|
||||
cancelDownloadService()
|
||||
swapFabs()
|
||||
input!!.isEnabled = true
|
||||
}
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent) {
|
||||
val action = intent.action
|
||||
val type = intent.type
|
||||
Log.e(TAG, "$action $type")
|
||||
if (action == Intent.ACTION_SEND && type != null) {
|
||||
Log.e(TAG, action)
|
||||
val txt = "yt-dlp " + intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
input!!.setText(txt)
|
||||
}
|
||||
}
|
||||
|
||||
private fun swapFabs() {
|
||||
val cancel = cancelFab!!.visibility
|
||||
val start = fab!!.visibility
|
||||
cancelFab!!.visibility = start
|
||||
fab!!.visibility = cancel
|
||||
}
|
||||
|
||||
|
||||
private fun startDownloadService(command: String?, id: Int) {
|
||||
if (isDownloadServiceRunning) return
|
||||
val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||
serviceIntent.putExtra("command", command)
|
||||
serviceIntent.putExtra("id", id)
|
||||
context!!.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||
}
|
||||
|
||||
fun stopDownloadService() {
|
||||
if (!isDownloadServiceRunning) return
|
||||
iDownloaderService!!.removeActivity(this)
|
||||
context!!.applicationContext.unbindService(serviceConnection)
|
||||
downloaderService!!.stopForeground(true)
|
||||
downloaderService!!.stopSelf()
|
||||
isDownloadServiceRunning = false
|
||||
}
|
||||
|
||||
fun cancelDownloadService() {
|
||||
if (!isDownloadServiceRunning) return
|
||||
iDownloaderService!!.cancelDownload(false)
|
||||
stopDownloadService()
|
||||
}
|
||||
|
||||
private val isStoragePermissionGranted: Boolean
|
||||
get() = if (ActivityCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
== PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
true
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
1
|
||||
)
|
||||
false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CustomCommandActivity"
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.HistoryAdapter
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel
|
||||
|
|
@ -45,7 +44,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
|
||||
private var downloading = false
|
||||
private var fragmentView: View? = null
|
||||
private var databaseManager: DatabaseManager? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private var fragmentContext: Context? = null
|
||||
|
|
@ -165,7 +163,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
val searchView = topAppBar!!.menu.findItem(R.id.search_downloads).actionView as SearchView?
|
||||
searchView!!.inputType = InputType.TYPE_CLASS_TEXT
|
||||
searchView.queryHint = getString(R.string.search_history_hint)
|
||||
databaseManager = DatabaseManager(context)
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
topAppBar!!.menu.findItem(R.id.search_downloads).collapseActionView()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
|||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
|
@ -23,7 +22,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
|
|
@ -37,18 +35,13 @@ import com.deniscerri.ytdlnis.util.InfoUtil
|
|||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
|
||||
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickListener {
|
||||
private var progressBar: LinearProgressIndicator? = null
|
||||
|
|
@ -70,7 +63,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
|
||||
private var downloading = false
|
||||
private var fragmentView: View? = null
|
||||
private var databaseManager: DatabaseManager? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private var fragmentContext: Context? = null
|
||||
|
|
@ -239,7 +231,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
val searchView = topAppBar!!.menu.findItem(R.id.search).actionView as SearchView?
|
||||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_URI
|
||||
searchView.queryHint = getString(R.string.search_hint)
|
||||
databaseManager = DatabaseManager(context)
|
||||
infoUtil = InfoUtil(requireContext())
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
|
|
@ -390,7 +381,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
downloadViewModel.insertDownload(downloadItem).observe(viewLifecycleOwner) {
|
||||
downloadItem.id = it
|
||||
val bottomSheet = DownloadBottomSheetDialog(downloadItem)
|
||||
bottomSheet.show(parentFragmentManager, "bottomSheet")
|
||||
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
|
||||
public class MoreFragment extends PreferenceFragmentCompat {
|
||||
public static final String TAG = "MoreFragment";
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.more_preferences, rootKey);
|
||||
}
|
||||
}
|
||||
15
app/src/main/java/com/deniscerri/ytdlnis/ui/MoreFragment.kt
Normal file
15
app/src/main/java/com/deniscerri/ytdlnis/ui/MoreFragment.kt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package com.deniscerri.ytdlnis.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.deniscerri.ytdlnis.R
|
||||
|
||||
class MoreFragment : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.more_preferences, rootKey)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "MoreFragment"
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import android.content.DialogInterface
|
|||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.fragment.app.findFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
|
@ -13,6 +14,8 @@ import androidx.viewpager2.widget.ViewPager2
|
|||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
|
||||
|
|
@ -28,11 +31,18 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val behavior = BottomSheetBehavior.from(view.parent as View)
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
override fun setupDialog(dialog: Dialog, style: Int) {
|
||||
super.setupDialog(dialog, style)
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null)
|
||||
dialog.setContentView(view)
|
||||
//view.minimumHeight = resources.displayMetrics.heightPixels
|
||||
|
||||
tabLayout = view.findViewById(R.id.download_tablayout)
|
||||
viewPager2 = view.findViewById(R.id.download_viewpager)
|
||||
|
|
@ -79,7 +89,7 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("bottomSheet")!!).commit()
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadSingleSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.ui.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
|
||||
import com.deniscerri.ytdlnis.R;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity{
|
||||
|
||||
private FragmentManager fm;
|
||||
private MaterialToolbar topAppBar;
|
||||
Context context;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
context = getBaseContext();
|
||||
topAppBar = findViewById(R.id.settings_toolbar);
|
||||
topAppBar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
fm = getSupportFragmentManager();
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.settings_frame_layout, new SettingsFragment())
|
||||
.commit();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.deniscerri.ytdlnis.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
private var fm: FragmentManager? = null
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
var context: Context? = null
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_settings)
|
||||
context = baseContext
|
||||
topAppBar = findViewById(R.id.settings_toolbar)
|
||||
topAppBar!!.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
|
||||
fm = supportFragmentManager
|
||||
fm!!.beginTransaction()
|
||||
.replace(R.id.settings_frame_layout, SettingsFragment())
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import android.app.Activity
|
|||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItemWithFormats
|
||||
|
|
@ -26,14 +25,12 @@ class InfoUtil(context: Context) {
|
|||
private var items: ArrayList<ResultItemWithFormats?>
|
||||
private var key: String? = null
|
||||
private var useInvidous = false
|
||||
private var databaseManager: DatabaseManager? = null
|
||||
|
||||
init {
|
||||
try {
|
||||
val sharedPreferences =
|
||||
context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
key = sharedPreferences.getString("api_key", "")
|
||||
databaseManager = DatabaseManager(context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
|
@ -258,9 +255,6 @@ class InfoUtil(context: Context) {
|
|||
val duration = obj.getString("duration")
|
||||
val thumb = obj.getString("thumb")
|
||||
val url = "https://www.youtube.com/watch?v=$id"
|
||||
val downloadedAudio = databaseManager!!.checkDownloaded(url, "audio")
|
||||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||
val isPlaylist = 0
|
||||
video = ResultItemWithFormats(
|
||||
ResultItem(0,
|
||||
url,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#00A6FF"
|
||||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M14,2H6C4.9,2 4,2.9 4,4v16c0,1.1 0.89,2 1.99,2H15v-8h5V8L14,2zM13,9V3.5L18.5,9H13zM17,21.66V16h5.66v2h-2.24l2.95,2.95l-1.41,1.41L19,19.41l0,2.24H17z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M14,2H6C4.9,2 4,2.9 4,4v16c0,1.1 0.89,2 1.99,2H15v-8h5V8L14,2zM13,9V3.5L18.5,9H13zM17,21.66V16h5.66v2h-2.24l2.95,2.95l-1.41,1.41L19,19.41l0,2.24H17z"/>
|
||||
</vector>
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_download_type.xml
Normal file
5
app/src/main/res/drawable/ic_download_type.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19L3,19L3,5h18v14zM8,15c0,-1.66 1.34,-3 3,-3 0.35,0 0.69,0.07 1,0.18L12,6h5v2h-3v7.03c-0.02,1.64 -1.35,2.97 -3,2.97 -1.66,0 -3,-1.34 -3,-3z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_format.xml
Normal file
5
app/src/main/res/drawable/ic_format.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM13,9h4c0.55,0 1,0.45 1,1v4c0,0.55 -0.45,1 -1,1h-4L13,9zM14.5,13.5h2v-3h-2v3z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_handle.xml
Normal file
5
app/src/main/res/drawable/ic_handle.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4V15z"/>
|
||||
</vector>
|
||||
138
app/src/main/res/layout/download_card.xml
Normal file
138
app/src/main/res/layout/download_card.xml
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/downloads_card_constraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/materialButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="end"
|
||||
android:padding="0dp"
|
||||
app:icon="@drawable/ic_handle" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/download_card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="95dp"
|
||||
android:layout_margin="10dp"
|
||||
android:checkable="true"
|
||||
app:cardCornerRadius="10dp"
|
||||
app:cardElevation="10dp"
|
||||
app:cardMaxElevation="12dp"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/materialButton"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/downloads_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/download_progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:alpha="0.7"
|
||||
android:indeterminate="true"
|
||||
android:scaleY="100"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="296dp"
|
||||
android:layout_height="41dp"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:shadowColor="@color/black"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowRadius="2"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author"
|
||||
android:layout_width="296dp"
|
||||
android:layout_height="23dp"
|
||||
android:gravity="bottom"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:shadowColor="@color/black"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowRadius="1.5"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/author"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/encoding"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/container" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/filesize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/encoding" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/downloads_download_button_type"
|
||||
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_margin="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
101
app/src/main/res/layout/download_multiple_bottom_sheet.xml
Normal file
101
app/src/main/res/layout/download_multiple_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/materialButton"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="end"
|
||||
app:icon="@drawable/ic_format"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/materialButton2"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/materialButton2"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="end"
|
||||
app:icon="@drawable/ic_download_type"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/download_multiple_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:padding="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:id="@+id/bottomsheet_cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:id="@+id/bottomsheet_download_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download"
|
||||
app:icon="@drawable/ic_down"
|
||||
android:autoLink="all"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -166,4 +166,5 @@
|
|||
<string name="container">Container</string>
|
||||
<string name="template">Template</string>
|
||||
<string name="history">History</string>
|
||||
<string name="logs">Logs</string>
|
||||
</resources>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<Preference
|
||||
app:enabled="false"
|
||||
android:layout="@layout/fragment_more"/>
|
||||
|
|
@ -9,6 +10,7 @@
|
|||
app:icon="@drawable/ic_code"
|
||||
app:key="rreth"
|
||||
app:summary="https://github.com/deniscerri/ytdlnis"
|
||||
app:allowDividerBelow="true"
|
||||
app:title="@string/source_code">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
|
|
@ -17,13 +19,19 @@
|
|||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
app:allowDividerAbove="true"
|
||||
app:allowDividerBelow="true"
|
||||
app:key="run_command"
|
||||
app:title="@string/custom_command">
|
||||
<intent android:action="ytdlnis.page.CustomCommandActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_baseline_file_open_24"
|
||||
app:key="download_logs"
|
||||
app:allowDividerBelow="true"
|
||||
app:title="@string/logs">
|
||||
<intent android:action="ytdlnis.page.DownloadLogsActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_settings"
|
||||
app:key="open_settings"
|
||||
|
|
@ -32,4 +40,5 @@
|
|||
</Preference>
|
||||
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
Reference in a new issue