1
0
Fork 0
mirror of https://github.com/gsantner/dandelion synced 2024-11-29 15:52:11 +01:00

Compare commits

...

5 commits

Author SHA1 Message Date
Gregor Santner
88a4bd75b7 [ci skip] Crowdin translation bot: New translations for Sinhala 2021-02-28 22:52:54 +01:00
Gregor Santner
b15c39b35b [ci skip] Crowdin translation bot: New translations for Sinhala 2021-02-28 22:11:24 +01:00
Gregor Santner
c9c10a6fd4
Add language Sinhala (Sri Lanka) 2021-02-28 22:09:03 +01:00
Gregor Santner
e5866ffb2b
Update opoc 2021-01-18 21:32:50 +01:00
Gregor Santner
97d9bf434e
Various additions & improvements to opoc utils 2021-01-12 20:23:10 +01:00
9 changed files with 212 additions and 57 deletions

View file

@ -26,6 +26,7 @@ import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@ -75,7 +76,7 @@ public class SearchOrCustomTextDialog {
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
public int gravity = Gravity.NO_GRAVITY;
public int searchInputType = 0;
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
public boolean searchIsRegex = false;
public Callback.a1<Spannable> highlighter;
public String extraFilter = null;
@ -99,21 +100,20 @@ public class SearchOrCustomTextDialog {
}
private static class WithPositionAdapter extends ArrayAdapter<Pair<String, Integer>> {
@LayoutRes
final int _layout;
final LayoutInflater _inflater;
final DialogOptions _dopt;
final List<Pair<String, Integer>> _filteredItems;
final Pattern _extraPattern;
final LayoutInflater mInflater;
final @LayoutRes
int mLayout;
final DialogOptions dopt;
final List<Pair<String, Integer>> filteredItems;
final Pattern extraPattern;
WithPositionAdapter(Context context, @LayoutRes int layout, List<Pair<String, Integer>> filteredItems, DialogOptions dopt) {
super(context, layout, filteredItems);
mInflater = LayoutInflater.from(context);
mLayout = layout;
this.dopt = dopt;
this.filteredItems = filteredItems;
extraPattern = dopt.extraFilter == null ? null : Pattern.compile(dopt.extraFilter);
WithPositionAdapter(Context c_context, @LayoutRes int c_layout, List<Pair<String, Integer>> c_filteredItems, DialogOptions c_dopt) {
super(c_context, c_layout, c_filteredItems);
_inflater = LayoutInflater.from(c_context);
_layout = c_layout;
_dopt = c_dopt;
_filteredItems = c_filteredItems;
_extraPattern = (c_dopt.extraFilter == null ? null : Pattern.compile(c_dopt.extraFilter));
}
@NonNull
@ -125,30 +125,30 @@ public class SearchOrCustomTextDialog {
final TextView textView;
if (convertView == null) {
textView = (TextView) mInflater.inflate(mLayout, parent, false);
textView = (TextView) _inflater.inflate(_layout, parent, false);
} else {
textView = (TextView) convertView;
}
if (posInOriginalList >= 0 && dopt.iconsForData != null && posInOriginalList < dopt.iconsForData.size() && dopt.iconsForData.get(posInOriginalList) != 0) {
textView.setCompoundDrawablesWithIntrinsicBounds(dopt.iconsForData.get(posInOriginalList), 0, 0, 0);
if (posInOriginalList >= 0 && _dopt.iconsForData != null && posInOriginalList < _dopt.iconsForData.size() && _dopt.iconsForData.get(posInOriginalList) != 0) {
textView.setCompoundDrawablesWithIntrinsicBounds(_dopt.iconsForData.get(posInOriginalList), 0, 0, 0);
textView.setCompoundDrawablePadding(32);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
textView.setCompoundDrawableTintList(ColorStateList.valueOf(dopt.isDarkDialog ? Color.WHITE : Color.BLACK));
textView.setCompoundDrawableTintList(ColorStateList.valueOf(_dopt.isDarkDialog ? Color.WHITE : Color.BLACK));
}
} else {
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
if (dopt.highlightData != null) {
final boolean hl = dopt.highlightData.contains(text);
textView.setTextColor(hl ? dopt.highlightColor : dopt.textColor);
if (_dopt.highlightData != null) {
final boolean hl = _dopt.highlightData.contains(text);
textView.setTextColor(hl ? _dopt.highlightColor : _dopt.textColor);
textView.setTypeface(null, hl ? Typeface.BOLD : Typeface.NORMAL);
}
if (dopt.highlighter != null) {
if (_dopt.highlighter != null) {
Spannable s = new SpannableString(text);
dopt.highlighter.callback(s);
_dopt.highlighter.callback(s);
textView.setText(s);
} else {
textView.setText(text);
@ -163,8 +163,8 @@ public class SearchOrCustomTextDialog {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(final CharSequence constraint, final FilterResults results) {
filteredItems.clear();
filteredItems.addAll((List<Pair<String, Integer>>) results.values);
_filteredItems.clear();
_filteredItems.addAll((List<Pair<String, Integer>>) results.values);
notifyDataSetChanged();
}
@ -172,14 +172,14 @@ public class SearchOrCustomTextDialog {
protected FilterResults performFiltering(final CharSequence constraint) {
final ArrayList<Pair<CharSequence, Integer>> resList = new ArrayList<>();
if (dopt.data != null) {
if (_dopt.data != null) {
final String fil = constraint.toString();
final boolean emptySearch = fil.isEmpty();
for (int i = 0; i < dopt.data.size(); i++) {
final CharSequence str = dopt.data.get(i);
final boolean matchExtra = (extraPattern == null) || extraPattern.matcher(str).find();
for (int i = 0; i < _dopt.data.size(); i++) {
final CharSequence str = _dopt.data.get(i);
final boolean matchExtra = (_extraPattern == null) || _extraPattern.matcher(str).find();
final boolean matchNormal = str.toString().toLowerCase(Locale.getDefault()).contains(fil.toLowerCase(Locale.getDefault()));
final boolean matchRegex = dopt.searchIsRegex && (str.toString().matches(fil));
final boolean matchRegex = _dopt.searchIsRegex && (str.toString().matches(fil));
if (matchExtra && (matchNormal || matchRegex || emptySearch)) {
resList.add(new Pair<>(str, i));
}

View file

@ -11,6 +11,7 @@
package net.gsantner.opoc.util;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@ -38,8 +39,10 @@ import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.widget.ScrollView;
import java.util.List;
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection"})
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "rawtypes", "UnusedReturnValue"})
public class ActivityUtils extends net.gsantner.opoc.util.ContextUtils {
//########################
//## Members, Constructors
@ -239,13 +242,22 @@ public class ActivityUtils extends net.gsantner.opoc.util.ContextUtils {
}
public ActivityUtils setLauncherActivityEnabled(Class activityClass, boolean enable) {
Context context = _context.getApplicationContext();
PackageManager pkg = context.getPackageManager();
ComponentName component = new ComponentName(context, activityClass);
pkg.setComponentEnabledSetting(component, enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
try {
ComponentName component = new ComponentName(_context, activityClass);
_context.getPackageManager().setComponentEnabledSetting(component, enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
} catch (Exception ignored) {
}
return this;
}
public boolean isLauncherEnabled(Class activityClass) {
try {
ComponentName component = new ComponentName(_context, activityClass);
return _context.getPackageManager().getComponentEnabledSetting(component) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
} catch (Exception ignored) {
}
return false;
}
@ColorInt
public Integer getCurrentPrimaryColor() {
@ -316,4 +328,20 @@ public class ActivityUtils extends net.gsantner.opoc.util.ContextUtils {
} catch (Exception ignored) {
}
}
// Make activity/app not show up in the recents history - call before finish / System.exit
public ActivityUtils removeActivityFromHistory() {
try {
ActivityManager am = (ActivityManager) _activity.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
List<ActivityManager.AppTask> tasks = am.getAppTasks();
if (tasks != null && !tasks.isEmpty()) {
tasks.get(0).setExcludeFromRecents(true);
}
}
} catch (Exception ignored) {
}
return this;
}
}

View file

@ -46,8 +46,9 @@ import java.util.Set;
/**
* Simple Host-Based AdBlocker
*/
@SuppressWarnings({"WeakerAccess", "SpellCheckingInspection", "unused"})
@SuppressWarnings({"WeakerAccess", "SpellCheckingInspection", "unused", "TryFinallyCanBeTryWithResources"})
public class AdBlock {
private static final Object synchronizeObj = new Object();
private static final AdBlock instance = new AdBlock();
public static AdBlock getInstance() {
@ -61,7 +62,9 @@ public class AdBlock {
//########################
private final Set<String> _adblockHostsFromRaw = new HashSet<>();
private final Set<String> _adblockHosts = new HashSet<>();
private boolean _isLoaded;
private final List<Callback.b3<URI, String, String>> _customBlockCallbacks = new ArrayList<>();
private boolean _isLoaded = false;
private boolean _isAdblockLogging = false;
//########################
//##
@ -72,25 +75,47 @@ public class AdBlock {
}
public boolean isAdHost(String urlS) {
boolean block = false;
if (urlS != null && !urlS.isEmpty() && urlS.startsWith("http")) {
try {
URI url = new URI(urlS);
URI url;
try {
url = new URI(urlS);
} catch (Exception e) {
url = new URI(urlS.replaceFirst("[?].*", ""));
}
String host = url.getHost().trim();
if (host.startsWith("www.") && host.length() >= 4) {
host = host.substring(4);
}
return _adblockHosts.contains(host) || _adblockHosts.contains("www." + host);
block = _adblockHosts.contains(host) || _adblockHosts.contains("www." + host);
for (Callback.b3<URI, String, String> cb : _customBlockCallbacks) {
if (block) {
break;
}
try {
block = cb.callback(url, urlS, host);
} catch (Exception ignored) {
}
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return false;
if (_isAdblockLogging) {
Log.d(getClass().getSimpleName(), "UrlAllowed-" + (block ? "N" : "Y") + " " + urlS);
}
return block;
}
public AdBlock reset() {
synchronized (synchronizeObj) {
_adblockHosts.clear();
_adblockHosts.addAll(_adblockHostsFromRaw);
_customBlockCallbacks.clear();
}
return this;
}
@ -102,7 +127,7 @@ public class AdBlock {
return new WebResourceResponse("text/plain", "utf-8", new ByteArrayInputStream("".getBytes()));
}
public void addBlockedHosts(String... hosts) {
public AdBlock addBlockedHosts(String... hosts) {
for (String host : hosts) {
if (host != null) {
host = host.trim();
@ -110,24 +135,30 @@ public class AdBlock {
host = host.substring(4);
}
if (!host.startsWith("#") && !host.startsWith("\"")) {
synchronized (synchronizeObj) {
_adblockHosts.add(host);
}
}
}
}
return this;
}
public void loadHostsFromRawAssetsAsync(final Context context) {
new Thread(new Runnable() {
@Override
public void run() {
public void loadHostsFromRawAssetsAsync(final Context context, final boolean... debugIgnoreAssets) {
if (debugIgnoreAssets != null && debugIgnoreAssets.length > 0 && debugIgnoreAssets[0]) {
_isLoaded = true;
return;
}
new Thread(() -> {
try {
synchronized (synchronizeObj) {
loadHostsFromRawAssets(context);
_isLoaded = true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@ -172,4 +203,17 @@ public class AdBlock {
}
return adblockResIds;
}
// URI uri, String url, String host
public AdBlock addCustomBlockCallback(Callback.b3<URI, String, String> cb) {
synchronized (synchronizeObj) {
_customBlockCallbacks.add(cb);
}
return this;
}
public AdBlock setLogEnabled(boolean isAdblockLogging) {
_isAdblockLogging = isAdblockLogging;
return this;
}
}

View file

@ -67,7 +67,9 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.ImageView;
import android.widget.TextView;
@ -90,7 +92,7 @@ import static android.content.Context.VIBRATOR_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.graphics.Bitmap.CompressFormat;
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "ObsoleteSdkInt", "deprecation", "SpellCheckingInspection", "TryFinallyCanBeTryWithResources", "UnusedAssignment"})
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "ObsoleteSdkInt", "deprecation", "SpellCheckingInspection", "TryFinallyCanBeTryWithResources", "UnusedAssignment", "UnusedReturnValue"})
public class ContextUtils {
//
// Members, Constructors
@ -257,7 +259,7 @@ public class ContextUtils {
* Send a {@link Intent#ACTION_VIEW} Intent with given paramter
* If the parameter is an string a browser will get triggered
*/
public void openWebpageInExternalBrowser(final String url) {
public ContextUtils openWebpageInExternalBrowser(final String url) {
try {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
@ -266,6 +268,7 @@ public class ContextUtils {
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
@ -1011,6 +1014,25 @@ public class ContextUtils {
vibrator.vibrate(ms_v);
}
}
/*
Check if Wifi is connected. Requires these permissions in AndroidManifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
*/
@SuppressLint("MissingPermission")
public boolean isWifiConnected(boolean... enabledOnly) {
final boolean doEnabledCheckOnly = enabledOnly != null && enabledOnly.length > 0 && enabledOnly[0];
final ConnectivityManager connectivityManager = (ConnectivityManager) _context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return wifiInfo != null && (doEnabledCheckOnly ? wifiInfo.isAvailable() : wifiInfo.isConnected());
}
// Returns if the device is currently in portrait orientation (landscape=false)
public boolean isDeviceOrientationPortrait() {
final int rotation = ((WindowManager) _context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
return (rotation == Surface.ROTATION_0) || (rotation == Surface.ROTATION_180);
}
}

View file

@ -501,4 +501,11 @@ public class FileUtils {
return String.format(Locale.getDefault(), "%.2f%s", (bytes / 1000000000f), "TB");
}
}
public static File join(File file, String... childSegments) {
for (final String s : childSegments != null ? childSegments : new String[0]) {
file = new File(file, s);
}
return file;
}
}

View file

@ -24,7 +24,6 @@ import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@ -222,4 +221,14 @@ public class NetworkUtils {
return result;
}
public static void httpGetAsync(final String url, final Callback.a1<String> callback) {
new Thread(() -> {
try {
String c = NetworkUtils.performCall(url, GET);
callback.callback(c);
} catch (Exception ignored) {
}
}).start();
}
}

View file

@ -1148,7 +1148,7 @@ public class ShareUtil {
if (isDirectory) {
// Nothing to do
} else {
pfd = _context.getContentResolver().openFileDescriptor(dof.getUri(), "rw");
pfd = _context.getContentResolver().openFileDescriptor(dof.getUri(), "rwt");
fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
}
}

View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Application -->
<string name="close">වසන්න</string>
<string name="cancel">අවලංගු</string>
<!-- Common Words -->
<string name="settings">සැකසුම්</string>
<string name="notifications">දැනුම්දීම්</string>
<string name="conversations">සංවාද</string>
<string name="profile">පැතිකඩ</string>
<string name="search">සොයන්න</string>
<!-- Notifications dropdown menu -->
<!-- Pod Activity -->
<!-- Drawer, Menu, Toolbar, ContextMenu -->
<!-- More from MainActivity -->
<!-- Permissions -->
<string name="protocol">කෙටුම්පත</string>
<!-- Operability -->
<!-- Category Titles -->
<string name="network">ජාලය</string>
<!-- Visuals -->
<!-- Navigiation Slider -->
<string name="user">පරිශීලක</string>
<!-- Themes -->
<!-- Notifications dropdown -->
<string name="language">භාෂාව</string>
<!-- Font size -->
<string name="normal">සාමාන්‍ය</string>
<!-- Load images -->
<!-- Screen rotation -->
<!-- Proxy -->
<string name="proxy">පෙරකලාසිය</string>
<string name="enable_proxy">පෙරකලාසිය සබල කරන්න</string>
<!-- Chrome custom tabs -->
<!-- Diaspora Settings -->
<string name="change_account">ගිණුම වෙනස් කරන්න</string>
<!-- More -->
<string name="about">පිලිබඳව</string>
<string name="license">බලපත්‍රය</string>
<string name="application">යෙදුම</string>
<string name="device">උපාංගය</string>
<!-- License & help (large amount of text) -->
<string name="donate">පරිත්‍යාග</string>
</resources>

View file

@ -57,4 +57,5 @@ files:
ta: ta # Tamil (Asian)
sq: sq # Albanian
mk: mk # Macedonian
si-LK: si # Sinhala (Sri Lanka)
translate_attributes: 0