added app icon (thank you decipher3114)

fixed app crashing when you multiselect and unselect
removed utc from history
updated mp3 and mp4 tags to audio and video
made app have a different background if its light or dark theme
This commit is contained in:
Denis Çerri 2022-09-28 00:15:30 +02:00
parent a24efbbe60
commit 69abfb947f
No known key found for this signature in database
GPG key ID: 3F50F14A8E7F7A13
33 changed files with 534 additions and 286 deletions

View file

@ -5,7 +5,304 @@
<map>
<entry key="imageWizard">
<value>
<PersistentState />
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="actionbar">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\denis\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="backgroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="imagePath" value="C:\Users\denis\Desktop\YTDLNIS\Dark\xxxhdpi\adaptiveproduct_youtube_background_color_108.png" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundClipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="imagePath" value="C:\Users\denis\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\denis\Desktop\YTDLNIS\Dark\xxxhdpi\adaptiveproduct_youtube_foreground_color_108.png" />
<entry key="scalingPercent" value="95" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundTextAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="backgroundAssetType" value="COLOR" />
<entry key="backgroundColor" value="000000" />
<entry key="generatePlayStoreIcon" value="false" />
<entry key="legacyIconShape" value="NONE" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcherLegacy">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\denis\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="notification">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\denis\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="tvBanner">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="tvChannel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundClipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="imagePath" value="C:\Users\denis\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundTextAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="vectorWizard">
@ -33,9 +330,10 @@
</option>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="color" value="00a6ff" />
<entry key="outputName" value="ic_video_stopped" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\eaKdW401.svg" />
<entry key="outputName" value="ic_launcher_foreground" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map>
</option>
</PersistentState>

View file

@ -7,11 +7,11 @@
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="192.168.1.131:44159" />
<value value="192.168.1.131:43815" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-09-23T20:00:37.414283600Z" />
<timeTargetWasSelectedWithDropDown value="2022-09-27T10:56:58.187849900Z" />
</component>
</project>

View file

@ -35,6 +35,7 @@
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.2057460611677479" />
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/xml/root_preferences.xml" value="0.33" />
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/xml/shortcuts.xml" value="0.13852073535699017" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.22" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_announcement.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_back.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_baseline_keyboard_arrow_right_24.xml" value="0.109" />
@ -48,6 +49,8 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_home.xml" value="0.1275" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_image.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_info.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_launcher_background.xml" value="0.2395" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_launcher_foreground.xml" value="0.1965" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_lines.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_more.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
@ -88,6 +91,7 @@
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/history_menu.xml" value="0.17" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.25" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/settings_menu.xml" value="0.16875" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.2395" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/about_preferences.xml" value="0.16875" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/display_preferences.xml" value="0.16875" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/download_preferences.xml" value="0.16875" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View file

