Reviewed-on: https://git.bubblev.org/bubblev/bubble-droid/pulls/13pull/14/head
@@ -1,20 +1,16 @@ | |||
package com.wireguard.android.activity; | |||
import android.content.Context; | |||
import android.os.Bundle; | |||
import android.os.Handler; | |||
import android.view.Gravity; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.view.ViewGroup; | |||
import android.widget.Toast; | |||
import com.wireguard.android.R; | |||
import com.wireguard.android.fragment.ErrorDialogFragment; | |||
import com.wireguard.android.fragment.LoadingDialogFragment; | |||
import java.net.ConnectException; | |||
import java.net.UnknownHostException; | |||
import androidx.annotation.Nullable; | |||
import androidx.appcompat.app.AppCompatActivity; | |||
import androidx.lifecycle.Lifecycle; | |||
@@ -23,10 +19,12 @@ public class BaseActivityBubble extends AppCompatActivity { | |||
public static final String LOADING_TAG = "loading_tag"; | |||
public static final String NO_CONNECTION_TAG = "no_connection_tag"; | |||
public static final String ERROR_TAG = "error_tag"; | |||
public static final String RATE_TAG = "rate tag"; | |||
private final long LOADER_DELAY = 1000; | |||
private LoadingDialogFragment loadingDialog; | |||
private ErrorDialogFragment errorDialog; | |||
private boolean showDialog = true; | |||
@Override | |||
@@ -80,4 +78,12 @@ public class BaseActivityBubble extends AppCompatActivity { | |||
toast.show(); | |||
} | |||
public void showErrorDialog(String message){ | |||
errorDialog = ErrorDialogFragment.newInstance(); | |||
final Bundle bundle = new Bundle(); | |||
bundle.putString("message",message); | |||
errorDialog.setArguments(bundle); | |||
getSupportFragmentManager().beginTransaction().add(errorDialog,ERROR_TAG).commitAllowingStateLoss(); | |||
} | |||
} |
@@ -200,8 +200,9 @@ public class LoginActivity extends BaseActivityBubble { | |||
if(userStatusResource.message.equals(NO_INTERNET_CONNECTION)){ | |||
showNetworkNotAvailableMessage(); | |||
} | |||
Toast.makeText(LoginActivity.this, getString(R.string.login_failed), Toast.LENGTH_SHORT).show(); | |||
Log.d("TAG", "Error"); | |||
else { | |||
showErrorDialog(userStatusResource.message); | |||
} | |||
break; | |||
} | |||
} | |||
@@ -0,0 +1,72 @@ | |||
package com.wireguard.android.fragment; | |||
import android.content.Intent; | |||
import android.net.Uri; | |||
import android.os.Bundle; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.view.View.OnClickListener; | |||
import android.view.ViewGroup; | |||
import com.wireguard.android.R; | |||
import androidx.annotation.NonNull; | |||
import androidx.annotation.Nullable; | |||
import androidx.appcompat.widget.AppCompatButton; | |||
import androidx.fragment.app.DialogFragment; | |||
public class ErrorDialogFragment extends DialogFragment { | |||
private AppCompatButton contactSupportButton; | |||
public static ErrorDialogFragment newInstance() { | |||
ErrorDialogFragment fragment = new ErrorDialogFragment(); | |||
Bundle args = new Bundle(); | |||
fragment.setArguments(args); | |||
return fragment; | |||
} | |||
@Override | |||
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |||
Bundle savedInstanceState) { | |||
return inflater.inflate(R.layout.error_layout, container, false); | |||
} | |||
@Override | |||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { | |||
super.onViewCreated(view, savedInstanceState); | |||
Bundle bundle = getArguments(); | |||
String message = ""; | |||
if(bundle!=null){ | |||
message = bundle.getString("message"); | |||
} | |||
initUI(view,message); | |||
} | |||
private void initUI(View view, String message) { | |||
initViews(view); | |||
initListeners(message); | |||
} | |||
private void initViews(View view) { | |||
contactSupportButton = view.findViewById(R.id.contactSupportButton); | |||
} | |||
private void initListeners(String message) { | |||
contactSupportButton.setOnClickListener(new OnClickListener() { | |||
@Override public void onClick(final View v) { | |||
sendEmail(message); | |||
} | |||
}); | |||
} | |||
private void sendEmail(String message){ | |||
final Intent send = new Intent(Intent.ACTION_SENDTO); | |||
final String uriText = "mailto:" + Uri.encode("support@getbubblenow.com") + | |||
"?subject=" + Uri.encode("Error Message") + | |||
"&body=" + Uri.encode(message); | |||
final Uri uri = Uri.parse(uriText); | |||
send.setData(uri); | |||
startActivity(Intent.createChooser(send, "Send Error")); | |||
} | |||
} |
@@ -33,6 +33,7 @@ import java.io.InputStream; | |||
import java.net.ConnectException; | |||
import java.net.UnknownHostException; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Scanner; | |||
@@ -49,10 +50,15 @@ import io.reactivex.disposables.CompositeDisposable; | |||
import io.reactivex.disposables.Disposable; | |||
import io.reactivex.schedulers.Schedulers; | |||
import okhttp3.Callback; | |||
import okhttp3.Headers; | |||
import okhttp3.HttpUrl; | |||
import okhttp3.OkHttpClient; | |||
import okhttp3.Request; | |||
import okhttp3.RequestBody; | |||
import okhttp3.Response; | |||
import okio.Buffer; | |||
import retrofit2.Call; | |||
import retrofit2.HttpException; | |||
public class DataRepository { | |||
private static volatile DataRepository instance; | |||
@@ -468,5 +474,29 @@ public class DataRepository { | |||
if( throwable instanceof UnknownHostException || throwable instanceof ConnectException){ | |||
liveData.postMutableLiveData(StatusResource.error(NO_INTERNET_CONNECTION)); | |||
} | |||
if(throwable instanceof HttpException){ | |||
if(((HttpException) throwable).code() == 500){ | |||
final String requestURL = ((HttpException) throwable).response().raw().request().url().toString(); | |||
final String requestMethod = ((HttpException) throwable).response().raw().request().method(); | |||
final String requestBody = bodyToString(((HttpException) throwable).response().raw().request()); | |||
final String stackTrace = Arrays.toString(throwable.getStackTrace()); | |||
final String message = "URL:" + requestURL + '\n' + | |||
"BODY:" + requestBody + '\n' + | |||
"METHOD:" + requestMethod + '\n' + | |||
"STACK_TRACE:" + stackTrace; | |||
liveData.postMutableLiveData(StatusResource.error(message)); | |||
} | |||
} | |||
} | |||
private String bodyToString(final Request request){ | |||
try { | |||
final Request copy = request.newBuilder().build(); | |||
final Buffer buffer = new Buffer(); | |||
copy.body().writeTo(buffer); | |||
return buffer.readUtf8(); | |||
} catch (final IOException e) { | |||
return "did not work"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<item> | |||
<shape android:shape="rectangle"> | |||
<gradient android:endColor="#701C79" android:startColor="#BC36BD" android:centerColor="#8F2695"/> | |||
<corners android:radius="100dp" /> | |||
</shape> | |||
</item> | |||
</selector> |
@@ -0,0 +1,79 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" | |||
android:layout_width="match_parent" | |||
android:background="@color/white" | |||
android:layout_height="match_parent"> | |||
<TextView | |||
android:id="@+id/textView" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="@dimen/margin_start_and_end" | |||
android:layout_marginTop="49dp" | |||
android:layout_marginEnd="@dimen/margin_start_and_end" | |||
android:fontFamily="@font/josefin_sans" | |||
android:text="@string/error_title" | |||
android:textAlignment="center" | |||
android:textColor="@color/black" | |||
android:textSize="@dimen/bubble_connection_title_text_size" | |||
android:textStyle="bold" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<ImageView | |||
android:layout_width="430dp" | |||
android:layout_height="430dp" | |||
android:layout_marginStart="@dimen/margin_start_and_end" | |||
android:layout_marginTop="200dp" | |||
android:layout_marginEnd="@dimen/margin_start_and_end" | |||
android:scaleType="fitXY" | |||
android:src="@drawable/error_face" | |||
app:layout_constraintBottom_toBottomOf="@+id/error_constraints" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView" /> | |||
<LinearLayout | |||
android:id="@+id/linearLayout" | |||
android:layout_width="@dimen/edit_text_width" | |||
android:layout_height="@dimen/edit_text_height" | |||
android:layout_marginStart="@dimen/margin_start_and_end" | |||
android:layout_marginEnd="@dimen/margin_start_and_end" | |||
android:layout_marginBottom="33dp" | |||
android:background="@android:color/transparent" | |||
android:orientation="vertical" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent"> | |||
<androidx.appcompat.widget.AppCompatButton | |||
android:id="@+id/contactSupportButton" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:background="@drawable/contact_support" | |||
android:enabled="true" | |||
android:text="@string/contact_support" | |||
android:textAlignment="center" | |||
android:textAllCaps="false" | |||
android:textColor="@color/white" | |||
android:textSize="@dimen/text_title" /> | |||
</LinearLayout> | |||
<androidx.constraintlayout.widget.Constraints | |||
android:id="@+id/error_constraints" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="@dimen/margin_start_and_end" | |||
android:layout_marginTop="@dimen/margin_start_and_end" | |||
android:layout_marginEnd="@dimen/margin_start_and_end" | |||
android:layout_marginBottom="@dimen/margin_start_and_end" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -257,4 +257,6 @@ | |||
<string name="enter_your_bubble_name">Enter your Bubble Name</string> | |||
<string name="your_private_bubble">Your private Bubble provides \n protection on this device.</string> | |||
<string name="network_not_found">Sorry, friends. Network not currently available.</string> | |||
<string name="error_title">Sadface. We have \n encountered \n an error.</string> | |||
<string name="contact_support">CONTACT SUPPORT</string> | |||
</resources> |