Ping instances
This commit is contained in:
parent
01335bb36f
commit
f9b8799461
|
@ -423,7 +423,10 @@
|
|||
android:pathPattern="/maps/place/.*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="app.fedilab.nitterizeme.InstanceActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/Base.V7.Theme.AppCompat.Dialog" />
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package app.fedilab.nitterizeme;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of NitterizeMe
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NitterizeMe 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 NitterizeMe; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
public class Instance {
|
||||
|
||||
enum instanceType{
|
||||
INVIDIOUS,
|
||||
NITTER,
|
||||
BIBLIOGRAM
|
||||
}
|
||||
private String domain;
|
||||
private long latency = -1;
|
||||
private boolean checked;
|
||||
private instanceType type;
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public long getLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
public void setLatency(long latency) {
|
||||
this.latency = latency;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public instanceType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(instanceType type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package app.fedilab.nitterizeme;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of NitterizeMe
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NitterizeMe 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 NitterizeMe; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class InstanceActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_popup_instance);
|
||||
new SearchInstances(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
||||
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/nitterizeme_instances/payload.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);
|
||||
Button close = activity.findViewById(R.id.close);
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(result);
|
||||
JSONArray jsonArrayInvidious = jsonObject.getJSONArray("invidious");
|
||||
JSONArray jsonArrayNitter = jsonObject.getJSONArray("nitter");
|
||||
JSONArray jsonArrayBibliogram = jsonObject.getJSONArray("bibliogram");
|
||||
|
||||
List<Instance> invidiousInstances = new ArrayList<>();
|
||||
for(int i = 0; i < jsonArrayInvidious.length(); i++){
|
||||
Instance instance = new Instance();
|
||||
instance.setDomain(jsonArrayInvidious.getString(i));
|
||||
instance.setType(Instance.instanceType.INVIDIOUS);
|
||||
invidiousInstances.add(instance);
|
||||
}
|
||||
List<Instance> nitterInstances = new ArrayList<>();
|
||||
for(int i = 0; i < jsonArrayNitter.length(); i++){
|
||||
Instance instance = new Instance();
|
||||
instance.setDomain(jsonArrayInvidious.getString(i));
|
||||
instance.setType(Instance.instanceType.NITTER);
|
||||
nitterInstances.add(instance);
|
||||
}
|
||||
List<Instance> bibliogramInstances = new ArrayList<>();
|
||||
for(int i = 0; i < jsonArrayBibliogram.length(); i++){
|
||||
Instance instance = new Instance();
|
||||
instance.setDomain(jsonArrayInvidious.getString(i));
|
||||
instance.setType(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);
|
||||
|
||||
final LinearLayoutManager nLayoutManager = new LinearLayoutManager(activity);
|
||||
InstanceAdapter nitterAdapter = new InstanceAdapter(nitterInstances);
|
||||
nitter_instances.setAdapter(nitterAdapter);
|
||||
nitter_instances.setLayoutManager(nLayoutManager);
|
||||
|
||||
final LinearLayoutManager bLayoutManager = new LinearLayoutManager(activity);
|
||||
InstanceAdapter bibliogramAdapter = new InstanceAdapter(bibliogramInstances);
|
||||
bibliogram_instances.setAdapter(bibliogramAdapter);
|
||||
bibliogram_instances.setLayoutManager(bLayoutManager);
|
||||
|
||||
latency_test.setOnClickListener(v-> invidiousAdapter.evalLatency());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
close.setOnClickListener(v-> activity.finish());
|
||||
|
||||
|
||||
|
||||
instance_container.setVisibility(View.VISIBLE);
|
||||
loader.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
package app.fedilab.nitterizeme;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of NitterizeMe
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* NitterizeMe 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 NitterizeMe; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static app.fedilab.nitterizeme.MainActivity.APP_PREFS;
|
||||
import static app.fedilab.nitterizeme.MainActivity.DEFAULT_BIBLIOGRAM_HOST;
|
||||
import static app.fedilab.nitterizeme.MainActivity.DEFAULT_INVIDIOUS_HOST;
|
||||
import static app.fedilab.nitterizeme.MainActivity.DEFAULT_NITTER_HOST;
|
||||
import static app.fedilab.nitterizeme.MainActivity.SET_BIBLIOGRAM_HOST;
|
||||
import static app.fedilab.nitterizeme.MainActivity.SET_INVIDIOUS_HOST;
|
||||
import static app.fedilab.nitterizeme.MainActivity.SET_NITTER_HOST;
|
||||
|
||||
public class InstanceAdapter extends RecyclerView.Adapter {
|
||||
|
||||
private List<Instance> instances;
|
||||
|
||||
InstanceAdapter(List<Instance> instances) {
|
||||
this.instances = instances;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
|
||||
Context context = parent.getContext();
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_instance, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
|
||||
|
||||
ViewHolder holder = (ViewHolder) viewHolder;
|
||||
Instance instance = instances.get(i);
|
||||
Context context = viewHolder.itemView.getContext();
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
|
||||
//Reset checked instances by type when tipping
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if (instance.getLatency() == -1){
|
||||
holder.latency.setVisibility(View.GONE);
|
||||
holder.progress.setVisibility(View.GONE);
|
||||
}else if(instance.getLatency() == 0 ){
|
||||
holder.latency.setVisibility(View.GONE);
|
||||
holder.progress.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
holder.latency.setVisibility(View.VISIBLE);
|
||||
holder.progress.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
switch (instance.getType()){
|
||||
case INVIDIOUS:
|
||||
if( instance.getDomain().compareTo(defaultInvidious) == 0 ){
|
||||
holder.checkbox_instance.setChecked(true);
|
||||
}
|
||||
break;
|
||||
case NITTER:
|
||||
if( instance.getDomain().compareTo(defaultNitter) == 0 ){
|
||||
holder.checkbox_instance.setChecked(true);
|
||||
}
|
||||
break;
|
||||
case BIBLIOGRAM:
|
||||
if( instance.getDomain().compareTo(defaultBibliogram) == 0 ){
|
||||
holder.checkbox_instance.setChecked(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
holder.checkbox_instance.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
for(Instance _ins: instances){
|
||||
if(instance.getType() == _ins.getType() && instance.getDomain().compareTo(_ins.getDomain()) != 0 ){
|
||||
_ins.setChecked(false);
|
||||
}
|
||||
}
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
switch (instance.getType()){
|
||||
case INVIDIOUS:
|
||||
if( isChecked) {
|
||||
editor.putString(SET_INVIDIOUS_HOST, instance.getDomain().trim());
|
||||
}else{
|
||||
editor.putString(SET_INVIDIOUS_HOST, null);
|
||||
}
|
||||
editor.apply();
|
||||
break;
|
||||
case NITTER:
|
||||
if( isChecked) {
|
||||
editor.putString(SET_NITTER_HOST, instance.getDomain().trim());
|
||||
}else{
|
||||
editor.putString(SET_NITTER_HOST, null);
|
||||
}
|
||||
editor.apply();
|
||||
break;
|
||||
case BIBLIOGRAM:
|
||||
if( isChecked) {
|
||||
editor.putString(SET_BIBLIOGRAM_HOST, instance.getDomain().trim());
|
||||
}else{
|
||||
editor.putString(SET_BIBLIOGRAM_HOST, null);
|
||||
}
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void evalLatency(){
|
||||
for(Instance instance: instances){
|
||||
instance.setLatency(0);
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
long ping = Utils.ping(instance.getDomain());
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
if( ping > 0 ) {
|
||||
instance.setLatency(ping);
|
||||
}else{
|
||||
instance.setLatency(R.string.error);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return instances.size();
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
CheckBox checkbox_instance;
|
||||
TextView latency;
|
||||
ProgressBar progress;
|
||||
|
||||
ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
checkbox_instance = itemView.findViewById(R.id.checkbox_instance);
|
||||
latency = itemView.findViewById(R.id.latency);
|
||||
progress = itemView.findViewById(R.id.progress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -143,6 +143,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
enable_osm.setChecked(osm_enabled);
|
||||
|
||||
Button button_save = findViewById(R.id.button_save);
|
||||
CheckBox enable_geo_uris = findViewById(R.id.enable_geo_uris);
|
||||
list_apps = findViewById(R.id.list_apps);
|
||||
String nitterHost = sharedpreferences.getString(SET_NITTER_HOST, null);
|
||||
String invidiousHost = sharedpreferences.getString(SET_INVIDIOUS_HOST, null);
|
||||
|
@ -153,21 +154,26 @@ public class MainActivity extends AppCompatActivity {
|
|||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(SET_INVIDIOUS_ENABLED, isChecked);
|
||||
editor.apply();
|
||||
invidious_instance.setVisibility(isChecked?View.VISIBLE:View.GONE);
|
||||
});
|
||||
enable_nitter.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(SET_NITTER_ENABLED, isChecked);
|
||||
editor.apply();
|
||||
nitter_instance.setVisibility(isChecked?View.VISIBLE:View.GONE);
|
||||
});
|
||||
enable_bibliogram.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(SET_BIBLIOGRAM_ENABLED, isChecked);
|
||||
editor.apply();
|
||||
bibliogram_instance.setVisibility(isChecked?View.VISIBLE:View.GONE);
|
||||
});
|
||||
enable_osm.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(SET_OSM_ENABLED, isChecked);
|
||||
editor.apply();
|
||||
osm_instance.setVisibility(isChecked?View.VISIBLE:View.GONE);
|
||||
enable_geo_uris.setVisibility(isChecked?View.VISIBLE:View.GONE);
|
||||
});
|
||||
|
||||
if (nitterHost != null) {
|
||||
|
@ -222,12 +228,19 @@ public class MainActivity extends AppCompatActivity {
|
|||
if (list_apps.getVisibility() == View.VISIBLE) {
|
||||
list_apps.setVisibility(View.GONE);
|
||||
buttonExpand.setContentDescription(getString(R.string.display_supported_links));
|
||||
buttonExpand.setImageResource(R.drawable.ic_expand_more);
|
||||
} else {
|
||||
list_apps.setVisibility(View.VISIBLE);
|
||||
buttonExpand.setContentDescription(getString(R.string.hide_supported_links));
|
||||
buttonExpand.setImageResource(R.drawable.ic_expand_less);
|
||||
}
|
||||
});
|
||||
|
||||
ImageButton buttonPing = findViewById(R.id.instances);
|
||||
buttonPing.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(MainActivity.this, InstanceActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
ArrayList<AppInfo> appInfos = new ArrayList<>();
|
||||
for (String domain : domains) {
|
||||
AppInfo appInfo = new AppInfo();
|
||||
|
@ -236,7 +249,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
appInfos.add(appInfo);
|
||||
}
|
||||
|
||||
CheckBox enable_geo_uris = findViewById(R.id.enable_geo_uris);
|
||||
|
||||
enable_geo_uris.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(SET_GEO_URIS, isChecked);
|
||||
|
|
|
@ -15,6 +15,7 @@ package app.fedilab.nitterizeme;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -81,4 +82,21 @@ class Utils {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time for reaching a domain
|
||||
* @param domain String domain name
|
||||
* @return long delay
|
||||
*/
|
||||
public static long ping(String domain){
|
||||
long timeDifference = -2;
|
||||
try {
|
||||
long beforeTime = System.currentTimeMillis();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
InetAddress.getByName(domain).isReachable(10000);
|
||||
long afterTime = System.currentTimeMillis();
|
||||
timeDifference = afterTime - beforeTime;
|
||||
} catch (IOException ignored) {}
|
||||
return timeDifference;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM11,19.93c-3.95,-0.49 -7,-3.85 -7,-7.93 0,-0.62 0.08,-1.21 0.21,-1.79L9,15v1c0,1.1 0.9,2 2,2v1.93zM17.9,17.39c-0.26,-0.81 -1,-1.39 -1.9,-1.39h-1v-3c0,-0.55 -0.45,-1 -1,-1L8,12v-2h2c0.55,0 1,-0.45 1,-1L11,7h2c1.1,0 2,-0.9 2,-2v-0.41c2.93,1.19 5,4.06 5,7.41 0,2.08 -0.8,3.97 -2.1,5.39z"/>
|
||||
</vector>
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:layout_height="match_parent">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:minHeight="500dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/instance_container"
|
||||
android:visibility="gone"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textSize="16sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/invidious_instances"/>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/invidious_instances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/nitter_instances"/>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/nitter_instances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/bibliogram_instances"/>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/bibliogram_instances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/instance_container"
|
||||
android:orientation="horizontal">
|
||||
<Button
|
||||
android:id="@+id/latency_test"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingLeft="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:paddingRight="30dp"
|
||||
android:text="@string/latency"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/close"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingLeft="30dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:paddingRight="30dp"
|
||||
android:text="@string/close"
|
||||
android:textColor="@android:color/white" />
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/loader"
|
||||
android:minHeight="500dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ProgressBar
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
|
@ -41,235 +41,245 @@
|
|||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nitter_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/redirect_twitter_to_nitter"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/introduction" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="20dp"
|
||||
android:id="@+id/nitter_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nitter_indications">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
app:layout_constraintTop_toBottomOf="@+id/introduction">
|
||||
<TextView
|
||||
android:id="@+id/nitter_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/nitter_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_nitter"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
android:text="@string/redirect_twitter_to_nitter"/>
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/enable_nitter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp" />
|
||||
android:layout_gravity="center"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/invidious_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/redirect_youtube_to_invidious"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/nitter_instance_container"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nitter_container" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/nitter_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/nitter_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_nitter"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/invidious_container"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/invidious_indications">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
app:layout_constraintTop_toBottomOf="@+id/nitter_instance_container"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/invidious_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/invidious_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_invidious"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
android:text="@string/redirect_youtube_to_invidious" />
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/enable_invidious"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp" />
|
||||
android:layout_gravity="center"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bibliogram_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/redirect_instagram_to_bibliogram"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/invidious_instance_container"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/invidious_container" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/invidious_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/invidious_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_invidious"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/bibliogram_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bibliogram_indications">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
app:layout_constraintTop_toBottomOf="@+id/invidious_instance_container">
|
||||
<TextView
|
||||
android:id="@+id/bibliogram_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/bibliogram_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_bibliogram"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
android:text="@string/redirect_instagram_to_bibliogram"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/invidious_container" />
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/enable_bibliogram"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp" />
|
||||
android:layout_gravity="center" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osm_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/redirect_gm_to_osm"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/bibliogram_instance_container"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bibliogram_container" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/bibliogram_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/bibliogram_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_bibliogram"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/osm_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_indications">
|
||||
|
||||
<LinearLayout
|
||||
app:layout_constraintTop_toBottomOf="@+id/bibliogram_instance_container">
|
||||
<TextView
|
||||
android:id="@+id/osm_indications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/osm_instance_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/osm_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_osm"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/enable_geo_uris"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/use_geo_uri" />
|
||||
</LinearLayout>
|
||||
|
||||
android:text="@string/redirect_gm_to_osm"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bibliogram_container" />
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/enable_osm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp" />
|
||||
android:layout_gravity="center" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/configure"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:drawableStart="@drawable/ic_settings"
|
||||
android:drawableLeft="@drawable/ic_settings"
|
||||
|
||||
android:drawablePadding="5dp"
|
||||
android:text="@string/configure"
|
||||
android:textColor="@android:color/white"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/osm_instance_container"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/button_save"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_container" />
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/osm_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/custom_osm"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<CheckBox
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_instance_container"
|
||||
android:id="@+id/enable_geo_uris"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/use_geo_uri" />
|
||||
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_save"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
|
||||
android:layout_marginTop="5dp"
|
||||
android:minWidth="100dp"
|
||||
android:drawableStart="@drawable/ic_save"
|
||||
android:drawableLeft="@drawable/ic_save"
|
||||
android:drawablePadding="5dp"
|
||||
android:text="@string/save"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintLeft_toRightOf="@+id/configure"
|
||||
app:layout_constraintRight_toRightOf="@+id/button_expand"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_container" />
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/enable_geo_uris" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/configure"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:drawableStart="@drawable/ic_settings"
|
||||
android:drawableLeft="@drawable/ic_settings"
|
||||
android:drawablePadding="5dp"
|
||||
android:text="@string/configure"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/button_expand"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button_save" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_expand"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:contentDescription="@string/display_supported_links"
|
||||
android:drawableStart="@drawable/ic_save"
|
||||
android:drawableLeft="@drawable/ic_save"
|
||||
android:drawablePadding="5dp"
|
||||
android:src="@drawable/ic_expand_more"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintLeft_toRightOf="@+id/button_save"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/osm_container" />
|
||||
app:layout_constraintLeft_toRightOf="@+id/configure"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button_save"
|
||||
app:layout_constraintRight_toLeftOf="@+id/instances"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/instances"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:contentDescription="@string/display_supported_links"
|
||||
android:drawableStart="@drawable/ic_save"
|
||||
android:drawableLeft="@drawable/ic_save"
|
||||
android:drawablePadding="5dp"
|
||||
android:src="@drawable/ic_public"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintLeft_toRightOf="@+id/button_expand"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button_save"
|
||||
/>
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list_apps"
|
||||
|
@ -281,7 +291,7 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button_save" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/configure" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/fab_margin"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginEnd="@dimen/fab_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox_instance"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<TextView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:id="@+id/latency"
|
||||
android:gravity="end"/>
|
||||
<ProgressBar
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:id="@+id/progress"/>
|
||||
</LinearLayout>
|
|
@ -40,4 +40,8 @@
|
|||
<string name="try_to_redirect">%1$s \n\nwill redirect you to\n\n<b>%2$s</b></string>
|
||||
<string name="try_to_redirect_again">Then it will redirect you to\n\n<b>%1$s</b></string>
|
||||
<string name="the_app_failed_shortened">The app didn\'t manage to retrieve the full URL</string>
|
||||
<string name="invidious_instances">Invidious instances</string>
|
||||
<string name="nitter_instances">Nitter instances</string>
|
||||
<string name="bibliogram_instances">Bibliogram instances</string>
|
||||
<string name="latency">Latency</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue