Merge branch 'develop' into master

# Conflicts:
#	app/build.gradle
This commit is contained in:
Thomas 2020-09-09 18:39:02 +02:00
commit 6a8a8e681a
21 changed files with 483 additions and 603 deletions

View File

@ -1,13 +1,13 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 29
versionCode 22
versionName "1.13.0"
targetSdkVersion 30
versionCode 23
versionName "1.14.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
@ -49,13 +49,14 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'org.jsoup:jsoup:1.13.1'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}

View File

@ -19,10 +19,10 @@
tools:replace="android:label,android:icon,android:roundIcon">
<activity
tools:replace="android:label"
android:name=".activities.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
android:theme="@style/AppTheme.NoActionBar"
tools:replace="android:label">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -32,8 +32,8 @@
<activity-alias
android:name=".activities.TransformActivity"
android:noHistory="true"
android:theme="@style/Theme.AppCompat.Translucent"
android:targetActivity=".activities.TransformActivity">
android:targetActivity=".activities.TransformActivity"
android:theme="@style/Theme.AppCompat.Translucent">
<!-- The app should handle these domains, more can be added here -->
<intent-filter>
@ -75,7 +75,6 @@
<!-- INVIDIOUS INSTANCES -->
<data android:host="invidio.us" />
<data android:host="invidious.snopyta.org" />
<data android:host="invidiou.sh" />
<data android:host="invidious.toot.koeln" />
@ -142,7 +141,6 @@
<data android:host="youtube-nocookie.com" />
<data android:host="*" />
<data android:mimeType="text/plain" />
@ -196,44 +194,44 @@
<activity-alias
android:name=".activities.AppsPickerActivity"
android:noHistory="true"
android:theme="@style/Theme.AppCompat.Translucent"
android:targetActivity=".activities.AppsPickerActivity" />
android:targetActivity=".activities.AppsPickerActivity"
android:theme="@style/Theme.AppCompat.Translucent" />
<activity-alias
android:name=".activities.InstanceActivity"
android:excludeFromRecents="true"
android:theme="@style/AppThemeDialog"
android:targetActivity=".activities.InstanceActivity" />
android:targetActivity=".activities.InstanceActivity"
android:theme="@style/AppThemeDialog" />
<activity-alias
android:name=".activities.AboutActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:targetActivity=".activities.AboutActivity" />
android:targetActivity=".activities.AboutActivity"
android:theme="@style/AppTheme" />
<activity-alias
android:name=".activities.CheckAppActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:targetActivity=".activities.CheckAppActivity" />
android:targetActivity=".activities.CheckAppActivity"
android:theme="@style/AppTheme" />
<activity-alias
android:name=".activities.DefaultAppActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:targetActivity=".activities.DefaultAppActivity" />
android:targetActivity=".activities.DefaultAppActivity"
android:theme="@style/AppTheme" />
<activity-alias
android:name=".activities.InvidiousSettingsActivity"
android:configChanges="orientation|screenSize"
android:label="@string/invidious_settings"
android:theme="@style/AppTheme"
android:targetActivity=".activities.InvidiousSettingsActivity" />
android:targetActivity=".activities.InvidiousSettingsActivity"
android:theme="@style/AppTheme" />
<activity-alias
android:name=".activities.WebviewPlayerActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/AppTheme"
android:targetActivity=".activities.WebviewPlayerActivity" />
android:targetActivity=".activities.WebviewPlayerActivity"
android:theme="@style/AppTheme" />
</application>
</manifest>

View File

@ -8,7 +8,6 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
tools:node="replace"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher_lite"
android:label="@string/app_name_lite"
@ -16,7 +15,8 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"
tools:node="replace">
<activity
android:name=".activities.MainActivity"

View File

