diff options
author | cyBerta <cyberta@riseup.net> | 2021-07-22 15:31:08 +0200 |
---|---|---|
committer | cyBerta <cyberta@riseup.net> | 2021-11-15 16:13:41 +0100 |
commit | 551ee22aafae99c1f0802ec48f43d448cc77db37 (patch) | |
tree | 50756228638aaf55ea17a4baf9285a363cba8760 /app/src | |
parent | 9b2b57d8617e60c0b69713e1e5f14dbb8e57c70a (diff) |
first implementation of the gateway button, started to remove labels from EipFragment, implement method to get the avearage load of a location as an enum value
Diffstat (limited to 'app/src')
12 files changed, 327 insertions, 118 deletions
diff --git a/app/src/androidTest/legacy/VpnTestController.java b/app/src/androidTest/legacy/VpnTestController.java index e39ebae3..035ca2b0 100644 --- a/app/src/androidTest/legacy/VpnTestController.java +++ b/app/src/androidTest/legacy/VpnTestController.java @@ -35,7 +35,7 @@ public class VpnTestController { } protected Button getVpnButton() { - View button_view = solo.getView(R.id.vpn_main_button); + View button_view = solo.getView(R.id.gateway_location_button); if (button_view != null) return (Button) button_view; else diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java index 615221ae..cc822463 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java @@ -38,9 +38,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.AppCompatButton; import androidx.appcompat.widget.AppCompatImageView; -import androidx.appcompat.widget.AppCompatTextView; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; @@ -60,9 +58,11 @@ import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; +import se.leap.bitmaskclient.base.views.LocationButton; import se.leap.bitmaskclient.base.views.VpnStateImage; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; +import se.leap.bitmaskclient.eip.GatewaysManager; import se.leap.bitmaskclient.providersetup.ProviderAPICommand; import se.leap.bitmaskclient.providersetup.ProviderListActivity; import se.leap.bitmaskclient.providersetup.activities.CustomProviderSetupActivity; @@ -86,6 +86,7 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask; import static se.leap.bitmaskclient.base.utils.ViewHelper.convertDimensionToPx; import static se.leap.bitmaskclient.eip.EipSetupObserver.gatewayOrder; import static se.leap.bitmaskclient.eip.EipSetupObserver.reconnectingWithDifferentGateway; +import static se.leap.bitmaskclient.eip.GatewaysManager.Load.UNKNOWN; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DOWNLOAD_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE; @@ -104,18 +105,14 @@ public class EipFragment extends Fragment implements Observer { @BindView(R.id.vpn_state_image) VpnStateImage vpnStateImage; - @BindView(R.id.vpn_main_button) - AppCompatButton mainButton; - - @BindView(R.id.routed_text) - AppCompatTextView routedText; - - @BindView(R.id.vpn_route) - AppCompatTextView vpnRoute; + @BindView(R.id.gateway_location_button) + LocationButton locationButton; private Unbinder unbinder; private EipStatus eipStatus; + private GatewaysManager gatewaysManager; + //---saved Instance ------- private final String KEY_SHOW_PENDING_START_CANCELLATION = "KEY_SHOW_PENDING_START_CANCELLATION"; private final String KEY_SHOW_ASK_TO_STOP_EIP = "KEY_SHOW_ASK_TO_STOP_EIP"; @@ -168,6 +165,9 @@ public class EipFragment extends Fragment implements Observer { } else { Log.e(TAG, "activity is null in onCreate - no preferences set!"); } + + gatewaysManager = new GatewaysManager(getContext()); + } @Override @@ -252,7 +252,7 @@ public class EipFragment extends Fragment implements Observer { preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, restartOnBoot).apply(); } - @OnClick(R.id.vpn_main_button) + @OnClick(R.id.gateway_location_button) void onButtonClick() { handleIcon(); } @@ -307,7 +307,7 @@ public class EipFragment extends Fragment implements Observer { } private void setMainButtonEnabled(boolean enabled) { - mainButton.setEnabled(enabled); + locationButton.setEnabled(enabled); vpnStateImage.setEnabled(enabled); } @@ -408,32 +408,35 @@ public class EipFragment extends Fragment implements Observer { setMainButtonEnabled(true); showConnectingLayout(activity); if (eipStatus.isReconnecting()) { - //Log.d(TAG, "eip show reconnecting toast!"); - //showReconnectToast(activity); + locationButton.setText(getString(R.string.reconnecting)); + } else { + locationButton.setText(getString(R.string.finding_best_connection)); } + locationButton.setVisibility(VISIBLE); + locationButton.setLocationLoad(UNKNOWN); } else if (eipStatus.isConnected() ) { - mainButton.setText(activity.getString(R.string.vpn_button_turn_off)); + locationButton.setText(activity.getString(R.string.vpn_button_turn_off)); setMainButtonEnabled(true); vpnStateImage.setStateIcon(R.drawable.vpn_connected); vpnStateImage.stopProgress(false); - routedText.setText(R.string.vpn_securely_routed); - routedText.setVisibility(VISIBLE); - vpnRoute.setVisibility(VISIBLE); - setVpnRouteText(); + locationButton.setLocationLoad(gatewaysManager.getLoadForLocation(VpnStatus.getLastConnectedVpnName())); + locationButton.setText(VpnStatus.getLastConnectedVpnName()); + locationButton.setVisibility(VISIBLE); colorBackground(); } else if(isOpenVpnRunningWithoutNetwork()){ - mainButton.setText(activity.getString(R.string.vpn_button_turn_off)); + locationButton.setText(activity.getString(R.string.vpn_button_turn_off)); setMainButtonEnabled(true); vpnStateImage.setStateIcon(R.drawable.vpn_disconnected); vpnStateImage.stopProgress(false); - routedText.setText(R.string.vpn_securely_routed_no_internet); - routedText.setVisibility(VISIBLE); - vpnRoute.setVisibility(VISIBLE); + locationButton.setVisibility(VISIBLE); setVpnRouteText(); colorBackgroundALittle(); } else if (eipStatus.isDisconnected() && reconnectingWithDifferentGateway()) { showConnectingLayout(activity); // showRetryToast(activity); + locationButton.setText(getString(R.string.finding_best_connection)); + locationButton.setVisibility(VISIBLE); + locationButton.setLocationLoad(UNKNOWN); } else if (eipStatus.isDisconnecting()) { setMainButtonEnabled(false); showDisconnectingLayout(activity); @@ -441,18 +444,18 @@ public class EipFragment extends Fragment implements Observer { setMainButtonEnabled(true); vpnStateImage.setStateIcon(R.drawable.vpn_blocking); vpnStateImage.stopProgress(false); - routedText.setText(getString(R.string.void_vpn_establish, getString(R.string.app_name))); - routedText.setVisibility(VISIBLE); - vpnRoute.setVisibility(GONE); colorBackgroundALittle(); + locationButton.setText(getString(R.string.finding_best_connection)); + locationButton.setVisibility(VISIBLE); + locationButton.setLocationLoad(UNKNOWN); } else { - mainButton.setText(activity.getString(R.string.vpn_button_turn_on)); + locationButton.setText(activity.getString(R.string.vpn_button_turn_on)); setMainButtonEnabled(true); vpnStateImage.setStateIcon(R.drawable.vpn_disconnected); vpnStateImage.stopProgress(false); - routedText.setVisibility(GONE); - vpnRoute.setVisibility(GONE); greyscaleBackground(); + locationButton.setLocationLoad(UNKNOWN); + locationButton.setVisibility(GONE); } } @@ -494,11 +497,8 @@ public class EipFragment extends Fragment implements Observer { } private void showConnectionTransitionLayout(Context activity, boolean isConnecting) { - mainButton.setText(activity.getString(android.R.string.cancel)); vpnStateImage.setStateIcon(R.drawable.vpn_connecting); vpnStateImage.showProgress(); - routedText.setVisibility(GONE); - vpnRoute.setVisibility(GONE); if (isConnecting) { colorBackgroundALittle(); } else { @@ -574,7 +574,7 @@ public class EipFragment extends Fragment implements Observer { if (!TextUtils.isEmpty(profileName)) { vpnRouteString += " (" + profileName + ")"; } - vpnRoute.setText(vpnRouteString); + // vpnRoute.setText(vpnRouteString); } private class EipFragmentServiceConnection implements ServiceConnection { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/LocationButton.java b/app/src/main/java/se/leap/bitmaskclient/base/views/LocationButton.java new file mode 100644 index 00000000..1d7f0d18 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/views/LocationButton.java @@ -0,0 +1,44 @@ +package se.leap.bitmaskclient.base.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.LinearLayoutCompat; + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.eip.GatewaysManager; + +public class LocationButton extends LinearLayoutCompat { + private LocationIndicator locationIndicator; + private AppCompatTextView textView; + public LocationButton(@NonNull Context context) { + super(context); + initLayout(context); + } + + public LocationButton(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initLayout(context); + } + + private void initLayout(Context context) { + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View rootview = inflater.inflate(R.layout.v_location_button, this, true); + locationIndicator = rootview.findViewById(R.id.load_indicator); + textView = rootview.findViewById(R.id.text_location); + } + + public void setLocationLoad(GatewaysManager.Load load) { + locationIndicator.setLoad(load); + } + + public void setText(CharSequence text) { + textView.setText(text); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/LocationIndicator.java b/app/src/main/java/se/leap/bitmaskclient/base/views/LocationIndicator.java new file mode 100644 index 00000000..f5e3dbe2 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/views/LocationIndicator.java @@ -0,0 +1,76 @@ +package se.leap.bitmaskclient.base.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.eip.GatewaysManager; + +public class LocationIndicator extends LinearLayout { + + private View level1; + private View level2; + private View level3; + + public LocationIndicator(Context context) { + super(context); + initLayout(context); + } + + public LocationIndicator(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initLayout(context); + + } + + public LocationIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initLayout(context); + } + + + void initLayout(Context context) { + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View rootview = inflater.inflate(R.layout.v_location_status_indicator, this, true); + level1 = rootview.findViewById(R.id.level1); + level2 = rootview.findViewById(R.id.level2); + level3 = rootview.findViewById(R.id.level3); + } + + public void setLoad(GatewaysManager.Load load) { + switch (load) { + case GOOD: + level1.setBackgroundColor(getResources().getColor(R.color.green200)); + level2.setBackgroundColor(getResources().getColor(R.color.green200)); + level3.setBackgroundColor(getResources().getColor(R.color.green200)); + level1.setVisibility(VISIBLE); + level2.setVisibility(VISIBLE); + level3.setVisibility(VISIBLE); + break; + case AVERAGE: + level1.setBackgroundColor(getResources().getColor(R.color.yellow200)); + level2.setBackgroundColor(getResources().getColor(R.color.yellow200)); + level1.setVisibility(VISIBLE); + level2.setVisibility(VISIBLE); + level3.setVisibility(INVISIBLE); + break; + case CRITICAL: + level1.setBackgroundColor(getResources().getColor(R.color.red200)); + level1.setVisibility(VISIBLE); + level2.setVisibility(INVISIBLE); + level3.setVisibility(INVISIBLE); + break; + default: + level1.setVisibility(INVISIBLE); + level2.setVisibility(INVISIBLE); + level3.setVisibility(INVISIBLE); + break; + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java index 05775d13..b311315c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Random; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConfigParser; @@ -59,6 +60,37 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges; */ public class GatewaysManager { + public enum Load { + UNKNOWN(0), + GOOD(0.25), + AVERAGE(0.75), + CRITICAL(1.0); + + private final double value; + + Load(double i) { + value = i; + } + + public static Load getLoadByValue(double value) { + if (value == UNKNOWN.value) { + return UNKNOWN; + } else if (value <= GOOD.value) { + return GOOD; + } else if (value <= AVERAGE.value) { + return AVERAGE; + } else if (value <= CRITICAL.value) { + return CRITICAL; + } else { + return UNKNOWN; + } + } + + public double getValue() { + return value; + } + } + private static final String TAG = GatewaysManager.class.getSimpleName(); private Context context; @@ -117,6 +149,22 @@ public class GatewaysManager { return locations; } + public Load getLoadForLocation(@Nullable String name) { + List <Location> locations = getGatewayLocations(); + for (Location location : locations) { + if (location.name.equals(name)) { + + // fake values for now + Random rand = new Random(); + double averageLoad = rand.nextDouble(); //location.averageLoad; + return Load.getLoadByValue(averageLoad); + } + } + + // location not found + return Load.UNKNOWN; + } + private Gateway getGatewayFromTimezoneCalculation(int nClosest, Connection.TransportType transportType, @Nullable String city) { List<Gateway> list = new ArrayList<>(gateways.values()); GatewaySelector gatewaySelector = new GatewaySelector(list); @@ -326,4 +374,6 @@ public class GatewaysManager { } } + + } diff --git a/app/src/main/res/drawable/cust_button_primary_hard_rect.xml b/app/src/main/res/drawable/cust_button_primary_hard_rect.xml new file mode 100644 index 00000000..93be5c18 --- /dev/null +++ b/app/src/main/res/drawable/cust_button_primary_hard_rect.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:state_pressed="true" > + <shape android:shape="rectangle" > + <padding android:left="8dp" android:right="8dp"/> + <solid android:color="@color/colorPrimaryDark"/> + </shape> + </item> + <item android:state_focused="true"> + <shape android:shape="rectangle" > + <padding android:left="8dp" android:right="8dp"/> + <solid android:color="@color/colorPrimaryDark"/> + </shape> + </item> + <item > + <shape android:shape="rectangle" > + <padding android:left="8dp" android:right="8dp"/> + <solid android:color="@color/colorPrimary"/> + </shape> + </item> +</selector>
\ No newline at end of file diff --git a/app/src/main/res/drawable/cust_button_primary_rect.xml b/app/src/main/res/drawable/cust_button_primary_rect.xml index c83d4e62..93be5c18 100644 --- a/app/src/main/res/drawable/cust_button_primary_rect.xml +++ b/app/src/main/res/drawable/cust_button_primary_rect.xml @@ -2,21 +2,18 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true" > <shape android:shape="rectangle" > - <corners android:radius="8dp" /> <padding android:left="8dp" android:right="8dp"/> <solid android:color="@color/colorPrimaryDark"/> </shape> </item> <item android:state_focused="true"> <shape android:shape="rectangle" > - <corners android:radius="8dp" /> <padding android:left="8dp" android:right="8dp"/> <solid android:color="@color/colorPrimaryDark"/> </shape> </item> <item > <shape android:shape="rectangle" > - <corners android:radius="8dp" /> <padding android:left="8dp" android:right="8dp"/> <solid android:color="@color/colorPrimary"/> </shape> diff --git a/app/src/main/res/layout-xlarge/f_eip.xml b/app/src/main/res/layout-xlarge/f_eip.xml index d4a51b8d..bef2d635 100644 --- a/app/src/main/res/layout-xlarge/f_eip.xml +++ b/app/src/main/res/layout-xlarge/f_eip.xml @@ -80,53 +80,21 @@ app:layout_constraintTop_toTopOf="@+id/guideline_horizontal_top" app:layout_constraintDimensionRatio="1:1" /> - <androidx.appcompat.widget.AppCompatButton - android:id="@+id/vpn_main_button" - android:layout_width="wrap_content" - android:layout_height="40dp" - android:minWidth="200dp" + + <se.leap.bitmaskclient.base.views.LocationButton + android:id="@+id/gateway_location_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:layout_marginBottom="@dimen/stdpadding" android:layout_marginEnd="@dimen/stdpadding" android:layout_marginStart="@dimen/stdpadding" android:layout_marginTop="@dimen/stdpadding" android:layout_marginLeft="@dimen/stdpadding" android:layout_marginRight="@dimen/stdpadding" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" app:layout_constraintBottom_toBottomOf="@+id/background" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - android:text="@string/vpn.button.turn.on" - tools:text="Turn on in another language" - style="@style/BitmaskButtonBlack" - /> - - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/routed_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" - android:paddingStart="@dimen/stdpadding" - android:paddingEnd="@dimen/stdpadding" - android:text="@string/vpn_securely_routed" - android:gravity="center" - android:visibility="visible" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/eipLabel" /> - - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/vpn_route" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" - android:paddingStart="@dimen/stdpadding" - android:paddingEnd="@dimen/stdpadding" - android:gravity="center" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/routed_text" /> + tools:text="SEATTLE" + android:gravity="center_vertical" /> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/f_eip.xml b/app/src/main/res/layout/f_eip.xml index 3309eb5d..8dc1e33b 100644 --- a/app/src/main/res/layout/f_eip.xml +++ b/app/src/main/res/layout/f_eip.xml @@ -82,54 +82,20 @@ app:layout_constraintDimensionRatio="1:1" /> - <androidx.appcompat.widget.AppCompatButton - android:id="@+id/vpn_main_button" - android:layout_width="wrap_content" - android:layout_height="32dp" - android:minWidth="150dp" + <se.leap.bitmaskclient.base.views.LocationButton + android:id="@+id/gateway_location_button" + android:layout_width="match_parent" + android:layout_height="64dp" android:layout_marginBottom="@dimen/stdpadding" android:layout_marginEnd="@dimen/stdpadding" android:layout_marginStart="@dimen/stdpadding" android:layout_marginTop="@dimen/stdpadding" android:layout_marginLeft="@dimen/stdpadding" android:layout_marginRight="@dimen/stdpadding" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" app:layout_constraintBottom_toBottomOf="@+id/background" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - android:text="@string/vpn.button.turn.on" - tools:text="Turn on in another language" - style="@style/BitmaskButtonBlack" - /> - - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/routed_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" - android:paddingStart="@dimen/stdpadding" - android:paddingEnd="@dimen/stdpadding" - android:paddingTop="@dimen/stdpadding" - android:text="@string/vpn_securely_routed" - android:gravity="center" - android:visibility="visible" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/eipLabel" /> - - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/vpn_route" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="@dimen/stdpadding" - android:paddingRight="@dimen/stdpadding" - android:paddingStart="@dimen/stdpadding" - android:paddingEnd="@dimen/stdpadding" - android:gravity="center" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/routed_text" /> + tools:text="SEATTLE" + android:gravity="center_vertical" /> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/v_location_button.xml b/app/src/main/res/layout/v_location_button.xml new file mode 100644 index 00000000..7425231e --- /dev/null +++ b/app/src/main/res/layout/v_location_button.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_gravity="center_vertical" + android:clickable="true" + android:focusable="true" + android:padding="@dimen/stdpadding" + android:background="@drawable/cust_button_primary_rect" + android:layout_height="wrap_content"> + + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/text_location" + android:padding="@dimen/stdpadding" + android:layout_weight="1" + android:layout_width="0dp" + android:maxLines="1" + android:ellipsize="end" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:textAppearance="@style/TextAppearance.AppCompat.Large" + android:textStyle="bold" + android:textColor="@color/white" + tools:text="Seattle" + /> + + <se.leap.bitmaskclient.base.views.LocationIndicator + android:id="@+id/load_indicator" + android:layout_width="48dp" + android:layout_height="match_parent" + android:visibility="visible" + android:layout_gravity="center_vertical" + /> + + + +</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file diff --git a/app/src/main/res/layout/v_location_status_indicator.xml b/app/src/main/res/layout/v_location_status_indicator.xml new file mode 100644 index 00000000..97b55917 --- /dev/null +++ b/app/src/main/res/layout/v_location_status_indicator.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:weightSum="100" + android:layout_margin="8dp" + > + + <View + android:id="@+id/level3" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="30" + android:background="@color/green200" + android:visibility="invisible" + /> + + <Space + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="5" + /> + + <View + android:id="@+id/level2" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="30" + android:background="@color/green200" + android:visibility="invisible" + /> + + <Space + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="5" + /> + + <View + android:id="@+id/level1" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="30" + android:background="@color/green200" + android:visibility="invisible" + /> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 22696c12..b6bdafa8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,7 +155,8 @@ <string name="gateway_selection_best_location">Location with best connection</string> <string name="gateway_selection_automatic">Automatic</string> <string name="gateway_selection_current_location">Your traffic is currently routed through: </string> - + <string name="finding_best_connection">Finding best connection…</string> + <string name="reconnecting">Reconnecting…</string> <string name="tor_starting">Starting bridges for censorship circumvention…</string> <string name="tor_stopping">Stopping bridges.</string> <string name="tor_started">Using bridges for censorship circumvention.</string> @@ -181,5 +182,4 @@ <string name="hide_connection_details">Hide connection details</string> <string name="error_network_connection">%s has no internet connection. Please check your WiFi and cellular data settings.</string> - </resources> |