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> <map>
<entry key="imageWizard"> <entry key="imageWizard">
<value> <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> </value>
</entry> </entry>
<entry key="vectorWizard"> <entry key="vectorWizard">
@ -33,9 +330,10 @@
</option> </option>
<option name="values"> <option name="values">
<map> <map>
<entry key="assetSourceType" value="FILE" />
<entry key="color" value="00a6ff" /> <entry key="color" value="00a6ff" />
<entry key="outputName" value="ic_video_stopped" /> <entry key="outputName" value="ic_launcher_foreground" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\eaKdW401.svg" /> <entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map> </map>
</option> </option>
</PersistentState> </PersistentState>

View file

@ -7,11 +7,11 @@
<deviceKey> <deviceKey>
<Key> <Key>
<type value="SERIAL_NUMBER" /> <type value="SERIAL_NUMBER" />
<value value="192.168.1.131:44159" /> <value value="192.168.1.131:43815" />
</Key> </Key>
</deviceKey> </deviceKey>
</Target> </Target>
</runningDeviceTargetSelectedWithDropDown> </runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-09-23T20:00:37.414283600Z" /> <timeTargetWasSelectedWithDropDown value="2022-09-27T10:56:58.187849900Z" />
</component> </component>
</project> </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/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/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/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_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_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" /> <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_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_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_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_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_more.xml" value="0.109" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" /> <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/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/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/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/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/display_preferences.xml" value="0.16875" />
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/download_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.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.media.MediaScannerConnection;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.deniscerri.ytdlnis.database.Video; import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.page.CustomCommandActivity;
import com.deniscerri.ytdlnis.service.DownloadInfo; import com.deniscerri.ytdlnis.service.DownloadInfo;
import com.deniscerri.ytdlnis.service.IDownloaderListener; import com.deniscerri.ytdlnis.service.IDownloaderListener;
import com.deniscerri.ytdlnis.service.IDownloaderService; 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.YoutubeDL;
import com.yausername.youtubedl_android.YoutubeDLRequest; import com.yausername.youtubedl_android.YoutubeDLRequest;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@ -31,7 +31,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
@ -48,15 +47,19 @@ public class DownloaderService extends Service {
private final NotificationUtil notificationUtil = App.notificationUtil; private final NotificationUtil notificationUtil = App.notificationUtil;
private Context context; private Context context;
public String downloadProcessID = "processID"; public String downloadProcessID = "processID";
private static final String TAG = "DownloaderService"; private static final String TAG = "DownloaderService";
private int downloadNotificationID;
private final DownloadProgressCallback callback = (progress, etaInSeconds, line) -> { private final DownloadProgressCallback callback = (progress, etaInSeconds, line) -> {
downloadInfo.setProgress((int) progress); downloadInfo.setProgress((int) progress);
downloadInfo.setOutputLine(line); downloadInfo.setOutputLine(line);
downloadInfo.setDownloadQueue(downloadQueue); downloadInfo.setDownloadQueue(downloadQueue);
notificationUtil.updateDownloadNotification(NotificationUtil.DOWNLOAD_NOTIFICATION_ID, String title = getString(R.string.running_ytdlp_command);
line, (int) progress, downloadQueue.size(), downloadQueue.peek().getTitle()); if (!downloadQueue.isEmpty()){
title = downloadQueue.peek().getTitle();
}
notificationUtil.updateDownloadNotification(downloadNotificationID,
line, (int) progress, downloadQueue.size(), title);
try{ try{
for (Activity activity: activities.keySet()){ for (Activity activity: activities.keySet()){
@ -79,8 +82,8 @@ public class DownloaderService extends Service {
@Nullable @Nullable
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
Intent theIntent = new Intent(this, MainActivity.class); Intent theIntent;
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, theIntent, PendingIntent.FLAG_IMMUTABLE); PendingIntent pendingIntent;
if(intent.getBooleanExtra("rebind", false)){ if(intent.getBooleanExtra("rebind", false)){
return binder; return binder;
@ -89,20 +92,28 @@ public class DownloaderService extends Service {
int id = intent.getIntExtra("id", 1); int id = intent.getIntExtra("id", 1);
switch (id){ switch (id){
case NotificationUtil.DOWNLOAD_NOTIFICATION_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 = new LinkedList<>();
downloadQueue.addAll(queue); downloadQueue.addAll(queue);
downloadInfo.setDownloadQueue(downloadQueue); downloadInfo.setDownloadQueue(downloadQueue);
String title = downloadInfo.getVideo().getTitle(); String title = downloadInfo.getVideo().getTitle();
Notification notification = App.notificationUtil.createDownloadServiceNotification(pendingIntent,title); Notification notification = App.notificationUtil.createDownloadServiceNotification(pendingIntent,title);
startForeground(NotificationUtil.DOWNLOAD_NOTIFICATION_ID, notification); startForeground(downloadNotificationID, notification);
startDownload(downloadQueue); startDownload(downloadQueue);
break; break;
case NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID: 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"); String command = intent.getStringExtra("command");
Notification command_notification = App.notificationUtil.createDownloadServiceNotification(pendingIntent,getString(R.string.running_ytdlp_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); startCommandDownload(command);
break; break;
} }
@ -180,6 +191,17 @@ public class DownloaderService extends Service {
return; 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(); String url = video.getURL();
YoutubeDLRequest request = new YoutubeDLRequest(url); YoutubeDLRequest request = new YoutubeDLRequest(url);
@ -201,29 +223,40 @@ public class DownloaderService extends Service {
if(!limitRate.equals("")) request.addOption("-r", limitRate); if(!limitRate.equals("")) request.addOption("-r", limitRate);
boolean writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false); 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"); request.addOption("--no-mtime");
if (type.equals("mp3")) { if (type.equals("audio")) {
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");
request.addOption("-x"); request.addOption("-x");
String format = sharedPreferences.getString("audio_format", ""); String format = sharedPreferences.getString("audio_format", "");
request.addOption("--audio-format", format); request.addOption("--audio-format", format);
request.addOption("--embed-metadata");
if(format.equals("mp3") || format.equals("m4a") || format.equals("flac")){ if(format.equals("mp3") || format.equals("m4a") || format.equals("flac")){
boolean embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false); boolean embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false);
if(embedThumb){ if(embedThumb){
request.addOption("--embed-thumbnail"); 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); boolean addChapters = sharedPreferences.getBoolean("add_chapters", false);
if(addChapters){ if(addChapters){
request.addOption("--sponsorblock-mark", "all"); request.addOption("--sponsorblock-mark", "all");
@ -251,6 +284,7 @@ public class DownloaderService extends Service {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(youtubeDLResponse -> { .subscribe(youtubeDLResponse -> {
downloadInfo.setDownloadPath(youtubeDLDir.getAbsolutePath()); downloadInfo.setDownloadPath(youtubeDLDir.getAbsolutePath());
try{ try{
for (Activity activity: activities.keySet()){ for (Activity activity: activities.keySet()){
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
@ -283,6 +317,7 @@ public class DownloaderService extends Service {
// SCAN NEXT IN QUEUE // SCAN NEXT IN QUEUE
videos.remove(); videos.remove();
downloadInfo.setDownloadQueue(videos);
startDownload(videos); startDownload(videos);
}); });
compositeDisposable.add(disposable); compositeDisposable.add(disposable);
@ -341,6 +376,7 @@ public class DownloaderService extends Service {
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
IDownloaderListener callback = activities.get(activity); IDownloaderListener callback = activities.get(activity);
callback.onDownloadError(downloadInfo); callback.onDownloadError(downloadInfo);
callback.onDownloadServiceEnd();
}); });
} }
}catch (Exception err){ }catch (Exception err){
@ -355,7 +391,7 @@ public class DownloaderService extends Service {
private File getDownloadLocation(String type) { private File getDownloadLocation(String type) {
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE); SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
String downloadsDir; String downloadsDir;
if (type.equals("mp3")) { if (type.equals("audio")) {
downloadsDir = sharedPreferences.getString("music_path", getString(R.string.music_path)); downloadsDir = sharedPreferences.getString("music_path", getString(R.string.music_path));
} else { } else {
downloadsDir = sharedPreferences.getString("video_path", getString(R.string.video_path)); downloadsDir = sharedPreferences.getString("video_path", getString(R.string.video_path));

View file

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

View file

@ -91,7 +91,7 @@ public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecy
// BUTTON ---------------------------------- // BUTTON ----------------------------------
LinearLayout buttonLayout = card.findViewById(R.id.history_download_button_layout); LinearLayout buttonLayout = card.findViewById(R.id.history_download_button_layout);
Button btn = buttonLayout.findViewById(R.id.history_download_button_type); 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)); btn.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_music));
}else{ }else{
btn.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_video)); 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); LinearLayout buttonLayout = card.findViewById(R.id.download_button_layout);
MaterialButton musicBtn = buttonLayout.findViewById(R.id.download_music); MaterialButton musicBtn = buttonLayout.findViewById(R.id.download_music);
musicBtn.setTag(videoID + "##mp3"); musicBtn.setTag(videoID + "##audio");
musicBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "mp3")); musicBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "audio"));
MaterialButton videoBtn = buttonLayout.findViewById(R.id.download_video); MaterialButton videoBtn = buttonLayout.findViewById(R.id.download_video);
videoBtn.setTag(videoID + "##mp4"); videoBtn.setTag(videoID + "##video");
videoBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "mp4")); videoBtn.setOnClickListener(view -> onItemClickListener.onButtonClick(position, "video"));
// PROGRESS BAR ---------------------------------------------------- // PROGRESS BAR ----------------------------------------------------
@ -143,7 +143,7 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
private void checkCard(MaterialCardView card, int position){ private void checkCard(MaterialCardView card, int position){
if(card.isChecked()){ if(card.isChecked()){
card.setStrokeWidth(0); card.setStrokeWidth(0);
checkedVideos.remove(position); checkedVideos.remove(Integer.valueOf(position));
}else{ }else{
card.setStrokeWidth(5); card.setStrokeWidth(5);
checkedVideos.add(position); checkedVideos.add(position);
@ -169,6 +169,15 @@ public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerVi
notifyItemRangeInserted(size, videoList.size()); 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(){ public void clear(){
int size = videoList.size(); int size = videoList.size();
videoList = new ArrayList<>(); videoList = new ArrayList<>();

View file

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

View file

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

View file

@ -1,8 +1,9 @@
package com.deniscerri.ytdlnis.database; 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 int id;
private String videoId; private String videoId;
private String title; 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() { public int getId() {
return id; return id;
} }
@ -118,4 +147,27 @@ public class Video implements Serializable {
public String getWebsite() { return website; } public String getWebsite() { return website; }
public void setWebsite(String site){ this.website = site; } 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; package com.deniscerri.ytdlnis.page;
import android.Manifest; import android.Manifest;
import android.app.ActivityManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -12,23 +11,19 @@ import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.deniscerri.ytdlnis.R; import com.deniscerri.ytdlnis.R;
import com.deniscerri.ytdlnis.DownloaderService; import com.deniscerri.ytdlnis.DownloaderService;
import com.deniscerri.ytdlnis.database.Video;
import com.deniscerri.ytdlnis.service.DownloadInfo; import com.deniscerri.ytdlnis.service.DownloadInfo;
import com.deniscerri.ytdlnis.service.IDownloaderListener; import com.deniscerri.ytdlnis.service.IDownloaderListener;
import com.deniscerri.ytdlnis.service.IDownloaderService; import com.deniscerri.ytdlnis.service.IDownloaderService;
import com.deniscerri.ytdlnis.util.NotificationUtil; import com.deniscerri.ytdlnis.util.NotificationUtil;
import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import java.util.Date;
public class CustomCommandActivity extends AppCompatActivity { public class CustomCommandActivity extends AppCompatActivity {
private static final String TAG = "CustomCommandActivity"; private static final String TAG = "CustomCommandActivity";
@ -40,6 +35,7 @@ public class CustomCommandActivity extends AppCompatActivity {
private ExtendedFloatingActionButton fab; private ExtendedFloatingActionButton fab;
private ExtendedFloatingActionButton cancelFab; private ExtendedFloatingActionButton cancelFab;
private IDownloaderService iDownloaderService; private IDownloaderService iDownloaderService;
private ScrollView scrollView;
Context context; Context context;
private final ServiceConnection serviceConnection = new ServiceConnection() { private final ServiceConnection serviceConnection = new ServiceConnection() {
@ -74,18 +70,23 @@ public class CustomCommandActivity extends AppCompatActivity {
public void onDownloadProgress(DownloadInfo info) { public void onDownloadProgress(DownloadInfo info) {
output.append("\n" + info.getOutputLine()); output.append("\n" + info.getOutputLine());
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
} }
public void onDownloadError(DownloadInfo info) { public void onDownloadError(DownloadInfo info) {
output.append("\n" + info.getOutputLine()); output.append("\n" + info.getOutputLine());
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
input.setText("yt-dlp ");
input.setEnabled(true); input.setEnabled(true);
swapFabs(); swapFabs();
} }
public void onDownloadEnd(DownloadInfo info) { public void onDownloadEnd(DownloadInfo info) {
output.append(info.getOutputLine()); output.append(info.getOutputLine());
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
// MEDIA SCAN // MEDIA SCAN
MediaScannerConnection.scanFile(context, new String[]{"/storage"}, null, null); MediaScannerConnection.scanFile(context, new String[]{"/storage"}, null, null);
input.setText("yt-dlp ");
input.setEnabled(true); input.setEnabled(true);
swapFabs(); swapFabs();
} }
@ -102,6 +103,7 @@ public class CustomCommandActivity extends AppCompatActivity {
setContentView(R.layout.activity_custom_command); setContentView(R.layout.activity_custom_command);
context = getBaseContext(); context = getBaseContext();
scrollView = findViewById(R.id.custom_command_scrollview);
topAppBar = findViewById(R.id.custom_command_toolbar); topAppBar = findViewById(R.id.custom_command_toolbar);
topAppBar.setNavigationOnClickListener(view -> onBackPressed()); topAppBar.setNavigationOnClickListener(view -> onBackPressed());
output = findViewById(R.id.custom_command_output); output = findViewById(R.id.custom_command_output);
@ -148,7 +150,6 @@ public class CustomCommandActivity extends AppCompatActivity {
} }
public void stopDownloadService(){ public void stopDownloadService(){
Log.e(TAG, String.valueOf(isDownloadServiceRunning));
if(!isDownloadServiceRunning) return; if(!isDownloadServiceRunning) return;
iDownloaderService.removeActivity(this); iDownloaderService.removeActivity(this);
context.getApplicationContext().unbindService(serviceConnection); context.getApplicationContext().unbindService(serviceConnection);

View file

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

View file

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

View file

@ -1,36 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="108dp" android:width="108dp"
android:gravity="fill_horizontal|fill_vertical"
android:height="108dp" android:height="108dp"
android:viewportHeight="108" android:viewportWidth="108"
android:viewportWidth="108"> android:viewportHeight="108">
<path <path
android:fillType="evenOdd" android:name="path"
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: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:strokeColor="#00000000" android:fillColor="#d43c3c"
android:strokeWidth="1"> android:strokeWidth="1"
<aapt:attr name="android:fillColor"> android:fillType="evenOdd"/>
<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" />
</vector> </vector>

View file

@ -5,166 +5,6 @@
android:viewportHeight="108" android:viewportHeight="108"
android:viewportWidth="108"> android:viewportWidth="108">
<path <path
android:fillColor="#26A69A" android:fillColor="@color/icon_bg"
android:pathData="M0,0h108v108h-108z" /> android:pathData="M 0 0 H 192 V 192 H 0 V 0 Z" />
<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" />
</vector> </vector>

View file

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

View file

@ -13,6 +13,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/home_toolbar" android:id="@+id/home_toolbar"
android:layout_width="match_parent" 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="audio_quality_summary">0 (Më i miri) 10 (Më i keqi)</string>
<string name="cancel_download">Anulo Shkarkimin</string> <string name="cancel_download">Anulo Shkarkimin</string>
<string name="run_command">Ekzekuto Komandën</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> </resources>

View file

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

View file

@ -90,4 +90,7 @@
<string name="audio_quality_summary">0 (Best) 10 (Worst)</string> <string name="audio_quality_summary">0 (Best) 10 (Worst)</string>
<string name="cancel_download">Cancel Download</string> <string name="cancel_download">Cancel Download</string>
<string name="run_command">Run Command</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> </resources>

View file

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