@ -7,15 +7,14 @@ import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaScannerConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.page.CustomCommandActivity;
import com.deniscerri.ytdlnis.service.DownloadInfo;
import com.deniscerri.ytdlnis.service.IDownloaderListener;
import com.deniscerri.ytdlnis.service.IDownloaderService;
@ -24,6 +23,7 @@ import com.yausername.youtubedl_android.DownloadProgressCallback;
import com.yausername.youtubedl_android.YoutubeDL;
import com.yausername.youtubedl_android.YoutubeDLRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
@ -31,7 +31,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
@ -48,15 +47,19 @@ public class DownloaderService extends Service {
private final NotificationUtil notificationUtil = App.notificationUtil;
private Context context;
public String downloadProcessID = "processID";
private static final String TAG = "DownloaderService";
private int downloadNotificationID;
private final DownloadProgressCallback callback = (progress, etaInSeconds, line) -> {
downloadInfo.setProgress((int) progress);
downloadInfo.setOutputLine(line);
downloadInfo.setDownloadQueue(downloadQueue);
notificationUtil.updateDownloadNotification(NotificationUtil.DOWNLOAD_NOTIFICATION_ID,
line, (int) progress, downloadQueue.size(), downloadQueue.peek().getTitle());
String title = getString(R.string.running_ytdlp_command);
if (!downloadQueue.isEmpty()){
title = downloadQueue.peek().getTitle();
}
notificationUtil.updateDownloadNotification(downloadNotificationID,
line, (int) progress, downloadQueue.size(), title);
try{
for (Activity activity: activities.keySet()){
@ -79,8 +82,8 @@ public class DownloaderService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
Intent theIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE);
Intent theIntent;
PendingIntent pendingIntent;
if(intent.getBooleanExtra("rebind", false)){
return binder;
@ -89,20 +92,28 @@ public class DownloaderService extends Service {
int id = intent.getIntExtra("id", 1);
switch (id){
case NotificationUtil.DOWNLOAD_NOTIFICATION_ID:
ArrayList queue = (ArrayList<Video>) intent.getSerializableExtra("queue");
theIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE);
downloadNotificationID = id;
ArrayList<? extends Video> queue = intent.getParcelableArrayListExtra("queue");
downloadQueue = new LinkedList<>();
downloadQueue.addAll(queue);
downloadInfo.setDownloadQueue(downloadQueue);
String title = downloadInfo.getVideo().getTitle();
Notification notification = App.notificationUtil.createDownloadServiceNotification(pendingIntent,title);
startForeground(NotificationUtil.DOWNLOAD_NOTIFICATION_ID, notification);
startForeground(downloadNotificationID, notification);
startDownload(downloadQueue);
break;
case NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID:
theIntent = new Intent(this, CustomCommandActivity.class);
pendingIntent = PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE);
downloadNotificationID = id;
String command = intent.getStringExtra("command");
Notification command_notification = App.notificationUtil.createDownloadServiceNotification(pendingIntent,getString(R.string.running_ytdlp_command));
startForeground(NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID, command_notification);
startForeground(downloadNotificationID, command_notification);
startCommandDownload(command);
break;
}
@ -180,6 +191,17 @@ public class DownloaderService extends Service {
return;
}
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadStart(downloadInfo);
});
}
}catch (Exception err){
err.printStackTrace();
}
String url = video.getURL();
YoutubeDLRequest request = new YoutubeDLRequest(url);
@ -201,29 +223,40 @@ public class DownloaderService extends Service {
if(!limitRate.equals("")) request.addOption("-r", limitRate);
boolean writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false);
if(writeThumbnail) request.addOption("--write-thumbnail");
if(writeThumbnail) {
request.addOption("--write-thumbnail");
request.addOption("--convert-thumbnails", "png");
}
request.addOption("--no-mtime");
if (type.equals("mp3")) {
boolean removeNonMusic = sharedPreferences.getBoolean("remove_non_music", false);
if(removeNonMusic){
request.addOption("--sponsorblock-remove", "all");
}
request.addOption("--postprocessor-args", "-write_id3v1 1 -id3v2_version 3");
request.addOption("--add-metadata");
if (type.equals("audio")) {
request.addOption("-x");
String format = sharedPreferences.getString("audio_format", "");
request.addOption("--audio-format", format);
request.addOption("--embed-metadata");
if(format.equals("mp3") || format.equals("m4a") || format.equals("flac")){
boolean embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false);
if(embedThumb){
request.addOption("--embed-thumbnail");
request.addOption("--convert-thumbnails", "png");
try{
File config = new File(getCacheDir(), "config.txt");
String config_data = "--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\"";
FileOutputStream stream = new FileOutputStream(config);
stream.write(config_data.getBytes());
stream.close();
request.addOption("--config", config.getAbsolutePath());
}catch(Exception ignored){}
}
}
} else if (type.equals("mp4")) {
boolean removeNonMusic = sharedPreferences.getBoolean("remove_non_music", false);
if(removeNonMusic){
request.addOption("--sponsorblock-remove", "all");
}
} else if (type.equals("video")) {
boolean addChapters = sharedPreferences.getBoolean("add_chapters", false);
if(addChapters){
request.addOption("--sponsorblock-mark", "all");
@ -251,6 +284,7 @@ public class DownloaderService extends Service {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(youtubeDLResponse -> {
downloadInfo.setDownloadPath(youtubeDLDir.getAbsolutePath());
try{
for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> {
@ -283,6 +317,7 @@ public class DownloaderService extends Service {
// SCAN NEXT IN QUEUE
videos.remove();
downloadInfo.setDownloadQueue(videos);
startDownload(videos);
});
compositeDisposable.add(disposable);
@ -341,6 +376,7 @@ public class DownloaderService extends Service {
activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity);
callback.onDownloadError(downloadInfo);
callback.onDownloadServiceEnd();
});
}
}catch (Exception err){
@ -355,7 +391,7 @@ public class DownloaderService extends Service {
private File getDownloadLocation(String type) {
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
String downloadsDir;
if (type.equals("mp3")) {
if (type.equals("audio")) {
downloadsDir = sharedPreferences.getString("music_path", getString(R.string.music_path));
} else {
downloadsDir = sharedPreferences.getString("video_path", getString(R.string.video_path));

View file

@ -166,7 +166,7 @@ public class MainActivity extends AppCompatActivity{
}
listener = awaitingListener;
Intent serviceIntent = new Intent(context, DownloaderService.class);
serviceIntent.putExtra("queue", downloadQueue);
serviceIntent.putParcelableArrayListExtra("queue", downloadQueue);
context.getApplicationContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}

View file

@ -91,7 +91,7 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
// BUTTON ----------------------------------
LinearLayout buttonLayout = card.findViewById(R.id.history_download_button_layout);
Button btn = buttonLayout.findViewById(R.id.history_download_button_type);
if(video.getDownloadedType().equals("mp3")){
if(video.getDownloadedType().equals("audio") || video.getDownloadedType().equals("mp3")){
btn.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_music));
}else{
btn.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_video));

View file

@ -95,12 +95,12 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
LinearLayout buttonLayout = card.findViewById(R.id.download_button_layout);
MaterialButton musicBtn = buttonLayout.findViewById(R.id.download_music);
musicBtn.setTag(videoID + "##mp3");
musicBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "mp3"));
musicBtn.setTag(videoID + "##audio");
musicBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "audio"));
MaterialButton videoBtn = buttonLayout.findViewById(R.id.download_video);
videoBtn.setTag(videoID + "##mp4");
videoBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "mp4"));
videoBtn.setTag(videoID + "##video");
videoBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "video"));
// PROGRESS BAR ----------------------------------------------------
@ -143,7 +143,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
private void checkCard(MaterialCardView card, int position){
if(card.isChecked()){
card.setStrokeWidth(0);
checkedVideos.remove(position);
checkedVideos.remove(Integer.valueOf(position));
}else{
card.setStrokeWidth(5);
checkedVideos.add(position);
@ -169,6 +169,15 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
notifyItemRangeInserted(size, videoList.size());
}
public void clearCheckedVideos(){
int size = checkedVideos.size();
for (int i = 0; i < size; i++){
int position = checkedVideos.get(i);
notifyItemChanged(position);
}
checkedVideos.clear();
}
public void clear(){
int size = videoList.size();
videoList = new ArrayList<>();

View file

@ -179,8 +179,8 @@ public class YoutubeAPIManager {
String duration = obj.getString("duration");
String thumb = obj.getString("thumb");
int downloadedAudio = dbManager.checkDownloaded(id, "mp3");
int downloadedVideo = dbManager.checkDownloaded(id, "mp4");
int downloadedAudio = dbManager.checkDownloaded(id, "audio");
int downloadedVideo = dbManager.checkDownloaded(id, "video");
String url = "https://www.youtube.com/watch?v=" + id;
int isPLaylist = 0;
@ -270,8 +270,8 @@ public class YoutubeAPIManager {
streamInfo.getUploader(),
formatIntegerDuration(streamInfo.getDuration()),
streamInfo.getThumbnail(),
dbManager.checkDownloaded(id, "mp3"),
dbManager.checkDownloaded(id, "mp4"),
dbManager.checkDownloaded(id, "audio"),
dbManager.checkDownloaded(id, "video"),
0,
streamInfo.getWebpageUrlBasename()
);
@ -335,7 +335,7 @@ public class YoutubeAPIManager {
tmp = "0" + tmp;
}
if (c == 'D'){
hours = String.valueOf(Integer.valueOf(tmp) * 24);
hours = String.valueOf(Integer.parseInt(tmp) * 24);
}else if(c == 'T'){
continue;
}else if(c == 'H'){

View file

@ -78,10 +78,10 @@ public class DBManager extends SQLiteOpenHelper {
String where = "";
switch(video.getDownloadedType()){
case "mp3":
case "audio":
where = " SET downloadedAudio=0 WHERE downloadedAudio=1 AND videoId='" + video.getVideoId()+"'";
break;
case "mp4":
case "video":
where = " SET downloadedVideo=0 WHERE downloadedVideo=1 AND videoId='" + video.getVideoId()+"'";
break;
}
@ -198,10 +198,10 @@ public class DBManager extends SQLiteOpenHelper {
ContentValues values = new ContentValues();
switch (type){
case "mp3":
case "audio":
values.put(downloadedAudio, 1);
break;
case "mp4":
case "video":
values.put(downloadedVideo, 1);
break;
}

View file

@ -1,8 +1,9 @@
package com.deniscerri.ytdlnis.database;
import java.io.Serializable;
import android.os.Parcel;
import android.os.Parcelable;
public class Video implements Serializable {
public class Video implements Parcelable {
private int id;
private String videoId;
private String title;
@ -47,6 +48,34 @@ public class Video implements Serializable {
}
protected Video(Parcel in) {
id = in.readInt();
videoId = in.readString();
title = in.readString();
author = in.readString();
duration = in.readString();
thumb = in.readString();
url = in.readString();
downloadedType = in.readString();
downloadedAudio = in.readInt();
downloadedVideo = in.readInt();
downloadedTime = in.readString();
isPlaylistItem = in.readInt();
website = in.readString();
}
public static final Creator<Video> CREATOR = new Creator<Video>() {
@Override
public Video createFromParcel(Parcel in) {
return new Video(in);
}
@Override
public Video[] newArray(int size) {
return new Video[size];
}
};
public int getId() {
return id;
}
@ -118,4 +147,27 @@ public class Video implements Serializable {
public String getWebsite() { return website; }
public void setWebsite(String site){ this.website = site; }
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(videoId);
parcel.writeString(title);
parcel.writeString(author);
parcel.writeString(duration);
parcel.writeString(thumb);
parcel.writeString(url);
parcel.writeString(downloadedType);
parcel.writeInt(downloadedAudio);
parcel.writeInt(downloadedVideo);
parcel.writeString(downloadedTime);
parcel.writeInt(isPlaylistItem);
parcel.writeString(website);
}
}

View file

@ -1,7 +1,6 @@
package com.deniscerri.ytdlnis.page;
import android.Manifest;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -12,23 +11,19 @@ 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 androidx.core.content.ContextCompat;
import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.DownloaderService;
import com.deniscerri.ytdlnis.database.Video;
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.button.MaterialButton;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import java.util.Date;
public class CustomCommandActivity extends AppCompatActivity {
private static final String TAG = "CustomCommandActivity";
@ -40,6 +35,7 @@ public class CustomCommandActivity extends AppCompatActivity {
private ExtendedFloatingActionButton fab;
private ExtendedFloatingActionButton cancelFab;
private IDownloaderService iDownloaderService;
private ScrollView scrollView;
Context context;
private final ServiceConnection serviceConnection = new ServiceConnection() {
@ -74,18 +70,23 @@ public class CustomCommandActivity extends AppCompatActivity {
public void onDownloadProgress(DownloadInfo info) {
output.append("\n" + info.getOutputLine());
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
}
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();
}
@ -102,6 +103,7 @@ public class CustomCommandActivity extends AppCompatActivity {
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);
@ -148,7 +150,6 @@ public class CustomCommandActivity extends AppCompatActivity {
}
public void stopDownloadService(){
Log.e(TAG, String.valueOf(isDownloadServiceRunning));
if(!isDownloadServiceRunning) return;
iDownloaderService.removeActivity(this);
context.getApplicationContext().unbindService(serviceConnection);

View file

@ -15,6 +15,7 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
@ -41,6 +42,8 @@ import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textfield.TextInputLayout;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -80,28 +83,29 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
public IDownloaderListener listener = new IDownloaderListener() {
public void onDownloadStart(DownloadInfo downloadInfo) {
if(downloadInfo != null){
String id = downloadInfo.getVideo().getVideoId();
String type = downloadInfo.getVideo().getDownloadedType();
MaterialButton clickedButton = recyclerView.findViewWithTag(id + "##"+type);
try{
if(downloadInfo != null){
String id = downloadInfo.getVideo().getVideoId();
String type = downloadInfo.getVideo().getDownloadedType();
progressBar = fragmentView.findViewWithTag(id + "##progress");
progressBar.setVisibility(View.VISIBLE);
recyclerView.smoothScrollToPosition(resultObjects.indexOf(findVideo(id)));
MaterialButton clickedButton = recyclerView.findViewWithTag(id + "##"+type);
progressBar = recyclerView.findViewWithTag(id + "##progress");
progressBar.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(true);
progressBar.setProgress(0);
downloading = true;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(true);
//scroll to Card
recyclerView.scrollToPosition(resultObjects.indexOf(findVideo(id)));
progressBar.setProgress(0);
downloading = true;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(true);
if (clickedButton != null) {
if (type.equals("mp3")) {
clickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
} else {
clickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
if (clickedButton != null) {
if (type.equals("audio")) {
clickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music));
} else {
clickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video));
}
}
}
}
}catch(Exception ignored){}
}
public void onDownloadProgress(DownloadInfo info) {
@ -109,6 +113,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
try{
progressBar = fragmentView.findViewWithTag(info.getVideo().getVideoId()+"##progress");
progressBar.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(false);
progressBar.setProgress(info.getProgress());
}catch(Exception ignored){}
});
@ -135,20 +140,32 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
MaterialButton theClickedButton = recyclerView.findViewWithTag(id + "##"+type);
if (theClickedButton != null) {
if (type.equals("mp3")) {
if (type.equals("audio")) {
theClickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded));
} else {
theClickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded));
}
}
addToHistory(item, new Date());
updateDownloadStatusOnResult(item, type);
downloading = false;
topAppBar.getMenu().findItem(R.id.cancel_download).setVisible(false);
// MEDIA SCAN
MediaScannerConnection.scanFile(context, new String[]{downloadInfo.getDownloadPath()}, null, null);
ArrayList<File> files = new ArrayList<>();
String title = downloadInfo.getVideo().getTitle();
File path = new File(downloadInfo.getDownloadPath());
for( File file : path.listFiles() ){
if(file.isFile() && file.getAbsolutePath().contains(title)) files.add(file);
}
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) paths[i] = files.get(i).getAbsolutePath();
MediaScannerConnection.scanFile(context, paths, null, null);
mainActivity.updateHistoryFragment();
}catch(Exception ignored){}
}
@ -182,7 +199,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
context = fragmentView.getContext();
context = fragmentView.getContext().getApplicationContext();
activity = getActivity();
mainActivity = (MainActivity) activity;
@ -194,7 +211,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
homeRecyclerViewAdapter = new HomeRecyclerViewAdapter(resultObjects, this, activity);
recyclerView.setAdapter(homeRecyclerViewAdapter);
recyclerView.setNestedScrollingEnabled(false);
youtubeAPIManager = new YoutubeAPIManager(context);
@ -213,8 +229,8 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
FloatingActionButton music_fab = downloadFabs.findViewById(R.id.audio_fab);
FloatingActionButton video_fab = downloadFabs.findViewById(R.id.video_fab);
music_fab.setTag("SELECT##mp3");
video_fab.setTag("SELECT##mp4");
music_fab.setTag("SELECT##audio");
video_fab.setTag("SELECT##video");
music_fab.setOnClickListener(this);
video_fab.setOnClickListener(this);
@ -329,7 +345,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
MaterialButton theClickedButton = recyclerView.findViewWithTag(id + "##"+type);
if (theClickedButton != null) {
if (type.equals("mp3")) {
if (type.equals("audio")) {
theClickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_music_stopped));
} else {
theClickedButton.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_video_stopped));
@ -583,7 +599,6 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
int year = cal.get(Calendar.YEAR);
DateFormat formatter = new SimpleDateFormat("HH:mm", Locale.getDefault());
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String time = formatter.format(date);
String downloadedTime = day + " " + month + " " + year + " " + time;
@ -634,17 +649,18 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
}
if (!viewIdName.isEmpty()) {
if (viewIdName.contains("mp3") || viewIdName.contains("mp4")) {
if (viewIdName.contains("audio") || viewIdName.contains("video")) {
Log.e(TAG, viewIdName);
String[] buttonData = viewIdName.split("##");
if (buttonData[0].equals("SELECT")) {
for (int i = 0; i < selectedObjects.size(); i++) {
Video vid = findVideo(selectedObjects.get(i).getVideoId());
vid.setDownloadedType(buttonData[1]);
homeRecyclerViewAdapter.notifyItemChanged(resultObjects.indexOf(vid));
downloadQueue.add(vid);
}
selectedObjects = new ArrayList<>();
homeRecyclerViewAdapter.clearCheckedVideos();
downloadFabs.setVisibility(View.GONE);
if (downloading) {
@ -681,14 +697,14 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
audio.setOnClickListener(view -> {
int start = Integer.parseInt(first.getEditText().getText().toString());
int end = Integer.parseInt(last.getEditText().getText().toString());
initDownloadAll(bottomSheet, start, end, "mp3");
initDownloadAll(bottomSheet, start, end, "audio");
});
Button video = bottomSheet.findViewById(R.id.bottomsheet_video_button);
video.setOnClickListener(view -> {
int start = Integer.parseInt(first.getEditText().getText().toString());
int end = Integer.parseInt(last.getEditText().getText().toString());
initDownloadAll(bottomSheet, start, end, "mp4");
initDownloadAll(bottomSheet, start, end, "video");
});
bottomSheet.show();

View file

@ -38,14 +38,14 @@ public class NotificationUtil {
//gui downloads
CharSequence name = context.getString(R.string.download_notification_channel_name);
String description = context.getString(R.string.download_notification_channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(DOWNLOAD_SERVICE_CHANNEL_ID, name, importance);
channel.setDescription(description);
notificationManager.createNotificationChannel(channel);
//command downloads
name = "Command Downloads";
description = "Notification that shows the download progress of a yt-dlp command";
name = context.getString(R.string.command_download_notification_channel_name);
description = context.getString(R.string.command_download_notification_channel_description);
channel = new NotificationChannel(COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID, name, importance);
channel.setDescription(description);
notificationManager.createNotificationChannel(channel);
@ -61,7 +61,6 @@ public class NotificationUtil {
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), android.R.drawable.stat_sys_download))
.setContentText("")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setOnlyAlertOnce(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setProgress(PROGRESS_MAX, PROGRESS_CURR, false)
.setContentIntent(pendingIntent)
@ -73,12 +72,12 @@ public class NotificationUtil {
public void updateDownloadNotification(int id, String desc, int progress, int queue, String title){
String contentText = "";
if (queue > 1) contentText += queue - 1 + " item(s) left\n";
contentText += desc.replaceAll("\\[.*?\\]", "");
if (queue > 1) contentText += queue - 1 + " " + context.getString(R.string.items_left) + "\n";
contentText += desc.replaceAll("\\[.*?\\] ", "");
notificationBuilder.setProgress(100, (int) progress, false)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(contentText));
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(contentText));
notificationManager.notify(id, notificationBuilder.build());
}

View file

@ -1,36 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="108dp"
android:gravity="fill_horizontal|fill_vertical"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
android:name="path"
android:pathData="M 73.977 46.512 C 75.734 48.222 76.781 50.662 76.872 53.315 C 76.945 55.412 77 57.629 77 59.482 C 77 61.335 76.945 63.552 76.872 65.649 C 76.718 70.133 73.835 74.006 69.404 74.78 C 65.706 75.426 60.571 76 54 76 C 47.429 76 42.294 75.426 38.596 74.78 C 34.165 74.006 31.282 70.133 31.128 65.649 C 31.055 63.552 31 61.335 31 59.482 C 31 57.629 31.055 55.412 31.128 53.315 C 31.282 48.831 34.165 44.957 38.596 44.183 C 41.576 43.663 45.489 43.189 50.335 43.025 C 51.232 37.348 56.145 33 62.083 33 C 68.658 33 73.977 38.331 73.977 44.895 L 73.977 46.512 Z M 52.345 42.976 C 52.886 42.968 53.438 42.963 54 42.963 L 54.086 42.963 C 53.495 42.964 52.915 42.969 52.347 42.978 C 52.224 43.601 52.16 44.244 52.16 44.902 L 52.16 51.756 L 48.489 51.76 C 46.26 51.763 44.867 54.174 45.98 56.106 L 51.541 65.764 C 52.656 67.699 55.448 67.701 56.565 65.767 L 62.15 56.095 C 63.267 54.161 61.869 51.744 59.636 51.747 L 55.803 51.752 L 55.803 44.902 L 55.803 44.895 L 55.782 44.895 C 55.782 41.413 58.603 38.59 62.083 38.59 C 65.26 38.59 67.888 40.943 68.322 44.003 C 68.695 44.062 69.056 44.122 69.404 44.183 C 70.345 44.347 71.216 44.651 72.006 45.071 L 72.006 44.895 C 72.006 39.412 67.563 34.967 62.083 34.967 C 57.259 34.967 53.239 38.411 52.345 42.976 Z M 66.248 43.705 C 65.731 41.885 64.058 40.557 62.083 40.557 C 60.356 40.557 58.86 41.571 58.166 43.043 C 61.248 43.162 63.941 43.407 66.248 43.705 Z"
android:fillColor="#d43c3c"
android:strokeWidth="1"
android:fillType="evenOdd"/>
</vector>

View file

@ -5,166 +5,6 @@
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
android:fillColor="@color/icon_bg"
android:pathData="M 0 0 H 192 V 192 H 0 V 0 Z" />
</vector>

View file

@ -19,7 +19,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
@ -33,6 +33,7 @@
android:maxLines="5" />
<ScrollView
android:id="@+id/custom_command_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"

View file

@ -13,6 +13,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/home_toolbar"
android:layout_width="match_parent"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="icon_bg">@android:color/background_dark</color>
</resources>

View file

@ -87,4 +87,7 @@
<string name="audio_quality_summary">0 (Më i miri) 10 (Më i keqi)</string>
<string name="cancel_download">Anulo Shkarkimin</string>
<string name="run_command">Ekzekuto Komandën</string>
<string name="command_download_notification_channel_name">Shkarkimet e Skedarëve nga Komanda</string>
<string name="command_download_notification_channel_description">Njoftimi i cili tregon progresin e shkarkimeve te skedarëve audio dhe video nga komanda</string>
<string name="items_left">element(e) në rradhë</string>
</resources>

View file

@ -4,4 +4,5 @@
<color name="black">#000000</color>
<color name="grey">#323232</color>
<color name="light_grey">#A6A6A6</color>
<color name="icon_bg">@android:color/background_light</color>
</resources>

View file

@ -90,4 +90,7 @@
<string name="audio_quality_summary">0 (Best) 10 (Worst)</string>
<string name="cancel_download">Cancel Download</string>
<string name="run_command">Run Command</string>
<string name="command_download_notification_channel_name">Command Downloads</string>
<string name="command_download_notification_channel_description">Notification that shows the download progress of a yt-dlp command</string>
<string name="items_left">item(s) left</string>
</resources>

View file

@ -17,7 +17,7 @@ buildscript {
def versionMajor = 1
def versionMinor = 3
def versionPatch = 0
def versionPatch = 1
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
ext {