@ -14,10 +14,7 @@ package app.fedilab.nitterizeme.activities;
* You should have received a copy of the GNU General Public License along with UntrackMe; if not,
* see <http://www.gnu.org/licenses>. */
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
@ -28,34 +25,18 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import app.fedilab.nitterizeme.R;
import app.fedilab.nitterizeme.adapters.InstanceAdapter;
import app.fedilab.nitterizeme.entities.Instance;
import static app.fedilab.nitterizeme.activities.MainActivity.APP_PREFS;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_BIBLIOGRAM_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_INVIDIOUS_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_NITTER_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_BIBLIOGRAM_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_INVIDIOUS_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_HOST;
import app.fedilab.nitterizeme.viewmodels.SearchInstanceVM;
public class InstanceActivity extends AppCompatActivity {
@ -66,168 +47,78 @@ public class InstanceActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup_instance);
new SearchInstances(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
setTitle(R.string.select_instances);
}
static class SearchInstances extends AsyncTask<Void, Void, String> {
private WeakReference<Activity> activityWeakReference;
SearchInstances(Activity activity) {
activityWeakReference = new WeakReference<>(activity);
}
@Override
protected String doInBackground(Void... voids) {
HttpsURLConnection httpsURLConnection;
try {
String instances_url = "https://fedilab.app/untrackme_instances/payload_2.json";
URL url = new URL(instances_url);
httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setConnectTimeout(10 * 1000);
httpsURLConnection.setRequestProperty("http.keepAlive", "false");
httpsURLConnection.setRequestProperty("Content-Type", "application/json");
httpsURLConnection.setRequestProperty("Accept", "application/json");
httpsURLConnection.setRequestMethod("GET");
httpsURLConnection.setDefaultUseCaches(true);
httpsURLConnection.setUseCaches(true);
String response = null;
if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
java.util.Scanner s = new java.util.Scanner(httpsURLConnection.getInputStream()).useDelimiter("\\A");
response = s.hasNext() ? s.next() : "";
}
httpsURLConnection.getInputStream().close();
return response;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
Activity activity = activityWeakReference.get();
LinearLayout instance_container = activity.findViewById(R.id.instance_container);
RelativeLayout loader = activity.findViewById(R.id.loader);
RecyclerView invidious_instances = activity.findViewById(R.id.invidious_instances);
RecyclerView nitter_instances = activity.findViewById(R.id.nitter_instances);
RecyclerView bibliogram_instances = activity.findViewById(R.id.bibliogram_instances);
Button latency_test = activity.findViewById(R.id.latency_test);
ImageButton instance_info = activity.findViewById(R.id.instance_info);
Button close = activity.findViewById(R.id.close);
SearchInstanceVM viewModel = new ViewModelProvider(this).get(SearchInstanceVM.class);
viewModel.getInstances().observe(this, result -> {
LinearLayout instance_container = findViewById(R.id.instance_container);
RelativeLayout loader = findViewById(R.id.loader);
RecyclerView invidious_instances = findViewById(R.id.invidious_instances);
RecyclerView nitter_instances = findViewById(R.id.nitter_instances);
RecyclerView bibliogram_instances = findViewById(R.id.bibliogram_instances);
Button latency_test = findViewById(R.id.latency_test);
ImageButton instance_info = findViewById(R.id.instance_info);
Button close = findViewById(R.id.close);
if (result == null) {
View parentLayout = activity.findViewById(android.R.id.content);
Snackbar.make(parentLayout, R.string.error_message_internet, Snackbar.LENGTH_LONG).setAction(R.string.close, v -> activity.finish()).show();
View parentLayout = findViewById(android.R.id.content);
Snackbar.make(parentLayout, R.string.error_message_internet, Snackbar.LENGTH_LONG).setAction(R.string.close, v -> finish()).show();
return;
}
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArrayInvidious = jsonObject.getJSONArray("invidious");
JSONArray jsonArrayNitter = jsonObject.getJSONArray("nitter");
JSONArray jsonArrayBibliogram = jsonObject.getJSONArray("bibliogram");
SharedPreferences sharedpreferences = activity.getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
String defaultInvidious = sharedpreferences.getString(SET_INVIDIOUS_HOST, DEFAULT_INVIDIOUS_HOST);
String defaultNitter = sharedpreferences.getString(SET_NITTER_HOST, DEFAULT_NITTER_HOST);
String defaultBibliogram = sharedpreferences.getString(SET_BIBLIOGRAM_HOST, DEFAULT_BIBLIOGRAM_HOST);
List<Instance> invidiousInstances = new ArrayList<>();
for (int i = 0; i < jsonArrayInvidious.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayInvidious.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayInvidious.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayInvidious.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
if (domain.compareTo(defaultInvidious) == 0) {
instance.setChecked(true);
}
instance.setType(Instance.instanceType.INVIDIOUS);
ArrayList<Instance> invidiousInstances = new ArrayList<>();
ArrayList<Instance> nitterInstances = new ArrayList<>();
ArrayList<Instance> bibliogramInstances = new ArrayList<>();
for (Instance instance : result) {
if (instance.getType() == Instance.instanceType.INVIDIOUS) {
invidiousInstances.add(instance);
}
List<Instance> nitterInstances = new ArrayList<>();
for (int i = 0; i < jsonArrayNitter.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayNitter.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayNitter.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayNitter.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
if (domain.compareTo(defaultNitter) == 0) {
instance.setChecked(true);
}
instance.setType(Instance.instanceType.NITTER);
} else if (instance.getType() == Instance.instanceType.NITTER) {
nitterInstances.add(instance);
}
List<Instance> bibliogramInstances = new ArrayList<>();
for (int i = 0; i < jsonArrayBibliogram.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayBibliogram.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayBibliogram.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayBibliogram.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
if (domain.compareTo(defaultBibliogram) == 0) {
instance.setChecked(true);
}
instance.setType(Instance.instanceType.BIBLIOGRAM);
} else if (instance.getType() == Instance.instanceType.BIBLIOGRAM) {
bibliogramInstances.add(instance);
}
final LinearLayoutManager iLayoutManager = new LinearLayoutManager(activity);
InstanceAdapter invidiousAdapter = new InstanceAdapter(invidiousInstances);
invidious_instances.setAdapter(invidiousAdapter);
invidious_instances.setLayoutManager(iLayoutManager);
invidious_instances.setNestedScrollingEnabled(false);
final LinearLayoutManager nLayoutManager = new LinearLayoutManager(activity);
InstanceAdapter nitterAdapter = new InstanceAdapter(nitterInstances);
nitter_instances.setAdapter(nitterAdapter);
nitter_instances.setLayoutManager(nLayoutManager);
nitter_instances.setNestedScrollingEnabled(false);
final LinearLayoutManager bLayoutManager = new LinearLayoutManager(activity);
InstanceAdapter bibliogramAdapter = new InstanceAdapter(bibliogramInstances);
bibliogram_instances.setAdapter(bibliogramAdapter);
bibliogram_instances.setLayoutManager(bLayoutManager);
bibliogram_instances.setNestedScrollingEnabled(false);
latency_test.setOnClickListener(
v -> {
invidiousAdapter.evalLatency();
nitterAdapter.evalLatency();
bibliogramAdapter.evalLatency();
}
);
instance_info.setOnClickListener(v -> {
AlertDialog.Builder instanceInfo = new AlertDialog.Builder(activity);
instanceInfo.setTitle(R.string.about_instances_title);
View view = activity.getLayoutInflater().inflate(R.layout.popup_instance_info, new LinearLayout(activity.getApplicationContext()), false);
instanceInfo.setView(view);
TextView infoInstancesTextview = view.findViewById(R.id.info_instances);
infoInstancesTextview.setText(activity.getString(R.string.about_instances, list_for_instances, list_for_instances));
instanceInfo.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
AlertDialog alertDialog = instanceInfo.create();
alertDialog.show();
});
} catch (JSONException e) {
e.printStackTrace();
}
final LinearLayoutManager iLayoutManager = new LinearLayoutManager(this);
InstanceAdapter invidiousAdapter = new InstanceAdapter(invidiousInstances);
invidious_instances.setAdapter(invidiousAdapter);
invidious_instances.setLayoutManager(iLayoutManager);
invidious_instances.setNestedScrollingEnabled(false);
close.setOnClickListener(v -> activity.finish());
final LinearLayoutManager nLayoutManager = new LinearLayoutManager(this);
InstanceAdapter nitterAdapter = new InstanceAdapter(nitterInstances);
nitter_instances.setAdapter(nitterAdapter);
nitter_instances.setLayoutManager(nLayoutManager);
nitter_instances.setNestedScrollingEnabled(false);
final LinearLayoutManager bLayoutManager = new LinearLayoutManager(this);
InstanceAdapter bibliogramAdapter = new InstanceAdapter(bibliogramInstances);
bibliogram_instances.setAdapter(bibliogramAdapter);
bibliogram_instances.setLayoutManager(bLayoutManager);
bibliogram_instances.setNestedScrollingEnabled(false);
latency_test.setOnClickListener(
v -> {
invidiousAdapter.evalLatency();
nitterAdapter.evalLatency();
bibliogramAdapter.evalLatency();
}
);
instance_info.setOnClickListener(v -> {
AlertDialog.Builder instanceInfo = new AlertDialog.Builder(this);
instanceInfo.setTitle(R.string.about_instances_title);
View view = getLayoutInflater().inflate(R.layout.popup_instance_info, new LinearLayout(getApplicationContext()), false);
instanceInfo.setView(view);
TextView infoInstancesTextview = view.findViewById(R.id.info_instances);
infoInstancesTextview.setText(getString(R.string.about_instances, list_for_instances, list_for_instances));
instanceInfo.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
AlertDialog alertDialog = instanceInfo.create();
alertDialog.show();
});
close.setOnClickListener(v -> finish());
instance_container.setVisibility(View.VISIBLE);
loader.setVisibility(View.GONE);
}
});
}
}

View File

@ -56,10 +56,10 @@ public class MainActivity extends AppCompatActivity {
public static final String SET_INVIDIOUS_HOST = "set_invidious_host";
public static final String SET_OSM_HOST = "set_osm_host";
public static final String SET_BIBLIOGRAM_HOST = "set_bibliogram_host";
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "RedundantSuppression"})
public static String TAG = "UntrackMe";
public static String DEFAULT_NITTER_HOST = "nitter.net";
public static String DEFAULT_INVIDIOUS_HOST = "invidio.us";
public static String DEFAULT_INVIDIOUS_HOST = "invidious.snopyta.org";
public static String SET_INVIDIOUS_ENABLED = "set_invidious_enabled";
public static String SET_NITTER_ENABLED = "set_nitter_enabled";
public static String SET_OSM_ENABLED = "set_osm_enabled";

View File

