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
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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" />
|
||||||
|
|
|
||||||
BIN
app/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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<>();
|
||||||
|
|
|
||||||
|
|
@ -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'){
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 3 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 9 KiB |
|
Before Width: | Height: | Size: 15 KiB |
4
app/src/main/res/values-night/colors.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="icon_bg">@android:color/background_dark</color>
|
||||||
|
</resources>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||