package org.mian.gitnex.helpers; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.util.Base64; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; import androidx.annotation.ColorInt; import androidx.core.content.pm.PackageInfoCompat; import org.mian.gitnex.database.models.UserAccount; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Author M M Arif */ public class AppUtil { public enum FileType { IMAGE, AUDIO, VIDEO, DOCUMENT, TEXT, EXECUTABLE, UNKNOWN } private static final HashMap extensions = new HashMap<>(); // AppUtil should not be instantiated. private AppUtil() {} static { extensions.put(new String[]{"jpg", "jpeg", "gif", "png", "ico", "tif", "tiff", "bmp"}, FileType.IMAGE); extensions.put(new String[]{"mp3", "wav", "opus", "flac", "wma", "aac", "m4a", "oga", "mpc", "ogg"}, FileType.AUDIO); extensions.put(new String[]{"mp4", "mkv", "avi", "mov", "wmv", "qt", "mts", "m2ts", "webm", "flv", "ogv", "amv", "mpg", "mpeg", "mpv", "m4v", "3gp", "wmv"}, FileType.VIDEO); extensions.put(new String[]{"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "odg", "otg", "odp", "otp", "bin", "psd", "xcf", "pdf"}, FileType.DOCUMENT); extensions.put(new String[]{"exe", "msi", "jar", "dmg", "deb", "apk"}, FileType.EXECUTABLE); extensions.put(new String[]{"txt", "md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam", "hx", "ts", "kt", "kts"}, FileType.TEXT); } public static FileType getFileType(String extension) { if(extension != null && !extension.isEmpty()) { for(String[] testExtensions : extensions.keySet()) { for(String testExtension : testExtensions) { if(testExtension.equalsIgnoreCase(extension)) return extensions.get(testExtensions); } } } return FileType.UNKNOWN; } public static boolean hasNetworkConnection(Context context) { return NetworkStatusObserver.getInstance(context).hasNetworkConnection(); } public static void copyProgress(InputStream inputStream, OutputStream outputStream, long totalSize, ProgressListener progressListener) throws IOException { byte[] buffer = new byte[4096]; int read; long totalSteps = (long) Math.ceil((double) totalSize / buffer.length); long stepsPerPercent = (long) Math.floor((double) totalSteps / 100); short percent = 0; long stepCount = 0; progressListener.onActionStarted(); while((read = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, read); stepCount++; if(stepCount == stepsPerPercent) { percent++; if(percent <= 100) progressListener.onProgressChanged(percent); stepCount = 0; } } if(percent < 100) { progressListener.onProgressChanged((short) 100); } progressListener.onActionFinished(); } public interface ProgressListener { default void onActionStarted() {} default void onActionFinished() {} void onProgressChanged(short progress); } public static int getAppBuildNo(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return (int) PackageInfoCompat.getLongVersionCode(packageInfo); } catch(PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get package name: " + e); } } public static String getAppVersion(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return packageInfo.versionName; } catch(PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get package name: " + e); } } public static boolean isPro(Context context) { return context.getPackageName().equals("org.mian.gitnex.pro"); } public static Boolean checkStringsWithAlphaNumeric(String str) { // [a-zA-Z0-9] return str.matches("^[\\w]+$"); } public static Boolean checkStrings(String str) { // [a-zA-Z0-9-_. ] return str.matches("^[\\w .-]+$"); } public static Boolean checkStringsWithAlphaNumericDashDotUnderscore(String str) { // [a-zA-Z0-9-_] return str.matches("^[\\w.-]+$"); } public static Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ] return str.matches("^[\\w-]+$"); } public static Boolean checkIntegers(String str) { return str.matches("\\d+"); } public int getResponseStatusCode(String u) throws Exception { URL url = new URL(u); HttpURLConnection http = (HttpURLConnection) url.openConnection(); return (http.getResponseCode()); } public static void setAppLocale(Resources resource, String locCode) { DisplayMetrics dm = resource.getDisplayMetrics(); Configuration config = resource.getConfiguration(); config.setLocale(new Locale(locCode.toLowerCase())); resource.updateConfiguration(config, dm); } public static String getTimestampFromDate(Context context, Date date) { TinyDB tinyDB = TinyDB.getInstance(context); Locale locale = new Locale(tinyDB.getString("locale")); return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", locale).format(date); } @ColorInt public static int getColorFromAttribute(Context context, int resid) { TypedValue typedValue = new TypedValue(); context.getTheme().resolveAttribute(resid, typedValue, true); return typedValue.data; } public static String customDateFormat(String customDate) { String[] parts = customDate.split("-"); final String year = parts[0]; final String month = parts[1]; final String day = parts[2]; String sMonth; if(Integer.parseInt(month) < 10) { sMonth = "0" + month; } else { sMonth = month; } String sDay; if(Integer.parseInt(day) < 10) { sDay = "0" + day; } else { sDay = day; } return year + "-" + sMonth + "-" + sDay; } public static String customDateCombine(String customDate) { final Calendar c = Calendar.getInstance(); int mHour = c.get(Calendar.HOUR_OF_DAY); int mMinute = c.get(Calendar.MINUTE); int mSeconds = c.get(Calendar.SECOND); String sMin; if((mMinute) < 10) { sMin = "0" + mMinute; } else { sMin = String.valueOf(mMinute); } String sSec; if((mSeconds) < 10) { sSec = "0" + mSeconds; } else { sSec = String.valueOf(mSeconds); } return (customDate + "T" + mHour + ":" + sMin + ":" + sSec + "Z"); } public static String encodeBase64(String str) { String base64Str = str; if(!str.equals("")) { byte[] data = str.getBytes(StandardCharsets.UTF_8); base64Str = Base64.encodeToString(data, Base64.DEFAULT); } return base64Str; } public static String decodeBase64(String str) { String base64Str = str; if(!str.equals("")) { byte[] data = Base64.decode(base64Str, Base64.DEFAULT); base64Str = new String(data, StandardCharsets.UTF_8); } return base64Str; } public static String getLastCharactersOfWord(String str, int count) { return str.substring(str.length() - count); } public static void setMultiVisibility(int visibility, View... views) { for(View view : views) { view.setVisibility(visibility); } } public static int getPixelsFromDensity(Context context, int dp) { return (int) (context.getResources().getDisplayMetrics().density * dp); } public static int getPixelsFromScaledDensity(Context context, int sp) { return (int) (context.getResources().getDisplayMetrics().scaledDensity * sp); } public static long getLineCount(String s) { long lines = 0; Pattern pattern = Pattern.compile("(\r\n|\r|\n)"); Matcher matcher = pattern.matcher(s); while(matcher.find()) lines++; // Sometimes there may be text, but no line breaks. // This should still count as one line. if(s.length() > 0 && lines == 0) return 1; return lines; } public static void copyToClipboard(Context ctx, CharSequence data, String message) { ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); assert clipboard != null; ClipData clip = ClipData.newPlainText(data, data); clipboard.setPrimaryClip(clip); Toasty.info(ctx, message); } public static boolean switchToAccount(Context context, UserAccount userAccount) { TinyDB tinyDB = TinyDB.getInstance(context); if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) { tinyDB.putString("loginUid", userAccount.getUserName()); tinyDB.putString("userLogin", userAccount.getUserName()); tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken()); tinyDB.putString("instanceUrl", userAccount.getInstanceUrl()); tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId()); return true; } return false; } }