mirror of
https://github.com/vernu/textbee.git
synced 2026-02-19 15:16:50 -05:00
ui(android): more app ui enhancement
This commit is contained in:
@@ -35,6 +35,9 @@ import com.vernu.sms.helpers.SharedPreferenceHelper;
|
||||
import com.vernu.sms.helpers.VersionTracker;
|
||||
import com.vernu.sms.helpers.HeartbeatManager;
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics;
|
||||
import com.google.gson.Gson;
|
||||
import okhttp3.ResponseBody;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
@@ -159,7 +162,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
|
||||
Log.d(TAG, response.toString());
|
||||
if (!response.isSuccessful()) {
|
||||
Snackbar.make(view, response.message().isEmpty() ? "An error occurred :( "+ response.code() : response.message(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(view, extractErrorMessage(response), Snackbar.LENGTH_LONG).show();
|
||||
compoundButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
@@ -257,7 +260,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
// Create radio buttons for each SIM with proper styling
|
||||
TextBeeUtils.getAvailableSimSlots(mContext).forEach(subscriptionInfo -> {
|
||||
String simInfo = "SIM " + (subscriptionInfo.getSimSlotIndex() + 1) + " (" + subscriptionInfo.getDisplayName() + ")";
|
||||
String displayName = subscriptionInfo.getDisplayName() != null ? subscriptionInfo.getDisplayName().toString() : "Unknown";
|
||||
String simInfo = displayName + " (Subscription ID: " + subscriptionInfo.getSubscriptionId() + ")";
|
||||
RadioButton radioButton = new RadioButton(mContext);
|
||||
radioButton.setText(simInfo);
|
||||
radioButton.setId(subscriptionInfo.getSubscriptionId());
|
||||
@@ -292,6 +296,44 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts error message from API response, trying multiple sources:
|
||||
* 1. Error message from response body (error field)
|
||||
* 2. Response message from HTTP headers
|
||||
* 3. Generic error with status code as fallback
|
||||
*/
|
||||
private String extractErrorMessage(Response<?> response) {
|
||||
// Try to parse error from response body
|
||||
try {
|
||||
ResponseBody errorBody = response.errorBody();
|
||||
if (errorBody != null) {
|
||||
String errorBodyString = errorBody.string();
|
||||
if (errorBodyString != null && !errorBodyString.isEmpty()) {
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
RegisterDeviceResponseDTO errorResponse = gson.fromJson(errorBodyString, RegisterDeviceResponseDTO.class);
|
||||
if (errorResponse != null && errorResponse.error != null && !errorResponse.error.isEmpty()) {
|
||||
return errorResponse.error;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If JSON parsing fails, try to extract message from raw string
|
||||
Log.d(TAG, "Could not parse error response as JSON: " + errorBodyString);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "Could not read error body: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Fall back to response message
|
||||
if (response.message() != null && !response.message().isEmpty()) {
|
||||
return response.message();
|
||||
}
|
||||
|
||||
// Final fallback to generic error with status code
|
||||
return "An error occurred :( " + response.code();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the custom radio button style to a programmatically created radio button
|
||||
*/
|
||||
@@ -391,7 +433,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
|
||||
Log.d(TAG, response.toString());
|
||||
if (!response.isSuccessful()) {
|
||||
Snackbar.make(view, response.message().isEmpty() ? "An error occurred :( "+ response.code() : response.message(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(view, extractErrorMessage(response), Snackbar.LENGTH_LONG).show();
|
||||
registerDeviceBtn.setEnabled(true);
|
||||
registerDeviceBtn.setText("Update");
|
||||
return;
|
||||
@@ -445,18 +487,18 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
Call<RegisterDeviceResponseDTO> apiCall = ApiManager.getApiService().registerDevice(newKey, registerDeviceInput);
|
||||
apiCall.enqueue(new Callback<RegisterDeviceResponseDTO>() {
|
||||
@Override
|
||||
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
|
||||
Log.d(TAG, response.toString());
|
||||
if (!response.isSuccessful()) {
|
||||
Snackbar.make(view, response.message().isEmpty() ? "An error occurred :( "+ response.code() : response.message(), Snackbar.LENGTH_LONG).show();
|
||||
registerDeviceBtn.setEnabled(true);
|
||||
registerDeviceBtn.setText("Update");
|
||||
return;
|
||||
}
|
||||
SharedPreferenceHelper.setSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_API_KEY_KEY, newKey);
|
||||
Snackbar.make(view, "Device Registration Successful :)", Snackbar.LENGTH_LONG).show();
|
||||
apiCall.enqueue(new Callback<RegisterDeviceResponseDTO>() {
|
||||
@Override
|
||||
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
|
||||
Log.d(TAG, response.toString());
|
||||
if (!response.isSuccessful()) {
|
||||
Snackbar.make(view, extractErrorMessage(response), Snackbar.LENGTH_LONG).show();
|
||||
registerDeviceBtn.setEnabled(true);
|
||||
registerDeviceBtn.setText("Update");
|
||||
return;
|
||||
}
|
||||
SharedPreferenceHelper.setSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_API_KEY_KEY, newKey);
|
||||
Snackbar.make(view, "Device Registration Successful :)", Snackbar.LENGTH_LONG).show();
|
||||
|
||||
if (response.body() != null && response.body().data != null && response.body().data.get("_id") != null) {
|
||||
deviceId = response.body().data.get("_id").toString();
|
||||
@@ -544,7 +586,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
|
||||
Log.d(TAG, response.toString());
|
||||
if (!response.isSuccessful()) {
|
||||
Snackbar.make(view, response.message().isEmpty() ? "An error occurred :( "+ response.code() : response.message(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(view, extractErrorMessage(response), Snackbar.LENGTH_LONG).show();
|
||||
registerDeviceBtn.setEnabled(true);
|
||||
registerDeviceBtn.setText("Update");
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
|
||||
<item android:color="?attr/colorPrimary" android:alpha="0.12"/>
|
||||
</selector>
|
||||
5
android/app/src/main/res/color/button_text_color.xml
Normal file
5
android/app/src/main/res/color/button_text_color.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/white" android:state_enabled="true"/>
|
||||
<item android:color="@color/white" android:alpha="0.38"/>
|
||||
</selector>
|
||||
@@ -256,11 +256,11 @@
|
||||
android:id="@+id/registerDeviceBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:backgroundTint="@color/button_background_tint"
|
||||
android:paddingHorizontal="28dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:text="Connect"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text_color"
|
||||
android:textSize="15sp"
|
||||
android:letterSpacing="0.01"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
@@ -334,24 +334,15 @@
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="REQUIRED for textbee to function!"
|
||||
android:textColor="@android:color/holo_red_dark"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/grantSMSPermissionBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:backgroundTint="@color/button_background_tint"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:text="Grant SMS Permissions"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@color/button_text_color"
|
||||
android:textSize="15sp"
|
||||
android:letterSpacing="0.01"
|
||||
android:visibility="visible"
|
||||
@@ -473,10 +464,11 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="Select your preferred SIM for sending SMS"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:text="This is the default SIM that will be used for sending SMS. You can override for individual SMS by providing the specific simSubscriptionId in your API request."
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="14sp"
|
||||
android:lineSpacingMultiplier="1.2" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/defaultSimSlotRadioGroup"
|
||||
|
||||
Reference in New Issue
Block a user