@ -15,19 +15,14 @@ package app.fedilab.nitterizeme.activities;
* see <http://www.gnu.org/licenses>. */
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Patterns;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Objects;
import java.util.regex.Matcher;
@ -36,30 +31,15 @@ import java.util.regex.Pattern;
import app.fedilab.nitterizeme.BuildConfig;
import app.fedilab.nitterizeme.helpers.Utils;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.bibliogram_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.instagram_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.invidious_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.nitter_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.outlook_safe_domain;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.shortener_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.twitter_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.youtube_domains;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_BIBLIOGRAM_ENABLED;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_INVIDIOUS_ENABLED;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_ENABLED;
import static app.fedilab.nitterizeme.helpers.Utils.KILL_ACTIVITY;
import static app.fedilab.nitterizeme.helpers.Utils.ampExtract;
import static app.fedilab.nitterizeme.helpers.Utils.bibliogramAccountPattern;
import static app.fedilab.nitterizeme.helpers.Utils.bibliogramPostPattern;
import static app.fedilab.nitterizeme.helpers.Utils.forwardToBrowser;
import static app.fedilab.nitterizeme.helpers.Utils.isRouted;
import static app.fedilab.nitterizeme.helpers.Utils.manageShortened;
import static app.fedilab.nitterizeme.helpers.Utils.manageShortenedShare;
import static app.fedilab.nitterizeme.helpers.Utils.maps;
import static app.fedilab.nitterizeme.helpers.Utils.nitterPattern;
import static app.fedilab.nitterizeme.helpers.Utils.outlookRedirect;
import static app.fedilab.nitterizeme.helpers.Utils.remove_tracking_param;
import static app.fedilab.nitterizeme.helpers.Utils.routerEnabledForHost;
import static app.fedilab.nitterizeme.helpers.Utils.transformUrl;
import static app.fedilab.nitterizeme.helpers.Utils.youtubePattern;
public class TransformActivity extends Activity {
@ -68,7 +48,6 @@ public class TransformActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedpreferences = getSharedPreferences(MainActivity.APP_PREFS, Context.MODE_PRIVATE);
Intent intent = getIntent();
if (intent != null && intent.getStringExtra("nitterizeme") != null) {
finish();
@ -80,6 +59,7 @@ public class TransformActivity extends Activity {
//Dealing with URLs
if (Objects.requireNonNull(intent.getAction()).equals(Intent.ACTION_VIEW)) {
String url = Objects.requireNonNull(intent.getData()).toString();
url = remove_tracking_param(url);
URL url_;
String host = null;
try {
@ -91,11 +71,9 @@ public class TransformActivity extends Activity {
//Shortened URLs
if (Arrays.asList(shortener_domains).contains(host)) {
manageShortened(TransformActivity.this, url);
}
//Twitter URLs
else if (Arrays.asList(twitter_domains).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
} else if (isRouted(url)) {
boolean routeEnabled = routerEnabledForHost(TransformActivity.this, url);
if (routeEnabled) {
Intent delegate = new Intent(Intent.ACTION_VIEW);
String transformedURL = transformUrl(TransformActivity.this, url);
if (transformedURL != null) {
@ -115,164 +93,6 @@ public class TransformActivity extends Activity {
} else {
forwardToBrowser(TransformActivity.this, intent);
}
} //Instagram URLs
else if (Arrays.asList(instagram_domains).contains(host)) {
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
Intent delegate = new Intent(Intent.ACTION_VIEW);
String transformedURL = transformUrl(TransformActivity.this, url);
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (BuildConfig.fullLinks) {
forwardToBrowser(TransformActivity.this, delegate);
} else {
if (delegate.resolveActivity(getPackageManager()) != null) {
startActivity(delegate);
finish();
}
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
}
//Maps URLs (containing /maps/place like Google Maps links)
else if (url.contains("/maps/place")) {
boolean osm_enabled = sharedpreferences.getBoolean(MainActivity.SET_OSM_ENABLED, true);
if (osm_enabled) {
Intent delegate = new Intent(Intent.ACTION_VIEW);
String transformedURL = transformUrl(TransformActivity.this, url);
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (BuildConfig.fullLinks) {
forwardToBrowser(TransformActivity.this, delegate);
} else {
if (delegate.resolveActivity(getPackageManager()) != null) {
startActivity(delegate);
finish();
}
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
}
//AMP URLs (containing /amp/s/ like Google AMP links)
else if (url.contains("/amp/s/")) {
Intent delegate = new Intent(Intent.ACTION_VIEW);
Matcher matcher = ampExtract.matcher(url);
String transformedURL = null;
while (matcher.find()) {
transformedURL = "https://" + matcher.group(1);
}
if (transformedURL != null) {
delegate.setData(Uri.parse(transformedURL));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (BuildConfig.fullLinks) {
forwardToBrowser(TransformActivity.this, delegate);
} else {
if (delegate.resolveActivity(getPackageManager()) != null) {
startActivity(delegate);
finish();
}
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
}
//YouTube URLs
else if (Arrays.asList(youtube_domains).contains(host)) { //Youtube URL
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
if (invidious_enabled) {
Intent delegate = new Intent(Intent.ACTION_VIEW);
String transformedURL = transformUrl(TransformActivity.this, url);
if (transformedURL != null) {
delegate.setData(Uri.parse(transformUrl(TransformActivity.this, url)));
delegate.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (BuildConfig.fullLinks) {
forwardToBrowser(TransformActivity.this, delegate);
} else {
if (delegate.resolveActivity(getPackageManager()) != null) {
startActivity(delegate);
finish();
}
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
} else {
forwardToBrowser(TransformActivity.this, intent);
}
}
//Transform an Invidious URL from an instance to another one selected by the end user.
else if (Arrays.asList(invidious_instances).contains(host)) {
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
if (invidious_enabled) {
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
String transformedURL = url;
if (host != null && host.compareTo(invidiousHost) != 0) {
if (!invidiousHost.startsWith("http")) {
transformedURL = url.replace(host, invidiousHost);
} else {
transformedURL = url.replace("https://" + host, invidiousHost).replace("http://" + host, invidiousHost);
}
}
transformedURL = Utils.replaceInvidiousParams(TransformActivity.this, transformedURL);
intent.setData(Uri.parse(transformedURL));
}
forwardToBrowser(TransformActivity.this, intent);
}
//Transform a Nitter URL from an instance to another one selected by the end user.
else if (Arrays.asList(nitter_instances).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
String transformedURL = url;
if (host != null && host.compareTo(nitterHost) != 0) {
if (!nitterHost.startsWith("http")) {
transformedURL = url.replace(host, nitterHost);
} else {
transformedURL = url.replace("https://" + host, nitterHost).replace("http://" + host, nitterHost);
}
}
intent.setData(Uri.parse(transformedURL));
}
forwardToBrowser(TransformActivity.this, intent);
}
//Transform a Bibliogram URL from an instance to another one selected by the end user.
else if (Arrays.asList(bibliogram_instances).contains(host)) {
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
String transformedURL = url;
if (host != null && host.compareTo(bibliogramHost) != 0) {
if (!bibliogramHost.startsWith("http")) {
transformedURL = url.replace(host, bibliogramHost);
} else {
transformedURL = url.replace("https://" + host, bibliogramHost).replace("http://" + host, bibliogramHost);
}
}
intent.setData(Uri.parse(transformedURL));
}
forwardToBrowser(TransformActivity.this, intent);
} else if (host != null && host.contains(outlook_safe_domain)) {
Matcher matcher = outlookRedirect.matcher(url);
if (matcher.find()) {
url = matcher.group(3);
try {
url = URLDecoder.decode(url, "UTF-8");
} catch (UnsupportedEncodingException ignored) {
}
}
intent.setData(Uri.parse(url));
forwardToBrowser(TransformActivity.this, intent);
} else {
String newUrl = remove_tracking_param(url);
try {
@ -309,7 +129,6 @@ public class TransformActivity extends Activity {
* @param extraText String the new extra text
*/
private void share(String extraText) {
SharedPreferences sharedpreferences = getSharedPreferences(MainActivity.APP_PREFS, Context.MODE_PRIVATE);
String url = null;
if (extraText != null) {
@ -326,15 +145,7 @@ public class TransformActivity extends Activity {
}
}
}
URL url_;
String host = null;
try {
url_ = new URL(url);
host = url_.getHost();
} catch (MalformedURLException e) {
e.printStackTrace();
}
String newUrl = null;
String newUrl;
if (url == null) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@ -343,156 +154,28 @@ public class TransformActivity extends Activity {
forwardToBrowser(TransformActivity.this, sendIntent);
return;
}
Uri url_r = Uri.parse(url);
String scheme = url_r.getScheme();
if (scheme == null) {
scheme = "https://";
} else {
scheme += "://";
url = Utils.remove_tracking_param(url);
URL url_;
String host = null;
try {
url_ = new URL(url);
host = url_.getHost();
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (Arrays.asList(twitter_domains).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
if (nitterHost.startsWith("http")) {
scheme = "";
}
assert host != null;
if (host.compareTo("pbs.twimg.com") == 0 || host.compareTo("pic.twitter.com") == 0) {
try {
newUrl = scheme + nitterHost + "/pic/" + URLEncoder.encode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
newUrl = scheme + nitterHost + "/pic/" + url;
}
} else if (url.contains("/search?")) {
newUrl = url.replace(host, nitterHost);
} else {
Matcher matcher = nitterPattern.matcher(url);
while (matcher.find()) {
final String nitter_directory = matcher.group(2);
newUrl = scheme + nitterHost + nitter_directory;
}
}
if (Arrays.asList(shortener_domains).contains(host)) {
Uri url_r = Uri.parse(url);
String scheme = url_r.getScheme();
if (scheme == null) {
scheme = "https://";
} else {
scheme += "://";
}
} else if (Arrays.asList(instagram_domains).contains(host)) {
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
if (bibliogramHost.startsWith("http")) {
scheme = "";
}
Matcher matcher = bibliogramPostPattern.matcher(url);
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
newUrl = scheme + bibliogramHost + bibliogram_directory;
}
matcher = bibliogramAccountPattern.matcher(url);
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
if (bibliogram_directory != null && bibliogram_directory.compareTo("privacy") != 0) {
newUrl = scheme + bibliogramHost + "/u" + bibliogram_directory;
} else {
newUrl = scheme + bibliogramHost + bibliogram_directory;
}
}
}
} else if (url.contains("/maps/place/")) {
boolean osm_enabled = sharedpreferences.getBoolean(MainActivity.SET_OSM_ENABLED, true);
if (osm_enabled) {
Matcher matcher = maps.matcher(url);
while (matcher.find()) {
final String localization = matcher.group(2);
assert localization != null;
String[] data = localization.split(",");
if (data.length > 2) {
String zoom;
String[] details = data[2].split("\\.");
if (details.length > 0) {
zoom = details[0];
} else {
zoom = data[2];
}
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
newUrl = scheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
}
}
}
} else if (url.contains("/amp/s/")) {
Matcher matcher = ampExtract.matcher(url);
while (matcher.find()) {
newUrl = scheme + matcher.group(1);
}
} else if (Arrays.asList(youtube_domains).contains(host)) { //Youtube URL
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
if (invidious_enabled) {
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
if (invidiousHost.startsWith("http")) {
scheme = "";
}
Matcher matcher = youtubePattern.matcher(url);
while (matcher.find()) {
final String youtubeId = matcher.group(3);
if (Objects.requireNonNull(matcher.group(2)).compareTo("youtu.be") == 0) {
newUrl = scheme + invidiousHost + "/watch?v=" + youtubeId;
} else {
newUrl = scheme + invidiousHost + "/" + youtubeId;
}
}
}
} else if (Arrays.asList(shortener_domains).contains(host)) {
manageShortenedShare(TransformActivity.this, url, extraText, scheme);
return;
} else if (Arrays.asList(invidious_instances).contains(host)) {
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
newUrl = url;
if (invidious_enabled) {
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
if (host != null && host.compareTo(invidiousHost) != 0) {
if (!invidiousHost.startsWith("http")) {
newUrl = url.replace(host, invidiousHost);
} else {
newUrl = url.replace("https://" + host, invidiousHost).replace("http://" + host, invidiousHost);
}
}
newUrl = Utils.replaceInvidiousParams(TransformActivity.this, newUrl);
}
}
//Transform a Nitter URL from an instance to another one selected by the end user.
else if (Arrays.asList(nitter_instances).contains(host)) {
newUrl = url;
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
if (host != null && host.compareTo(nitterHost) != 0) {
if (!nitterHost.startsWith("http")) {
newUrl = url.replace(host, nitterHost);
} else {
newUrl = url.replace("https://" + host, nitterHost).replace("http://" + host, nitterHost);
}
}
}
}
//Transform a Bibliogram URL from an instance to another one selected by the end user.
else if (Arrays.asList(bibliogram_instances).contains(host)) {
newUrl = url;
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
if (host != null && host.compareTo(bibliogramHost) != 0) {
if (!bibliogramHost.startsWith("http")) {
newUrl = url.replace(host, bibliogramHost);
} else {
newUrl = url.replace("https://" + host, bibliogramHost).replace("http://" + host, bibliogramHost);
}
}
}
} else {
newUrl = remove_tracking_param(url);
}
newUrl = transformUrl(TransformActivity.this, url);
if (newUrl != null) {
extraText = extraText.replaceAll(Pattern.quote(url), Matcher.quoteReplacement(newUrl));
}

View File

@ -36,7 +36,7 @@ import app.fedilab.nitterizeme.BuildConfig;
import app.fedilab.nitterizeme.R;
import app.fedilab.nitterizeme.entities.AppInfo;
public class AppInfoAdapter extends RecyclerView.Adapter {
public class AppInfoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int LAYOUT_TITLE = 0;
private static final int LAYOUT_INFO = 1;

View File

@ -37,7 +37,7 @@ import app.fedilab.nitterizeme.entities.DefaultApp;
import app.fedilab.nitterizeme.sqlite.DefaultAppDAO;
import app.fedilab.nitterizeme.sqlite.Sqlite;
public class DefaultAppAdapter extends RecyclerView.Adapter {
public class DefaultAppAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DefaultApp> defaultApps;

View File

@ -42,7 +42,7 @@ import static app.fedilab.nitterizeme.activities.MainActivity.SET_BIBLIOGRAM_HOS
import static app.fedilab.nitterizeme.activities.MainActivity.SET_INVIDIOUS_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_HOST;
public class InstanceAdapter extends RecyclerView.Adapter {
public class InstanceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Instance> instances;
private InstanceAdapter instanceAdapter;

View File

@ -30,6 +30,7 @@ public class InvidiousSettingsFragment extends PreferenceFragmentCompat implemen
setPreferencesFromResource(R.xml.preferences_invidious, rootKey);
SharedPreferences prefs = getPreferenceScreen().getSharedPreferences();
String volume_mode = prefs.getString(getString(R.string.invidious_volume_mode), "0");
assert volume_mode != null;
if (volume_mode.compareTo("0") == 0 || volume_mode.compareTo("-1") == 0) {
PreferenceCategory player_parameters = findPreference(getString(R.string.invidious_category_player_parameters));
SeekBarPreference volume_pref = findPreference(getString(R.string.invidious_volume_value));
@ -63,6 +64,7 @@ public class InvidiousSettingsFragment extends PreferenceFragmentCompat implemen
String volume_mode = sharedPreferences.getString(getString(R.string.invidious_volume_mode), "0");
SeekBarPreference volume_pref = findPreference(getString(R.string.invidious_volume_value));
PreferenceCategory player_parameters = findPreference(getString(R.string.invidious_category_player_parameters));
assert volume_mode != null;
if (volume_mode.compareTo("0") == 0 || volume_mode.compareTo("-1") == 0) {
assert player_parameters != null;
if (volume_pref != null) {

View File

@ -47,6 +47,7 @@ import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -70,8 +71,11 @@ import app.fedilab.nitterizeme.activities.MainActivity;
import app.fedilab.nitterizeme.activities.WebviewPlayerActivity;
import static android.content.Context.DOWNLOAD_SERVICE;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.bibliogram_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.instagram_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.invidious_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.nitter_instances;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.outlook_safe_domain;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.shortener_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.twitter_domains;
import static app.fedilab.nitterizeme.activities.CheckAppActivity.youtube_domains;
@ -94,9 +98,9 @@ public class Utils {
public static final Pattern maps = Pattern.compile("/maps/place/([^@]+@)?([\\d.,z]+).*");
public static final Pattern ampExtract = Pattern.compile("amp/s/(.*)");
public static final String RECEIVE_STREAMING_URL = "receive_streaming_url";
public static final Pattern outlookRedirect = Pattern.compile("(.*)safelinks\\.protection\\.outlook\\.com/?[?]?((?!url).)*url=([^&]+)");
private static final Pattern extractPlace = Pattern.compile("/maps/place/(((?!/data).)*)");
private static final Pattern googleRedirect = Pattern.compile("https?://(www\\.)?google(\\.\\w{2,})?(\\.\\w{2,})/url\\?q=(.*)");
public static final Pattern outlookRedirect = Pattern.compile("(.*)safelinks\\.protection\\.outlook\\.com/?[?]?((?!url).)*url=([^&]+)");
private static final String[] G_TRACKING = {
"sourceid",
"aqs",
@ -217,6 +221,7 @@ public class Utils {
String newUrl = null;
URL url_;
String host = null;
url = Utils.remove_tracking_param(url);
try {
url_ = new URL(url);
host = url_.getHost();
@ -233,7 +238,9 @@ public class Utils {
if (Arrays.asList(twitter_domains).contains(host)) {
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST);
assert nitterHost != null;
nitterHost = nitterHost.toLowerCase();
if (nitterHost.startsWith("http")) {
scheme = "";
}
@ -263,7 +270,9 @@ public class Utils {
} else if (Arrays.asList(instagram_domains).contains(host)) {
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST).toLowerCase();
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST);
assert bibliogramHost != null;
bibliogramHost = bibliogramHost.toLowerCase();
if (bibliogramHost.startsWith("http")) {
scheme = "";
}
@ -276,7 +285,7 @@ public class Utils {
matcher = bibliogramAccountPattern.matcher(url);
while (matcher.find()) {
final String bibliogram_directory = matcher.group(2);
if (bibliogram_directory != null && bibliogram_directory.compareTo("privacy") != 0) {
if (bibliogram_directory != null && bibliogram_directory.compareTo("privacy") != 0 && !bibliogram_directory.startsWith("/tv/") && !bibliogram_directory.startsWith("/reel/") && !bibliogram_directory.startsWith("/igtv/")) {
newUrl = scheme + bibliogramHost + "/u" + bibliogram_directory;
} else {
newUrl = scheme + bibliogramHost + bibliogram_directory;
@ -306,7 +315,9 @@ public class Utils {
} else {
zoom = "16";
}
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST);
assert osmHost != null;
osmHost = osmHost.toLowerCase();
boolean geo_uri_enabled = sharedpreferences.getBoolean(MainActivity.SET_GEO_URIS, false);
if (!geo_uri_enabled) {
newUrl = scheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
@ -326,10 +337,19 @@ public class Utils {
} else {
return url;
}
} else if (url.contains("/amp/s/")) {
Matcher matcher = ampExtract.matcher(url);
String transformedURL = url;
while (matcher.find()) {
transformedURL = "https://" + matcher.group(1);
}
return transformedURL;
} else if (Arrays.asList(youtube_domains).contains(host)) { //Youtube URL
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
if (invidious_enabled) {
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST);
assert invidiousHost != null;
invidiousHost = invidiousHost.toLowerCase();
if (invidiousHost.startsWith("http")) {
scheme = "";
}
@ -351,6 +371,70 @@ public class Utils {
} else {
return url;
}
} else if (Arrays.asList(invidious_instances).contains(host)) {
boolean invidious_enabled = sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
newUrl = url;
if (invidious_enabled) {
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST);
assert invidiousHost != null;
invidiousHost = invidiousHost.toLowerCase();
if (host != null && host.compareTo(invidiousHost) != 0) {
if (!invidiousHost.startsWith("http")) {
newUrl = url.replace(host, invidiousHost);
} else {
newUrl = url.replace("https://" + host, invidiousHost).replace("http://" + host, invidiousHost);
}
}
newUrl = Utils.replaceInvidiousParams(context, newUrl);
}
return newUrl;
}
//Transform a Nitter URL from an instance to another one selected by the end user.
else if (Arrays.asList(nitter_instances).contains(host)) {
newUrl = url;
boolean nitter_enabled = sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
if (nitter_enabled) {
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST);
assert nitterHost != null;
nitterHost = nitterHost.toLowerCase();
if (host != null && host.compareTo(nitterHost) != 0) {
if (!nitterHost.startsWith("http")) {
newUrl = url.replace(host, nitterHost);
} else {
newUrl = url.replace("https://" + host, nitterHost).replace("http://" + host, nitterHost);
}
}
}
return newUrl;
}
//Transform a Bibliogram URL from an instance to another one selected by the end user.
else if (Arrays.asList(bibliogram_instances).contains(host)) {
newUrl = url;
boolean bibliogram_enabled = sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
if (bibliogram_enabled) {
String bibliogramHost = sharedpreferences.getString(MainActivity.SET_BIBLIOGRAM_HOST, MainActivity.DEFAULT_BIBLIOGRAM_HOST);
assert bibliogramHost != null;
bibliogramHost = bibliogramHost.toLowerCase();
if (host != null && host.compareTo(bibliogramHost) != 0) {
if (!bibliogramHost.startsWith("http")) {
newUrl = url.replace(host, bibliogramHost);
} else {
newUrl = url.replace("https://" + host, bibliogramHost).replace("http://" + host, bibliogramHost);
}
}
}
return newUrl;
} else if (host != null && host.contains(outlook_safe_domain)) {
newUrl = url;
Matcher matcher = outlookRedirect.matcher(url);
if (matcher.find()) {
String tmp_url = matcher.group(3);
try {
newUrl = transformUrl(context, URLDecoder.decode(tmp_url, "UTF-8"));
} catch (UnsupportedEncodingException ignored) {
}
}
return newUrl;
}
return url;
}
@ -367,6 +451,7 @@ public class Utils {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
//Theme
String theme = sharedpreferences.getString(context.getString(R.string.invidious_dark_mode), "0");
assert theme != null;
if (theme.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?dark_mode=(true|false)", "");
} else if (theme.compareTo("0") != 0) { //Change value
@ -379,6 +464,7 @@ public class Utils {
//Thin mode
String thin = sharedpreferences.getString(context.getString(R.string.invidious_thin_mode), "0");
assert thin != null;
if (thin.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?thin_mode=(true|false)", "");
} else if (thin.compareTo("0") != 0) { //Change value
@ -391,6 +477,7 @@ public class Utils {
//Language
String language = sharedpreferences.getString(context.getString(R.string.invidious_language_mode), "0");
assert language != null;
if (language.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?hl=\\w{2}(-\\w{2})?", "");
} else if (language.compareTo("0") != 0) { //Change value
@ -403,6 +490,7 @@ public class Utils {
//Annotations
String annotations = sharedpreferences.getString(context.getString(R.string.invidious_annotations_mode), "0");
assert annotations != null;
if (annotations.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?iv_load_policy=\\d", "");
} else if (annotations.compareTo("0") != 0) { //Change value
@ -415,6 +503,7 @@ public class Utils {
//Autoplay
String autoplay = sharedpreferences.getString(context.getString(R.string.invidious_autoplay_mode), "0");
assert autoplay != null;
if (autoplay.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?autoplay=\\d", "");
} else if (autoplay.compareTo("0") != 0) { //Change value
@ -427,6 +516,7 @@ public class Utils {
//Continue
String continueMode = sharedpreferences.getString(context.getString(R.string.invidious_continue_mode), "0");
assert continueMode != null;
if (continueMode.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?continue=\\d", "");
} else if (continueMode.compareTo("0") != 0) { //Change value
@ -439,6 +529,7 @@ public class Utils {
//Listen
String listen = sharedpreferences.getString(context.getString(R.string.invidious_listen_mode), "0");
assert listen != null;
if (listen.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?listen=(true|false)", "");
} else if (listen.compareTo("0") != 0) { //Change value
@ -452,6 +543,7 @@ public class Utils {
//Local
String local = sharedpreferences.getString(context.getString(R.string.invidious_local_mode), "local=true");
if (!url.contains("/channel/")) {
assert local != null;
if (local.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?local=(true|false)", "");
} else if (local.compareTo("0") != 0) { //Change value
@ -465,6 +557,7 @@ public class Utils {
//Subtitles
String subtitles = sharedpreferences.getString(context.getString(R.string.invidious_subtitles_mode), "0");
assert subtitles != null;
if (subtitles.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?subtitles=\\w+", "");
} else if (subtitles.compareTo("0") != 0) { //Change value
@ -477,6 +570,7 @@ public class Utils {
//Quality
String quality = sharedpreferences.getString(context.getString(R.string.invidious_quality_mode), "0");
assert quality != null;
if (quality.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?quality=\\w+", "");
} else if (quality.compareTo("0") != 0) { //Change value
@ -489,6 +583,7 @@ public class Utils {
//Loop
String loop = sharedpreferences.getString(context.getString(R.string.invidious_loop_mode), "0");
assert loop != null;
if (loop.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?loop=\\d", "");
} else if (loop.compareTo("0") != 0) { //Change value
@ -502,6 +597,7 @@ public class Utils {
//Volume
String volume = sharedpreferences.getString(context.getString(R.string.invidious_volume_mode), "0");
assert volume != null;
if (volume.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?volume=\\d{1,3}", "");
} else if (volume.compareTo("0") != 0) { //Change value
@ -515,6 +611,7 @@ public class Utils {
//Player style
String player_style = sharedpreferences.getString(context.getString(R.string.invidious_player_style_mode), "0");
assert player_style != null;
if (player_style.compareTo("-1") == 0) { //Remove value
newUrl = newUrl.replaceAll("&?player_style=\\w+", "");
} else if (player_style.compareTo("0") != 0) { //Change value
@ -626,7 +723,7 @@ public class Utils {
*
* @return boolean
*/
@SuppressWarnings({"unused", "SameParameterValue"})
@SuppressWarnings({"SameParameterValue"})
private static boolean isAppInstalled(Context context, String packageName) {
try {
context.getPackageManager().getPackageInfo(packageName, 0);
@ -641,7 +738,6 @@ public class Utils {
*
* @return PackageInfo
*/
@SuppressWarnings("unused")
public static PackageInfo getPackageInfo(Context context, String packageName) {
PackageInfo packageInfo = null;
try {
@ -812,7 +908,9 @@ public class Utils {
String newUrlFinal = notShortnedURLDialog.get(notShortnedURLDialog.size() - 1);
while (matcher.find()) {
final String nitter_directory = matcher.group(2);
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST).toLowerCase();
String nitterHost = sharedpreferences.getString(MainActivity.SET_NITTER_HOST, MainActivity.DEFAULT_NITTER_HOST);
assert nitterHost != null;
nitterHost = nitterHost.toLowerCase();
newUrlFinal = scheme + nitterHost + nitter_directory;
}
String newExtraText = extraText.replaceAll(Pattern.quote(url), Matcher.quoteReplacement(newUrlFinal));
@ -826,7 +924,9 @@ public class Utils {
String newUrlFinal = notShortnedURLDialog.get(notShortnedURLDialog.size() - 1);
while (matcher.find()) {
final String youtubeId = matcher.group(3);
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST).toLowerCase();
String invidiousHost = sharedpreferences.getString(MainActivity.SET_INVIDIOUS_HOST, MainActivity.DEFAULT_INVIDIOUS_HOST);
assert invidiousHost != null;
invidiousHost = invidiousHost.toLowerCase();
if (Objects.requireNonNull(matcher.group(2)).compareTo("youtu.be") == 0) {
newUrlFinal = scheme + invidiousHost + "/watch?v=" + youtubeId;
} else {
@ -855,7 +955,9 @@ public class Utils {
} else {
zoom = data[2];
}
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST).toLowerCase();
String osmHost = sharedpreferences.getString(MainActivity.SET_OSM_HOST, MainActivity.DEFAULT_OSM_HOST);
assert osmHost != null;
osmHost = osmHost.toLowerCase();
newUrlFinal = scheme + osmHost + "/#map=" + zoom + "/" + data[0] + "/" + data[1];
}
}
@ -889,9 +991,6 @@ public class Utils {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
String type = i.getType();
if (type == null) {
type = "text/html";
}
intent.setDataAndType(i.getData(), type);
List<ResolveInfo> activities = context.getPackageManager().queryIntentActivities(intent, 0);
ArrayList<Intent> targetIntents = new ArrayList<>();
@ -960,4 +1059,44 @@ public class Utils {
}
public static boolean isRouted(String url) {
URL url_;
String host = null;
try {
url_ = new URL(url);
host = url_.getHost();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return Arrays.asList(twitter_domains).contains(host) || Arrays.asList(nitter_instances).contains(host)
|| Arrays.asList(instagram_domains).contains(host) || Arrays.asList(bibliogram_instances).contains(host)
|| url.contains("/maps/place") || url.contains("/amp/s/") || (host != null && host.contains(outlook_safe_domain))
|| Arrays.asList(youtube_domains).contains(host) || Arrays.asList(invidious_instances).contains(host);
}
public static boolean routerEnabledForHost(Context context, String url) {
URL url_;
String host = null;
try {
url_ = new URL(url);
host = url_.getHost();
} catch (MalformedURLException e) {
e.printStackTrace();
}
SharedPreferences sharedpreferences = context.getSharedPreferences(MainActivity.APP_PREFS, Context.MODE_PRIVATE);
if (Arrays.asList(twitter_domains).contains(host) || Arrays.asList(nitter_instances).contains(host)) {
return sharedpreferences.getBoolean(SET_NITTER_ENABLED, true);
} else if (Arrays.asList(instagram_domains).contains(host) || Arrays.asList(bibliogram_instances).contains(host)) {
return sharedpreferences.getBoolean(SET_BIBLIOGRAM_ENABLED, true);
} else if (url.contains("/maps/place")) {
return sharedpreferences.getBoolean(MainActivity.SET_OSM_ENABLED, true);
} else if (Arrays.asList(youtube_domains).contains(host) || Arrays.asList(invidious_instances).contains(host)) {
return sharedpreferences.getBoolean(SET_INVIDIOUS_ENABLED, true);
} else
return url.contains("/amp/s/") || (host != null && host.contains(outlook_safe_domain));
}
}

View File

@ -59,7 +59,8 @@ public class DefaultAppDAO {
db.delete(Sqlite.TABLE_DEFAULT_APPS, Sqlite.COL_DEFAULT_PACKAGE + " = \"" + packageName + "\"", null);
}
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "RedundantSuppression"})
public int removeAll() {
return db.delete(Sqlite.TABLE_DEFAULT_APPS, null, null);
}

View File

@ -0,0 +1,156 @@
package app.fedilab.nitterizeme.viewmodels;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of UntrackMe
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* UntrackMe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with UntrackMe; if not,
* see <http://www.gnu.org/licenses>. */
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import app.fedilab.nitterizeme.entities.Instance;
import static app.fedilab.nitterizeme.activities.MainActivity.APP_PREFS;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_BIBLIOGRAM_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_INVIDIOUS_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.DEFAULT_NITTER_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_BIBLIOGRAM_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_INVIDIOUS_HOST;
import static app.fedilab.nitterizeme.activities.MainActivity.SET_NITTER_HOST;
public class SearchInstanceVM extends AndroidViewModel {
private MutableLiveData<List<Instance>> instancesMLD;
public SearchInstanceVM(@NonNull Application application) {
super(application);
}
public LiveData<List<Instance>> getInstances() {
if (instancesMLD == null) {
instancesMLD = new MutableLiveData<>();
loadInstances();
}
return instancesMLD;
}
private void loadInstances() {
Thread thread = new Thread() {
@Override
public void run() {
HttpsURLConnection httpsURLConnection;
try {
String instances_url = "https://fedilab.app/untrackme_instances/payload_2.json";
URL url = new URL(instances_url);
httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setConnectTimeout(10 * 1000);
httpsURLConnection.setRequestProperty("http.keepAlive", "false");
httpsURLConnection.setRequestProperty("Content-Type", "application/json");
httpsURLConnection.setRequestProperty("Accept", "application/json");
httpsURLConnection.setRequestMethod("GET");
httpsURLConnection.setDefaultUseCaches(true);
httpsURLConnection.setUseCaches(true);
String response = null;
if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
java.util.Scanner s = new java.util.Scanner(httpsURLConnection.getInputStream()).useDelimiter("\\A");
response = s.hasNext() ? s.next() : "";
}
httpsURLConnection.getInputStream().close();
SharedPreferences sharedpreferences = getApplication().getApplicationContext().getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
String defaultInvidious = sharedpreferences.getString(SET_INVIDIOUS_HOST, DEFAULT_INVIDIOUS_HOST);
String defaultNitter = sharedpreferences.getString(SET_NITTER_HOST, DEFAULT_NITTER_HOST);
String defaultBibliogram = sharedpreferences.getString(SET_BIBLIOGRAM_HOST, DEFAULT_BIBLIOGRAM_HOST);
ArrayList<Instance> instances = new ArrayList<>();
if (response != null) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArrayInvidious = jsonObject.getJSONArray("invidious");
JSONArray jsonArrayNitter = jsonObject.getJSONArray("nitter");
JSONArray jsonArrayBibliogram = jsonObject.getJSONArray("bibliogram");
for (int i = 0; i < jsonArrayInvidious.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayInvidious.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayInvidious.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayInvidious.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
instance.setType(Instance.instanceType.INVIDIOUS);
if (defaultInvidious != null && domain.compareTo(defaultInvidious) == 0) {
instance.setChecked(true);
}
instances.add(instance);
}
for (int i = 0; i < jsonArrayNitter.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayNitter.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayNitter.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayNitter.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
instance.setType(Instance.instanceType.NITTER);
if (defaultNitter != null && domain.compareTo(defaultNitter) == 0) {
instance.setChecked(true);
}
instances.add(instance);
}
for (int i = 0; i < jsonArrayBibliogram.length(); i++) {
Instance instance = new Instance();
String domain = jsonArrayBibliogram.getJSONObject(i).getString("domain");
boolean cloudFlare = jsonArrayBibliogram.getJSONObject(i).getBoolean("cloudflare");
String locale = jsonArrayBibliogram.getJSONObject(i).getString("locale");
instance.setDomain(domain);
instance.setCloudflare(cloudFlare);
instance.setLocale(locale);
instance.setType(Instance.instanceType.BIBLIOGRAM);
if (defaultBibliogram != null && domain.compareTo(defaultBibliogram) == 0) {
instance.setChecked(true);
}
instances.add(instance);
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> instancesMLD.setValue(instances);
mainHandler.post(myRunnable);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_lite_background"/>
<foreground android:drawable="@drawable/ic_launcher_lite_foreground"/>
<background android:drawable="@color/ic_launcher_lite_background" />
<foreground android:drawable="@drawable/ic_launcher_lite_foreground" />
</adaptive-icon>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_lite_background"/>
<foreground android:drawable="@drawable/ic_launcher_lite_foreground"/>
<background android:drawable="@color/ic_launcher_lite_background" />
<foreground android:drawable="@drawable/ic_launcher_lite_foreground" />
</adaptive-icon>

View File

@ -59,7 +59,7 @@
<string name="check_apps">Vérifier les applications</string>
<string name="select_instances">Sélectionner les instances</string>
<string name="continue_with">Continuer avec…</string>
<string name="just_once">Une seule fois</string>
<string name="just_once">Cette fois uniquement</string>
<string name="always">Toujours</string>
<string name="default_app_indication">%1$s a été défini comme application par défaut.\nVous pouvez supprimer ce comportement des paramètres de l\'application.</string>
<string name="indication_error_title">Il y a quelque chose qui ne va pas dans la configuration de l\'application. Veuillez suivre ces indications pour résoudre ce problème.</string>
@ -83,12 +83,12 @@
<string name="invidious_dark_mode_indication">Configurer le thème par défaut sans paramétrer les cookies</string>
<string name="invidious_thin_mode_title">Mode fin</string>
<string name="invidious_thin_mode_indication">Charger les éléments HTML, CSS, JS et vidéo (désactive les images)</string>
<string name="invidious_language_mode_indication">Locales disponibles</string>
<string name="invidious_language_mode_indication">Langues disponibles</string>
<string name="invidious_language_mode_title">Langue de l\'interface utilisateur</string>
<string name="pref_invidious_head1">Paramètres globaux du site</string>
<string name="pref_invidious_head2">Paramètres du lecteur</string>
<string name="invidious_annotations_mode_title">Annotations</string>
<string name="invidious_annotations_mode_indication">Show legacy annotations, provided by the Internet Archive</string>
<string name="invidious_annotations_mode_indication">Afficher les anciennes annotations, fournies par l\'Internet Archive</string>
<string name="invidious_autoplay_mode_indication">Lire la vidéo automatiquement au chargement</string>
<string name="invidious_autoplay_mode_title">Lecture automatique</string>
<string name="invidious_continue_mode_title">Continuer</string>
@ -103,19 +103,19 @@
<string name="invidious_quality_mode_indication">Qualité du lecteur par défaut</string>
<string name="invidious_loop_mode_title">Lecture en boucle</string>
<string name="invidious_volume_mode_title">Volume</string>
<string name="invidious_volume_mode_indication">Default player volume, can be any whole number between 0 and 100</string>
<string name="invidious_loop_mode_indication">Loop player by default</string>
<string name="invidious_volume_mode_indication">Le volume du joueur par défaut, cela peut être un nombre entier compris entre 0 et 100</string>
<string name="invidious_loop_mode_indication">Lire en boucle par défaut</string>
<string name="invidious_volume_mode_value">Valeur du volume</string>
<string name="invidious_volume_mode_value_indication">Override the volume with this value</string>
<string name="invidious_volume_mode_value_indication">Remplacer le volume avec cette valeur</string>
<string name="pref_invidious_head3">Style du lecteur</string>
<string name="invidious_player_style_mode_title">Apparence</string>
<string name="invidious_player_style_mode_indication">Invidious, the default one. YouTube, using a centered play button and always visible video control bar</string>
<string name="invidious_player_style_mode_indication">Invidieux, celui par défaut. YouTube, en utilisant un bouton de lecture centré et une barre de contrôle vidéo toujours visible</string>
<string name="help">Aide</string>
<string name="invidious_help_title">Réglage des options</string>
<string name="invidious_help_ignore"><b>Ignore:</b> This is the default action for all¹ parameters. This means UntrackMe will not do anything about the parameter</string>
<string name="invidious_help_remove"><b>Remove:</b> UntrackMe will remove the parameter from URL, if it exists</string>
<string name="invidious_help_ignore"><b>Ignorer :</b> Il s\'agit de l\'action par défaut pour tous1 les paramètres . Cela signifie qu\'UntrackMe ne fera rien à propos du paramètre</string>
<string name="invidious_help_remove"><b>Supprimer:</b> UntrackMe supprimera le paramètre de l\'URL, s\'il existe</string>
<string name="invidious_help_other">Si vous sélectionnez d\'autres valeurs pour un paramètre, elles seront ajoutées à l\'URL. Si le paramètre existe déjà, sa valeur sera changée selon votre choix</string>
<string name="invidious_help_explanations">[1] \'local\' parameter is set to \'true\' by default for better privacy</string>
<string name="invidious_help_explanations">[1] Le paramètre \'local\' est défini à \'Actif\' par défaut pour une meilleure confidentialité</string>
<string-array name="invidious_theme">
<item>Ignorer</item>
<item>Retirer</item>

View File

@ -75,27 +75,27 @@
<string name="delete">Usuń</string>
<string name="cancel">Anuluj</string>
<string name="delete_app_from_default">Usunąć %1$s z domyślnych aplikacji?</string>
<string name="copy_done">Copied</string>
<string name="no_apps_set_as_default">No apps set as default!</string>
<string name="custom_settings_for_invidious">Custom settings for Invidious</string>
<string name="invidious_settings">Invidious settings</string>
<string name="invidious_dark_mode_title">Theme</string>
<string name="invidious_dark_mode_indication">Configure default theme without setting cookies</string>
<string name="invidious_thin_mode_title">Thin mode</string>
<string name="invidious_thin_mode_indication">Load HTML, CSS, JS and video elements (disables images)</string>
<string name="invidious_language_mode_indication">Available locales</string>
<string name="invidious_language_mode_title">UI Language</string>
<string name="copy_done">Skopiowane</string>
<string name="no_apps_set_as_default">Brak aplikacji ustawionych jako domyślne!</string>
<string name="custom_settings_for_invidious">Własne ustawienia dla Invidious</string>
<string name="invidious_settings">Ustawiania Invidious</string>
<string name="invidious_dark_mode_title">Motyw</string>
<string name="invidious_dark_mode_indication">Skonfiguruj domyślny motyw bez ustawiania ciasteczek</string>
<string name="invidious_thin_mode_title">Tryb cienki</string>
<string name="invidious_thin_mode_indication">Wczytaj elementy HTML, CSS, JS i wideo (wyłącza obrazy)</string>
<string name="invidious_language_mode_indication">Dostępne ustawienia regionalne</string>
<string name="invidious_language_mode_title">Język interfejsu</string>
<string name="pref_invidious_head1">Site-wide parameters</string>
<string name="pref_invidious_head2">Player parameters</string>
<string name="invidious_annotations_mode_title">Annotations</string>
<string name="invidious_annotations_mode_indication">Show legacy annotations, provided by the Internet Archive</string>
<string name="invidious_autoplay_mode_indication">Automatically play video on load</string>
<string name="invidious_autoplay_mode_title">Autoplay</string>
<string name="invidious_continue_mode_title">Continue</string>
<string name="invidious_continue_mode_indication">When video is done, automatically go to the next related video (similar to YouTubes Autoplay feature)</string>
<string name="invidious_listen_mode_title">Listen</string>
<string name="invidious_listen_mode_indication">Play only audio portion of video</string>
<string name="invidious_local_mode_title">Local</string>
<string name="pref_invidious_head2">Parametry gracza</string>
<string name="invidious_annotations_mode_title">Adnotacje</string>
<string name="invidious_annotations_mode_indication">Pokaż dotychczasowe adnotacje dostarczone przez archiwum internetowe</string>
<string name="invidious_autoplay_mode_indication">Automatycznie odtwarzaj wideo przy obciążeniu</string>
<string name="invidious_autoplay_mode_title">Autoodtwarzanie</string>
<string name="invidious_continue_mode_title">Dalej</string>
<string name="invidious_continue_mode_indication">Po zakończeniu filmu, przejdź automatycznie do następnego powiązanego filmu (podobnego do funkcji automatycznego odtwarzania YouTube)</string>
<string name="invidious_listen_mode_title">Odsłuchaj</string>
<string name="invidious_listen_mode_indication">Odtwarzaj tylko część dźwięku wideo</string>
<string name="invidious_local_mode_title">Lokalnie</string>
<string name="invidious_local_mode_indication">Proxy video streams</string>
<string name="invidious_subtitles_mode_title">Subtitles</string>
<string name="invidious_subtitles_mode_indication">List of ISO 6391 language codes</string>

View File

@ -35,8 +35,8 @@
<PreferenceCategory
android:title="@string/pref_invidious_head2"
android:key="@string/invidious_category_player_parameters"
android:title="@string/pref_invidious_head2"
app:iconSpaceReserved="false">
<ListPreference
android:defaultValue="0"
@ -125,12 +125,12 @@
<SeekBarPreference
android:defaultValue="60"
app:showSeekBarValue="true"
app:iconSpaceReserved="false"
android:key="@string/invidious_volume_value"
android:max="100"
android:title="@string/invidious_volume_mode_value"
app:summary="@string/invidious_volume_mode_value_indication"
android:max="100" />
app:iconSpaceReserved="false"
app:showSeekBarValue="true"
app:summary="@string/invidious_volume_mode_value_indication" />
</PreferenceCategory>
<PreferenceCategory

View File

@ -7,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -6,11 +6,11 @@
**Lite έκδοση:
- When sharing a Twitter, YouTube or Google Maps link just pick up UntrackMe to transform it before sharing it with another app.
- Όταν μοιράζεστε ένα σύνδεσμο Twitter, YouTube ή Google Maps απλά επιλέξτε το UntrackMe για να τον μετατρέψετε πρίν τον μοιραστείτε με μια άλλη εφαρμογή.
**Πλήρης έκδοση:
- Contains all features of the lite version and it also handle all links to remove tracking parameters. It uses its own app picker that display URLs before visiting them.
Περιέχει όλες τις λειτουργίες της έκδοσης lite και μπορεί επίσης να διαχειριστεί όλους τους συνδέσμους ώστε να αφαιρέσει τις παραμέτρους παρακολούθησης. Χρησιμοποιεί τον δικό του επιλογέα εφαρμογών για την εμφάνιση URL πρίν την εμφάνιση.
Τι είναι το Nitter:

View File

@ -0,0 +1,9 @@
Added
- Handle /tv/, /igtv/ and /reel/ for Bibliogram
- Handle multiple tracking
Changed
- Remove default invidio.us instance for Invidious
Fixed
- Allow sharing to YouTube apps (Lite)