Compare commits
No commits in common. "main" and "v2024.12.26" have entirely different histories.
main
...
v2024.12.2
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -4,10 +4,10 @@
|
|||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-09-05T19:18:31.537268933Z">
|
||||
<DropdownSelection timestamp="2024-12-25T13:45:31.415609709Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/home/nicolas/.android/avd/Pixel_6_Pro_API_34.avd" />
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=ZY22FN7MHQ" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ plugins {
|
|||
|
||||
android {
|
||||
namespace 'com.example.dcav2gui'
|
||||
compileSdk 35
|
||||
compileSdk 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.dcav2gui"
|
||||
minSdk 24
|
||||
targetSdk 35
|
||||
targetSdk 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
|
|
@ -42,9 +42,7 @@ dependencies {
|
|||
implementation libs.navigation.ui
|
||||
implementation libs.gson
|
||||
implementation libs.recyclerview
|
||||
implementation libs.biometric
|
||||
implementation libs.activity
|
||||
implementation libs.fragment
|
||||
//implementation libs.okhttp
|
||||
implementation libs.okhttp.v492
|
||||
implementation libs.firebase.crashlytics.buildtools
|
||||
testImplementation libs.junit
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
|
|
|||
|
|
@ -1,988 +0,0 @@
|
|||
package com.example.dcav2gui;
|
||||
|
||||
import static com.example.dcav2gui.MainActivity.globalSettings;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.InputType;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.dcav2gui.ui.earners.EarnerData;
|
||||
import com.example.dcav2gui.ui.home.HomeFragment;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class EarnerInterface {
|
||||
|
||||
private static final String API_BASE_URL = globalSettings.apiUrl;
|
||||
private static final String API_KEY = globalSettings.earnApiKey;
|
||||
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||
|
||||
|
||||
public static void sendRequestGlobalData(Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
EarnerGlobalData result = getEarnerGlobalData(true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showSimpleDialog("Global data", result.toString(), context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get global status", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestTotalBalance(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getTotalBalance(exchange, true);
|
||||
String dialogTitle = "Balances";
|
||||
String dialogMessage = "Trading balance: " + result.get("trading_balance").getAsString() +
|
||||
" | Earning balance " + result.get("earning_balance").getAsString();
|
||||
new Handler(Looper.getMainLooper()).post(() -> showSimpleDialog(dialogTitle, dialogMessage, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get total balance", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestGetStepSize(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getStepSize(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get step size", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestGetPercentage(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getPercentage(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get percentage", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestLastSubscription(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getLastSubscription(exchange, true);
|
||||
String dialogTitle = "Last subscription";
|
||||
String dialogMessage = HomeFragment.timeStampConverter(result.get("last_subscription").getAsJsonObject().get(exchange).getAsDouble(),false);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showSimpleDialog(dialogTitle, dialogMessage, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get last subscription", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestLastRedemption(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getLastRedemption(exchange, true);
|
||||
String dialogTitle = "Last redemption";
|
||||
String dialogMessage = HomeFragment.timeStampConverter(result.get("last_redemption").getAsJsonObject().get(exchange).getAsDouble(),false);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showSimpleDialog(dialogTitle, dialogMessage, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get last redemption", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestGetTimeBetweenSubscriptions(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getTimeBetweenSubscriptions(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get time between subscriptions", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestGetTimeBetweenRedemptions(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getTimeBetweenRedemptions(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get time between redemptions", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestGetMinimumAmountInTradingAccount(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = getMinimumAmountInTradingAccount(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to get minimum amount in trading account", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestTogglePause(String exchange, Context context) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject result = togglePause(exchange, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> showJsonDialog(result, context));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, "Failed to toggle pause", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static void sendRequestSetStepSize(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Change step size on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double amountToAdd = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = setStepSize(exchange, amountToAdd,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to change step size: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestSetPercentage(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Change percentage on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double newPercentage = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = setPercentage(exchange, newPercentage,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to change percentage: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestSetTimeBetweenSubscriptions(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Change time between subscriptions on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double newTime = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = setTimeBetweenSubscriptions(exchange, newTime,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to change time between subscriptions: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestSetTimeBetweenRedemptions(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Change time between redemptions on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double newTime = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = setTimeBetweenRedemptions(exchange, newTime,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to change time between redemptions: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestSetMinimumAmountInTradingAccount(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Change minimum amount in trading account on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double minimumAmount = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = setMinimumAmountInTradingAccount(exchange, minimumAmount,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to change minimum amount in trading account: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestSubscribeFunds(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Subscribe funds on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double amountToSubscribe = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = subscribeFunds(exchange, amountToSubscribe,true,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to subscribe funds: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendRequestRedeemFunds(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Redeem funds on "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Set", (dialog, which) -> {
|
||||
final double amountToRedeem = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = redeemFunds(exchange, amountToRedeem,true,true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showJsonDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to redeem funds: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static EarnerGlobalData getEarnerGlobalData(boolean retry) throws IOException {
|
||||
double uptime = 0.0;
|
||||
List<EarnerData> earnerList = new ArrayList<>();
|
||||
|
||||
Request getEarnerGlobalDataRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_global_status")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getEarnerGlobalDataResponse = httpClient.newCall(getEarnerGlobalDataRequest).execute()) {
|
||||
if (!getEarnerGlobalDataResponse.isSuccessful()) {
|
||||
if (getEarnerGlobalDataResponse.code() == 503 && retry) {
|
||||
return getEarnerGlobalData(false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getEarnerGlobalDataResponse);
|
||||
}
|
||||
String getEarnerGlobalDataResponseBody = getEarnerGlobalDataResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getEarnerGlobalDataResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String key : jsonObject.keySet()) {
|
||||
if (key.equals("uptime")) {
|
||||
uptime = jsonObject.get(key).getAsDouble();
|
||||
} else {
|
||||
JsonObject jsonEarner = jsonObject.get(key).getAsJsonObject();
|
||||
earnerList.add(new EarnerData(
|
||||
key,
|
||||
jsonEarner.get("trading_balance").getAsDouble(),
|
||||
jsonEarner.get("earning_balance").getAsDouble(),
|
||||
jsonEarner.get("is_paused").getAsBoolean(),
|
||||
jsonEarner.get("step_size").getAsDouble(),
|
||||
jsonEarner.get("percentage").getAsDouble(),
|
||||
jsonEarner.get("minimum_amount_in_trading_account").getAsDouble(),
|
||||
jsonEarner.get("time_between_subscriptions").getAsDouble(),
|
||||
jsonEarner.get("time_between_redemptions").getAsDouble(),
|
||||
jsonEarner.get("last_subscription").getAsJsonObject(),
|
||||
jsonEarner.get("last_redemption").getAsJsonObject()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new EarnerGlobalData(uptime, earnerList);
|
||||
}
|
||||
|
||||
public static JsonObject togglePause(String exchange, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request togglePauseRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/toggle_pause")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response togglePauseResponse = httpClient.newCall(togglePauseRequest).execute()) {
|
||||
if (!togglePauseResponse.isSuccessful()) {
|
||||
if (togglePauseResponse.code() == 503 && retry) {
|
||||
return togglePause(exchange, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + togglePauseResponse);
|
||||
}
|
||||
String togglePauseResponseBody = togglePauseResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(togglePauseResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"Status": true|false }
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getStepSize(String exchange, boolean retry) throws IOException {
|
||||
Request getStepSizeRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_step_size?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getStepSizeResponse = httpClient.newCall(getStepSizeRequest).execute()) {
|
||||
if (!getStepSizeResponse.isSuccessful()) {
|
||||
if (getStepSizeResponse.code() == 503 && retry) {
|
||||
return getStepSize(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getStepSizeResponse);
|
||||
}
|
||||
String getStepSizeResponseBody = getStepSizeResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getStepSizeResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject setStepSize(String exchange, double stepSize, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("new_step_size", stepSize);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request setStepSizeRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/set_step_size")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response setStepSizeResponse = httpClient.newCall(setStepSizeRequest).execute()) {
|
||||
if (!setStepSizeResponse.isSuccessful()) {
|
||||
if (setStepSizeResponse.code() == 503 && retry) {
|
||||
return setStepSize(exchange, stepSize, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + setStepSizeResponse);
|
||||
}
|
||||
String setStepSizeResponseBody = setStepSizeResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(setStepSizeResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"step_size": stepSize }
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getPercentage(String exchange, boolean retry) throws IOException {
|
||||
Request getPercentageRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_percentage?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getPercentageResponse = httpClient.newCall(getPercentageRequest).execute()) {
|
||||
if (!getPercentageResponse.isSuccessful()) {
|
||||
if (getPercentageResponse.code() == 503 && retry) {
|
||||
return getPercentage(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getPercentageResponse);
|
||||
}
|
||||
String getPercentageResponseBody = getPercentageResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getPercentageResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject setPercentage(String exchange, double newPercentage, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("new_percentage", newPercentage);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request setPercentageRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/set_percentage")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response setPercentageResponse = httpClient.newCall(setPercentageRequest).execute()) {
|
||||
if (!setPercentageResponse.isSuccessful()) {
|
||||
if (setPercentageResponse.code() == 503 && retry) {
|
||||
return setPercentage(exchange, newPercentage, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + setPercentageResponse);
|
||||
}
|
||||
String setPercentageResponseBody = setPercentageResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(setPercentageResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"percentage": newPercentage }
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getTimeBetweenSubscriptions(String exchange, boolean retry) throws IOException {
|
||||
Request getTimeBetweenSubscriptionsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_time_between_subscriptions?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getTimeBetweenSubscriptionsResponse = httpClient.newCall(getTimeBetweenSubscriptionsRequest).execute()) {
|
||||
if (!getTimeBetweenSubscriptionsResponse.isSuccessful()) {
|
||||
if (getTimeBetweenSubscriptionsResponse.code() == 503 && retry) {
|
||||
return getTimeBetweenSubscriptions(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getTimeBetweenSubscriptionsResponse);
|
||||
}
|
||||
String getTimeBetweenSubscriptionsResponseBody = getTimeBetweenSubscriptionsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getTimeBetweenSubscriptionsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject setTimeBetweenSubscriptions(String exchange, double newTime, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("new_time_between_subscriptions", newTime);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request setTimeBetweenSubscriptionsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/set_time_between_subscriptions")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response setTimeBetweenSubscriptionsResponse = httpClient.newCall(setTimeBetweenSubscriptionsRequest).execute()) {
|
||||
if (!setTimeBetweenSubscriptionsResponse.isSuccessful()) {
|
||||
if (setTimeBetweenSubscriptionsResponse.code() == 503 && retry) {
|
||||
return setTimeBetweenSubscriptions(exchange, newTime, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + setTimeBetweenSubscriptionsResponse);
|
||||
}
|
||||
String setTimeBetweenSubscriptionsResponseBody = setTimeBetweenSubscriptionsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(setTimeBetweenSubscriptionsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"time_between_subscriptions": newTime }
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getTimeBetweenRedemptions(String exchange, boolean retry) throws IOException {
|
||||
Request getTimeBetweenRedemptionsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_time_between_redemptions?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getTimeBetweenRedemptionsResponse = httpClient.newCall(getTimeBetweenRedemptionsRequest).execute()) {
|
||||
if (!getTimeBetweenRedemptionsResponse.isSuccessful()) {
|
||||
if (getTimeBetweenRedemptionsResponse.code() == 503 && retry) {
|
||||
return getTimeBetweenRedemptions(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getTimeBetweenRedemptionsResponse);
|
||||
}
|
||||
String getTimeBetweenRedemptionsResponseBody = getTimeBetweenRedemptionsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getTimeBetweenRedemptionsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject setTimeBetweenRedemptions(String exchange, double newTime, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("new_time_between_redemptions", newTime);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request setTimeBetweenRedemptionsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/set_time_between_redemptions")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response setTimeBetweenRedemptionsResponse = httpClient.newCall(setTimeBetweenRedemptionsRequest).execute()) {
|
||||
if (!setTimeBetweenRedemptionsResponse.isSuccessful()) {
|
||||
if (setTimeBetweenRedemptionsResponse.code() == 503 && retry) {
|
||||
return setTimeBetweenRedemptions(exchange, newTime, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + setTimeBetweenRedemptionsResponse);
|
||||
}
|
||||
String setTimeBetweenRedemptionsResponseBody = setTimeBetweenRedemptionsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(setTimeBetweenRedemptionsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"time_between_redemptions": newTime }
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getMinimumAmountInTradingAccount(String exchange, boolean retry) throws IOException {
|
||||
Request getMinimumAmountInTradingAccountRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_minimum_amount_in_trading_account?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getMinimumAmountInTradingAccountResponse = httpClient.newCall(getMinimumAmountInTradingAccountRequest).execute()) {
|
||||
if (!getMinimumAmountInTradingAccountResponse.isSuccessful()) {
|
||||
if (getMinimumAmountInTradingAccountResponse.code() == 503 && retry) {
|
||||
return getMinimumAmountInTradingAccount(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getMinimumAmountInTradingAccountResponse);
|
||||
}
|
||||
String getMinimumAmountInTradingAccountResponseBody = getMinimumAmountInTradingAccountResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getMinimumAmountInTradingAccountResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject setMinimumAmountInTradingAccount(String exchange, double minAmount, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("new_minimum_amount_in_trading_account", minAmount);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request setMinimumAmountInTradingAccountRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/set_minimum_amount_in_trading_account")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response setMinimumAmountInTradingAccountResponse = httpClient.newCall(setMinimumAmountInTradingAccountRequest).execute()) {
|
||||
if (!setMinimumAmountInTradingAccountResponse.isSuccessful()) {
|
||||
if (setMinimumAmountInTradingAccountResponse.code() == 503 && retry) {
|
||||
return setMinimumAmountInTradingAccount(exchange, minAmount, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + setMinimumAmountInTradingAccountResponse);
|
||||
}
|
||||
String setMinimumAmountInTradingAccountResponseBody = setMinimumAmountInTradingAccountResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(setMinimumAmountInTradingAccountResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"minimum_amount_in_trading_account": minAmount}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getLastSubscription(String exchange, boolean retry) throws IOException {
|
||||
Request getLastSubscriptionRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_last_subscription?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getLastSubscriptionResponse = httpClient.newCall(getLastSubscriptionRequest).execute()) {
|
||||
if (!getLastSubscriptionResponse.isSuccessful()) {
|
||||
if (getLastSubscriptionResponse.code() == 503 && retry) {
|
||||
return getLastSubscription(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getLastSubscriptionResponse);
|
||||
}
|
||||
String getLastSubscriptionResponseBody = getLastSubscriptionResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getLastSubscriptionResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getLastRedemption(String exchange, boolean retry) throws IOException {
|
||||
Request getLastRedemptionRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_last_redemption?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getLastRedemptionResponse = httpClient.newCall(getLastRedemptionRequest).execute()) {
|
||||
if (!getLastRedemptionResponse.isSuccessful()) {
|
||||
if (getLastRedemptionResponse.code() == 503 && retry) {
|
||||
return getLastRedemption(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getLastRedemptionResponse);
|
||||
}
|
||||
String getLastRedemptionResponseBody = getLastRedemptionResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getLastRedemptionResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject getTotalBalance(String exchange, boolean retry) throws IOException {
|
||||
Request getTotalBalanceRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_total_balance?broker=" + exchange)
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.build();
|
||||
try (Response getTotalBalanceResponse = httpClient.newCall(getTotalBalanceRequest).execute()) {
|
||||
if (!getTotalBalanceResponse.isSuccessful()) {
|
||||
if (getTotalBalanceResponse.code() == 503 && retry) {
|
||||
return getTotalBalance(exchange,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + getTotalBalanceResponse);
|
||||
}
|
||||
String getTotalBalanceResponseBody = getTotalBalanceResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(getTotalBalanceResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
return jsonElement.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject subscribeFunds(String exchange, double amount, boolean forcePause, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("amount", amount);
|
||||
jsonPayload.addProperty("force_pause", forcePause);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request subscribeFundsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/subscribe")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response subscribeFundsResponse = httpClient.newCall(subscribeFundsRequest).execute()) {
|
||||
if (!subscribeFundsResponse.isSuccessful()) {
|
||||
if (subscribeFundsResponse.code() == 503 && retry) {
|
||||
return subscribeFunds(exchange, amount, forcePause,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + subscribeFundsResponse);
|
||||
}
|
||||
String subscribeFundsResponseBody = subscribeFundsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(subscribeFundsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no errors in the request, the response is {"Success": 0 (success) | 1 (earner error)}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject redeemFunds(String exchange, double amount, boolean forcePause, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("broker", exchange);
|
||||
jsonPayload.addProperty("amount", amount);
|
||||
jsonPayload.addProperty("force_pause", forcePause);
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request redeemFundsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/redeem")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response redeemFundsResponse = httpClient.newCall(redeemFundsRequest).execute()) {
|
||||
if (!redeemFundsResponse.isSuccessful()) {
|
||||
if (redeemFundsResponse.code() == 503 && retry) {
|
||||
return redeemFunds(exchange, amount, forcePause,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + redeemFundsResponse);
|
||||
}
|
||||
String redeemFundsResponseBody = redeemFundsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(redeemFundsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no errors in the request, the response is {"Success": 0 (success) | 1 (earner error)}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void showSimpleDialog(String title, String message, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(message);
|
||||
builder.setPositiveButton("OK", null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static void showJsonDialog(JsonObject result, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
for (String key: result.keySet()) {
|
||||
builder.setTitle(key);
|
||||
builder.setMessage(result.get(key).getAsString());
|
||||
}
|
||||
builder.setPositiveButton("OK", null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static class EarnerGlobalData {
|
||||
private final double uptime;
|
||||
private final List<EarnerData> earnerList;
|
||||
|
||||
public EarnerGlobalData(double uptime, List<EarnerData> earnerList) {
|
||||
this.uptime = uptime;
|
||||
this.earnerList = earnerList;
|
||||
}
|
||||
|
||||
public double getUptime() {
|
||||
return uptime;
|
||||
}
|
||||
|
||||
public List<EarnerData> getEarnerList() {
|
||||
return earnerList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2,12 +2,9 @@ package com.example.dcav2gui;
|
|||
|
||||
import static com.example.dcav2gui.MainActivity.globalSettings;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
|
@ -19,20 +16,16 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
|
||||
public class InstanceInterface {
|
||||
private static final String API_BASE_URL = globalSettings.apiUrl;
|
||||
private static final String API_KEY = globalSettings.apiKey;
|
||||
private static final String EARN_API_KEY = globalSettings.earnApiKey;
|
||||
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||
|
||||
public static ProfitStatsData getProfitStatsData(boolean retry) throws IOException {
|
||||
|
|
@ -382,45 +375,6 @@ public class InstanceInterface {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static JsonObject modDefaultOrderSize(String exchange, double newOrderSize, boolean retry) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("amount", String.valueOf(newOrderSize));
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request modDefaultOrderSizeRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/" + exchange + "/mod_default_order_size")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response modDefaultOrderSizeResponse = httpClient.newCall(modDefaultOrderSizeRequest).execute()) {
|
||||
if (!modDefaultOrderSizeResponse.isSuccessful()) {
|
||||
if (modDefaultOrderSizeResponse.code() == 503 && retry) {
|
||||
return modDefaultOrderSize(exchange, newOrderSize,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + modDefaultOrderSizeResponse);
|
||||
}
|
||||
String modDefaultOrderSizeResponseBody = modDefaultOrderSizeResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(modDefaultOrderSizeResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"Success": f"Success. Default order size modified to $amount}"}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getAllLogs(String exchange, boolean retry) throws IOException {
|
||||
//200 lines hard limit
|
||||
Request logRequest = new Request.Builder()
|
||||
|
|
@ -489,11 +443,7 @@ public class InstanceInterface {
|
|||
});
|
||||
CompletableFuture<Double> fundsAvailableFuture = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
if (globalSettings.useEarn) {
|
||||
return getFundsAvailableWithEarn(exchange,"USDT", true);
|
||||
} else {
|
||||
return getFundsAvailable(exchange,"USDT", true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
@ -541,40 +491,6 @@ public class InstanceInterface {
|
|||
}
|
||||
|
||||
|
||||
private static double getFundsAvailableWithEarn(String exchange, String coin, boolean retry) throws IOException {
|
||||
String parsedBroker = exchange;
|
||||
if (Objects.equals(parsedBroker, "okex")) {
|
||||
parsedBroker = "okx";
|
||||
}
|
||||
|
||||
Request fundsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/earn/get_total_balance?broker=" + parsedBroker)
|
||||
.header("X-API-KEY", EARN_API_KEY)
|
||||
.build();
|
||||
|
||||
try (Response fundsResponse = httpClient.newCall(fundsRequest).execute()) {
|
||||
if (!fundsResponse.isSuccessful()) {
|
||||
if (fundsResponse.code() == 503 && retry) {
|
||||
return getFundsAvailableWithEarn(exchange, coin, false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + fundsResponse);
|
||||
}
|
||||
String fundsResponseBody = fundsResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(fundsResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return 0.0;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (!jsonObject.has("trading_balance")) {
|
||||
System.err.println("The parsed JSON response does not contain the balances requested.");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return jsonObject.get("trading_balance").getAsDouble() + jsonObject.get("earning_balance").getAsDouble();
|
||||
}
|
||||
}
|
||||
|
||||
private static double getFundsAvailable(String exchange, String coin, boolean retry) throws IOException {
|
||||
Request fundsRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/" + exchange + "/get_balance?coin=" + coin)
|
||||
|
|
@ -694,24 +610,10 @@ public class InstanceInterface {
|
|||
double price = value.has("price") && value.get("price").isJsonPrimitive() ? value.get("price").getAsDouble() : 0.0;
|
||||
double takeProfitPrice = value.has("take_profit_price") && value.get("take_profit_price").isJsonPrimitive() ? value.get("take_profit_price").getAsDouble() : 0.0;
|
||||
double nextSoPrice = value.has("next_so_price") && value.get("next_so_price").isJsonPrimitive() ? value.get("next_so_price").getAsDouble() : 0.0;
|
||||
JsonObject takeProfitOrder = null;
|
||||
String tpOrderId = "";
|
||||
JsonArray safetyOrders = null;
|
||||
String safetyOrderId = "";
|
||||
JsonElement takeProfitOrderElement = value.get("take_profit_order");
|
||||
if (takeProfitOrderElement!=null && !takeProfitOrderElement.isJsonNull() && takeProfitOrderElement.isJsonObject()) {
|
||||
takeProfitOrder = takeProfitOrderElement.getAsJsonObject();
|
||||
tpOrderId = takeProfitOrder.has("id") && takeProfitOrder.get("id").isJsonPrimitive() ? takeProfitOrder.get("id").getAsString() : "";
|
||||
}
|
||||
JsonElement safetyOrderElements = value.get("safety_orders");
|
||||
if (safetyOrderElements!=null && !safetyOrderElements.isJsonNull() && safetyOrderElements.isJsonArray()) {
|
||||
safetyOrders = safetyOrderElements.getAsJsonArray();
|
||||
if (!safetyOrders.isEmpty()) {
|
||||
JsonObject firstSafetyOrder = safetyOrders.get(0).getAsJsonObject();
|
||||
safetyOrderId = firstSafetyOrder.has("id") && firstSafetyOrder.get("id").isJsonPrimitive() ? firstSafetyOrder.get("id").getAsString() : "";
|
||||
}
|
||||
}
|
||||
int safetyOrdersFilled = value.has("safety_orders_filled") && value.get("safety_orders_filled").isJsonPrimitive() ? value.get("safety_orders_filled").getAsInt() : 0;
|
||||
String tpOrderId = value.has("tp_order_id") && value.get("tp_order_id").isJsonPrimitive() ? value.get("tp_order_id").getAsString() : null;
|
||||
JsonObject takeProfitOrder = value.get("take_profit_order").getAsJsonObject();
|
||||
String safetyOrderId = value.has("so_order_id") && value.get("so_order_id").isJsonPrimitive() ? value.get("so_order_id").getAsString() : null;
|
||||
JsonObject safetyOrder = value.get("safety_order").getAsJsonObject();
|
||||
double feesPaidInBase = value.has("fees_paid_in_base") && value.get("fees_paid_in_base").isJsonPrimitive() ? value.get("fees_paid_in_base").getAsDouble() : 0.0;
|
||||
double feesPaidInQuote = value.has("fees_paid_in_quote") && value.get("fees_paid_in_quote").isJsonPrimitive() ? value.get("fees_paid_in_quote").getAsDouble() : 0.0;
|
||||
double partialProfit = value.has("partial_profit") && value.get("partial_profit").isJsonPrimitive() ? value.get("partial_profit").getAsDouble() : 0.0;
|
||||
|
|
@ -723,7 +625,6 @@ public class InstanceInterface {
|
|||
OldLongDictionary oldLongDictionary = null;
|
||||
if (value.has("old_long")) {
|
||||
oldLong = value.get("old_long").getAsJsonObject();
|
||||
if (!oldLong.entrySet().isEmpty()) {
|
||||
oldLongDictionary = new OldLongDictionary(
|
||||
oldLong.get("datetime").getAsString(),
|
||||
oldLong.get("fees_paid_in_quote").getAsDouble(),
|
||||
|
|
@ -732,7 +633,6 @@ public class InstanceInterface {
|
|||
oldLong.get("tp_price").getAsDouble()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
valueToReturn.add(new WorkerStatsData(
|
||||
key,
|
||||
|
|
@ -759,8 +659,7 @@ public class InstanceInterface {
|
|||
tpOrderId,
|
||||
takeProfitOrder,
|
||||
safetyOrderId,
|
||||
safetyOrders,
|
||||
safetyOrdersFilled,
|
||||
safetyOrder,
|
||||
feesPaidInBase,
|
||||
feesPaidInQuote,
|
||||
partialProfit,
|
||||
|
|
@ -771,7 +670,7 @@ public class InstanceInterface {
|
|||
statusString
|
||||
));
|
||||
} catch (Exception e) {
|
||||
System.err.println("In getAllWorkersStats: Error processing JSON for key '" + key + "': " + e.getMessage());
|
||||
System.err.println("Error processing JSON for key '" + key + "': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -892,7 +791,6 @@ public class InstanceInterface {
|
|||
WorkerData workerData = new WorkerData(
|
||||
workerStatsData.getPair(),
|
||||
workerStatsData.getSoAmount(),
|
||||
workerStatsData.getSafetyOrdersFilled(),
|
||||
workerStatsData.getNumberOfSafetyOrders(),
|
||||
workerStatsData.getDealUptime(),
|
||||
workerStatsData.getNextSoPrice(),
|
||||
|
|
@ -1103,14 +1001,14 @@ public class InstanceInterface {
|
|||
private final double dealStartTime;
|
||||
private final double dealUptime;
|
||||
private final double totalUptime;
|
||||
|
||||
private final double price;
|
||||
private final double takeProfitPrice;
|
||||
private final double nextSoPrice;
|
||||
private final String tpOrderId;
|
||||
private final JsonObject takeProfitOrder;
|
||||
private final String soOrderId;
|
||||
private final JsonArray safetyOrders;
|
||||
private final int safetyOrdersFilled;
|
||||
private final JsonObject safetyOrder;
|
||||
private final double feesPaidInBase;
|
||||
private final double feesPaidInQuote;
|
||||
private final double partialProfit;
|
||||
|
|
@ -1120,7 +1018,7 @@ public class InstanceInterface {
|
|||
private final OldLongDictionary oldLongDictionary; //Change type
|
||||
private final String statusString;
|
||||
|
||||
public WorkerStatsData(String pair, boolean isShort, boolean isBoosted, boolean isPaused, boolean autoSwitchEnabled, boolean stopWhenProfit, double orderSize, double quoteSpent, double baseBought, int soAmount, int numberOfSafetyOrders, int tpMode, String profitTable, double startTime, double startPrice, double dealStartTime, double dealUptime, double totalUptime, double price, double takeProfitPrice, double nextSoPrice, String tpOrderId, JsonObject takeProfitOrder, String soOrderId, JsonArray safetyOrders, int safetyOrdersFilled, double feesPaidInBase, double feesPaidInQuote, double partialProfit, String safetyPriceTable, String dealOrderHistory, String pauseReason, OldLongDictionary oldLong, String statusString) {
|
||||
public WorkerStatsData(String pair, boolean isShort, boolean isBoosted, boolean isPaused, boolean autoSwitchEnabled, boolean stopWhenProfit, double orderSize, double quoteSpent, double baseBought, int soAmount, int numberOfSafetyOrders, int tpMode, String profitTable, double startTime, double startPrice, double dealStartTime, double dealUptime, double totalUptime, double price, double takeProfitPrice, double nextSoPrice, String tpOrderId, JsonObject takeProfitOrder, String soOrderId, JsonObject safetyOrder, double feesPaidInBase, double feesPaidInQuote, double partialProfit, String safetyPriceTable, String dealOrderHistory, String pauseReason, OldLongDictionary oldLong, String statusString) {
|
||||
this.pair = pair;
|
||||
this.isShort = isShort;
|
||||
this.isBoosted = isBoosted;
|
||||
|
|
@ -1145,8 +1043,7 @@ public class InstanceInterface {
|
|||
this.tpOrderId = tpOrderId;
|
||||
this.takeProfitOrder = takeProfitOrder;
|
||||
this.soOrderId = soOrderId;
|
||||
this.safetyOrders = safetyOrders;
|
||||
this.safetyOrdersFilled = safetyOrdersFilled;
|
||||
this.safetyOrder = safetyOrder;
|
||||
this.feesPaidInBase = feesPaidInBase;
|
||||
this.feesPaidInQuote = feesPaidInQuote;
|
||||
this.partialProfit = partialProfit;
|
||||
|
|
@ -1180,8 +1077,7 @@ public class InstanceInterface {
|
|||
public String getTpOrderId() { return tpOrderId; }
|
||||
public JsonObject getTakeProfitOrder() { return takeProfitOrder; }
|
||||
public String getSoOrderId() { return soOrderId; }
|
||||
public JsonArray getSafetyOrders() { return safetyOrders; }
|
||||
public int getSafetyOrdersFilled() { return safetyOrdersFilled; }
|
||||
public JsonObject getSafetyOrder() { return safetyOrder; }
|
||||
public double getFeesPaidInBase() { return feesPaidInBase; }
|
||||
public double getFeesPaidInQuote() { return feesPaidInQuote; }
|
||||
public double getPartialProfit() { return partialProfit; }
|
||||
|
|
|
|||
|
|
@ -1,17 +1,7 @@
|
|||
package com.example.dcav2gui;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.biometric.BiometricManager;
|
||||
import androidx.biometric.BiometricPrompt;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;//
|
||||
|
|
@ -33,7 +23,6 @@ import com.example.dcav2gui.databinding.ActivityMainBinding;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
|
|
@ -46,11 +35,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
public static InstanceInterface.ExchangeStatsData kucoinCache;
|
||||
public static InstanceInterface.ExchangeStatsData okxCache;
|
||||
|
||||
private BiometricPrompt biometricPrompt;
|
||||
private BiometricPrompt.PromptInfo promptInfo;
|
||||
private boolean isAuthenticated = false;
|
||||
|
||||
private ActivityResultLauncher<Intent> enrollBiometricLauncher;
|
||||
|
||||
public HomeFragment.HomeCache getHomeViewCache() {
|
||||
return homeViewCache;
|
||||
|
|
@ -85,20 +70,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
registerBiometricEnrollLauncher();
|
||||
setupBiometricAuthentication();
|
||||
}
|
||||
|
||||
private void registerBiometricEnrollLauncher() {
|
||||
enrollBiometricLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
setupBiometricAuthentication();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void initializeApp() {
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
|
|
@ -127,90 +99,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupBiometricAuthentication() {
|
||||
BiometricManager biometricManager = BiometricManager.from(this);
|
||||
switch (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL)) {
|
||||
case BiometricManager.BIOMETRIC_SUCCESS:
|
||||
// Device supports biometric authentication
|
||||
setupBiometricPrompt();
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
|
||||
// No biometric features available on this device
|
||||
Toast.makeText(this, "Fingerprint authentication not available", Toast.LENGTH_LONG).show();
|
||||
initializeApp(); // Skip to app initialization
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
|
||||
// Biometric features are currently unavailable
|
||||
Toast.makeText(this, "Biometric authentication temporarily unavailable", Toast.LENGTH_LONG).show();
|
||||
initializeApp(); // Skip to app initialization
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
|
||||
// No biometrics or PIN enrolled, prompt user to set them up
|
||||
Toast.makeText(this, "No fingerprint or PIN set up on device", Toast.LENGTH_LONG).show();
|
||||
|
||||
// For API 30 and above, direct user to enroll biometrics
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
|
||||
enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
|
||||
BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL);
|
||||
try {
|
||||
enrollBiometricLauncher.launch(enrollIntent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
initializeApp(); // Skip to app initialization if enrollment activity not found
|
||||
}
|
||||
} else {
|
||||
initializeApp(); // Skip to app initialization for older Android versions
|
||||
}
|
||||
break;
|
||||
default:
|
||||
initializeApp(); // Skip to app initialization for any other case
|
||||
}
|
||||
}
|
||||
|
||||
private void setupBiometricPrompt() {
|
||||
Executor executor = ContextCompat.getMainExecutor(this);
|
||||
biometricPrompt = new BiometricPrompt(this, executor,
|
||||
new BiometricPrompt.AuthenticationCallback() {
|
||||
@Override
|
||||
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
|
||||
super.onAuthenticationError(errorCode, errString);
|
||||
Toast.makeText(getApplicationContext(), "Authentication error: " + errString, Toast.LENGTH_SHORT).show();
|
||||
// If authentication is canceled or fails multiple times, exit the app
|
||||
if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON ||
|
||||
errorCode == BiometricPrompt.ERROR_USER_CANCELED) {
|
||||
finish();
|
||||
} else {
|
||||
// For other errors, try again
|
||||
biometricPrompt.authenticate(promptInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
//Toast.makeText(getApplicationContext(), "Authentication succeeded!", Toast.LENGTH_SHORT).show();
|
||||
isAuthenticated = true;
|
||||
initializeApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed();
|
||||
Toast.makeText(getApplicationContext(), "Authentication failed", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
promptInfo = new BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle("Authenticate to access your app")
|
||||
.setSubtitle("Verify your identity")
|
||||
.setDescription("Use your fingerprint or PIN to access")
|
||||
.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL)
|
||||
.build();
|
||||
|
||||
// Start authentication
|
||||
biometricPrompt.authenticate(promptInfo);
|
||||
}
|
||||
|
||||
public static SettingsData getGlobalSettings() {
|
||||
return globalSettings;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
|||
import com.example.dcav2gui.ui.home.HomeFragment;
|
||||
import com.google.android.material.materialswitch.MaterialSwitch;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
|
@ -94,19 +93,10 @@ public class WorkerInterface {
|
|||
double price = value.has("price") && value.get("price").isJsonPrimitive() ? value.get("price").getAsDouble() : 0.0;
|
||||
double takeProfitPrice = value.has("take_profit_price") && value.get("take_profit_price").isJsonPrimitive() ? value.get("take_profit_price").getAsDouble() : 0.0;
|
||||
double nextSoPrice = value.has("next_so_price") && value.get("next_so_price").isJsonPrimitive() ? value.get("next_so_price").getAsDouble() : 0.0;
|
||||
String tpOrderId = value.has("tp_order_id") && value.get("tp_order_id").isJsonPrimitive() ? value.get("tp_order_id").getAsString() : null;
|
||||
JsonObject takeProfitOrder = value.get("take_profit_order").getAsJsonObject();
|
||||
JsonArray safetyOrders = null;
|
||||
String safetyOrderId = "";
|
||||
JsonElement safetyOrderElements = value.get("safety_orders");
|
||||
if (safetyOrderElements!=null && !safetyOrderElements.isJsonNull() && safetyOrderElements.isJsonArray()) {
|
||||
safetyOrders = safetyOrderElements.getAsJsonArray();
|
||||
if (!safetyOrders.isEmpty()) {
|
||||
JsonObject firstSafetyOrder = safetyOrders.get(0).getAsJsonObject();
|
||||
safetyOrderId = firstSafetyOrder.has("id") && firstSafetyOrder.get("id").isJsonPrimitive() ? firstSafetyOrder.get("id").getAsString() : "";
|
||||
}
|
||||
}
|
||||
int safetyOrdersFilled = value.has("safety_orders_filled") && value.get("safety_orders_filled").isJsonPrimitive() ? value.get("safety_orders_filled").getAsInt() : 0;
|
||||
String tpOrderId = takeProfitOrder.has("id") && takeProfitOrder.get("id").isJsonPrimitive() ? takeProfitOrder.get("id").getAsString() : null;
|
||||
String safetyOrderId = value.has("so_order_id") && value.get("so_order_id").isJsonPrimitive() ? value.get("so_order_id").getAsString() : null;
|
||||
JsonObject safetyOrder = value.get("safety_order").getAsJsonObject();
|
||||
double feesPaidInBase = value.has("fees_paid_in_base") && value.get("fees_paid_in_base").isJsonPrimitive() ? value.get("fees_paid_in_base").getAsDouble() : 0.0;
|
||||
double feesPaidInQuote = value.has("fees_paid_in_quote") && value.get("fees_paid_in_quote").isJsonPrimitive() ? value.get("fees_paid_in_quote").getAsDouble() : 0.0;
|
||||
double partialProfit = value.has("partial_profit") && value.get("partial_profit").isJsonPrimitive() ? value.get("partial_profit").getAsDouble() : 0.0;
|
||||
|
|
@ -118,7 +108,6 @@ public class WorkerInterface {
|
|||
InstanceInterface.OldLongDictionary oldLongDictionary = null;
|
||||
if (value.has("old_long")) {
|
||||
oldLong = value.get("old_long").getAsJsonObject();
|
||||
if (!oldLong.entrySet().isEmpty()) {
|
||||
oldLongDictionary = new InstanceInterface.OldLongDictionary(
|
||||
oldLong.get("datetime").getAsString(),
|
||||
oldLong.get("fees_paid_in_quote").getAsDouble(),
|
||||
|
|
@ -127,7 +116,6 @@ public class WorkerInterface {
|
|||
oldLong.get("tp_price").getAsDouble()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
valueToReturn = new InstanceInterface.WorkerStatsData(
|
||||
pair,
|
||||
|
|
@ -154,8 +142,7 @@ public class WorkerInterface {
|
|||
tpOrderId,
|
||||
takeProfitOrder,
|
||||
safetyOrderId,
|
||||
safetyOrders,
|
||||
safetyOrdersFilled,
|
||||
safetyOrder,
|
||||
feesPaidInBase,
|
||||
feesPaidInQuote,
|
||||
partialProfit,
|
||||
|
|
@ -650,93 +637,6 @@ public class WorkerInterface {
|
|||
}
|
||||
}
|
||||
|
||||
public static JsonObject modConcurrentSafetyOrders(String exchange, String pair, int amount, boolean retry) throws IOException {
|
||||
String[] pairBaseAndQuote = pair.split("/");
|
||||
String base = pairBaseAndQuote[0];
|
||||
String quote = pairBaseAndQuote[1];
|
||||
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("base", base);
|
||||
jsonPayload.addProperty("quote", quote);
|
||||
jsonPayload.addProperty("amount", String.valueOf(amount));
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request modConcurrentSafetyOrdersRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/" + exchange + "/mod_concurrent_safety_orders")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response modConcurrentSafetyOrdersResponse = httpClient.newCall(modConcurrentSafetyOrdersRequest).execute()) {
|
||||
if (!modConcurrentSafetyOrdersResponse.isSuccessful()) {
|
||||
if (modConcurrentSafetyOrdersResponse.code() == 503 && retry) {
|
||||
return modConcurrentSafetyOrders(exchange, pair, amount,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + modConcurrentSafetyOrdersResponse);
|
||||
}
|
||||
String modConcurrentSafetyOrdersResponseBody = modConcurrentSafetyOrdersResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(modConcurrentSafetyOrdersResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"Success": "Success. The change will take effect as new safety orders are sent or filled"}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static JsonObject modOrderSize(String exchange, String pair, double newOrderSize, boolean retry) throws IOException {
|
||||
String[] pairBaseAndQuote = pair.split("/");
|
||||
String base = pairBaseAndQuote[0];
|
||||
String quote = pairBaseAndQuote[1];
|
||||
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonPayload = new JsonObject();
|
||||
jsonPayload.addProperty("base", base);
|
||||
jsonPayload.addProperty("quote", quote);
|
||||
jsonPayload.addProperty("amount", String.valueOf(newOrderSize));
|
||||
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||
Request modOrderSizeRequest = new Request.Builder()
|
||||
.url(API_BASE_URL + "/" + exchange + "/mod_order_size")
|
||||
.header("X-API-KEY", API_KEY)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response modOrderSizeResponse = httpClient.newCall(modOrderSizeRequest).execute()) {
|
||||
if (!modOrderSizeResponse.isSuccessful()) {
|
||||
if (modOrderSizeResponse.code() == 503 && retry) {
|
||||
return modOrderSize(exchange, pair, newOrderSize,false);
|
||||
}
|
||||
throw new IOException("Unexpected code " + modOrderSizeResponse);
|
||||
}
|
||||
String modOrderSizeResponseBody = modOrderSizeResponse.body().string();
|
||||
JsonElement jsonElement = JsonParser.parseString(modOrderSizeResponseBody);
|
||||
if (!jsonElement.isJsonObject()) {
|
||||
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||
return null;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("Error")) {
|
||||
System.err.println("The parsed JSON response contains Error");
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
//If no error, the response is {"Success": "Success. The change will take effect when the next deal is started"}
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static JsonObject addSafetyOrders(String exchange, String pair, int amount, boolean retry) throws IOException {
|
||||
String[] pairBaseAndQuote = pair.split("/");
|
||||
|
|
@ -987,18 +887,11 @@ public class WorkerInterface {
|
|||
|
||||
public static void sendRemoveTraderCall(String exchange, String pair, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Remove trader from instance?");
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
input.setText(pair);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setTitle("Remove "+ pair + " from instance?");
|
||||
builder.setPositiveButton("Remove trader", (dialog, which) -> {
|
||||
final String pairToRemove = input.getText().toString();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = WorkerInterface.removeTrader(exchange, pairToRemove, true);
|
||||
JsonObject response = WorkerInterface.removeTrader(exchange, pair, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showToggleDialog(response, context);
|
||||
});
|
||||
|
|
@ -1121,77 +1014,6 @@ public class WorkerInterface {
|
|||
builder.show();
|
||||
}
|
||||
|
||||
public static void sendModifyConcurrentSafetyOrdersCall(String exchange, String pair, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Modify concurrent safety orders of "+ pair);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Modify concurrent safety orders", (dialog, which) -> {
|
||||
final int newAmount = Integer.parseInt(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = WorkerInterface.modConcurrentSafetyOrders(exchange, pair, newAmount, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showToggleDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to modify concurrent safety orders: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
|
||||
public static void sendModifyOrderSizeCall(String exchange, String pair, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Modify order size of "+ pair);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Modify", (dialog, which) -> {
|
||||
final double newOrderSize = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = WorkerInterface.modOrderSize(exchange, pair, newOrderSize, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showToggleDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to modify order size: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
|
||||
public static void sendAddSafetyOrdersCall(String exchange, String pair, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
|
@ -1305,9 +1127,6 @@ public class WorkerInterface {
|
|||
"Next safety order price: " + String.format(Locale.ROOT, numberFormat,result.getNextSoPrice()) + "\n" +
|
||||
"Take profit order ID: " + result.getTpOrderId() + "\n" +
|
||||
"Safety order ID: " + result.getSoOrderId() + "\n" +
|
||||
"Safety orders online: " + result.getSafetyOrders().size() + "\n" +
|
||||
"Safety orders filled: " + result.getSafetyOrdersFilled() + "\n" +
|
||||
"Max safety orders: " + result.getNumberOfSafetyOrders() + "\n" +
|
||||
"Short: " + result.getIsShort() + "\n" +
|
||||
"Boosted: " + result.getIsBoosted() + "\n" +
|
||||
"Paused: " + result.getIsPaused() + "\n" + isPausedExtraString +
|
||||
|
|
@ -1316,6 +1135,8 @@ public class WorkerInterface {
|
|||
"Order size: " + result.getOrderSize() + "\n" +
|
||||
"Quote in deal: " + result.getQuoteSpent() + "\n" +
|
||||
"Base in deal: " + result.getBaseBought() + "\n" +
|
||||
"Safety orders sent: " + (result.getSoAmount()-1) + "\n" +
|
||||
"Max safety orders: " + result.getNumberOfSafetyOrders() + "\n" +
|
||||
"Start time: " + HomeFragment.timeStampConverter(result.getStartTime(), false) + "\n" +
|
||||
"Total uptime: " + WorkerCardAdapter.formatSeconds(result.getTotalUptime()) + "\n" +
|
||||
"Start price: " + String.format(Locale.ROOT, numberFormat,result.getStartPrice()) + "\n" +
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
package com.example.dcav2gui.ui.earners;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.example.dcav2gui.EarnerInterface;
|
||||
import com.example.dcav2gui.R;
|
||||
import com.example.dcav2gui.WorkerInterface;
|
||||
import com.example.dcav2gui.databinding.FragmentEarnersBinding;
|
||||
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class EarnFragment extends Fragment implements EarnerCardAdapter.OnCardLongClickListener {
|
||||
private EarnerCardAdapter earnerCardAdapter;
|
||||
private TextView statusBar;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
com.example.dcav2gui.databinding.FragmentEarnersBinding binding = FragmentEarnersBinding.inflate(inflater, container, false);
|
||||
View root = binding.getRoot();
|
||||
|
||||
statusBar = root.findViewById(R.id.earners_status_bar);
|
||||
EarnerViewModel earnerViewModel = new ViewModelProvider(this).get(EarnerViewModel.class);
|
||||
earnerCardAdapter = new EarnerCardAdapter(binding.earnersCardsContainer);
|
||||
earnerCardAdapter.setOnCardLongClickListener(this);
|
||||
|
||||
earnerViewModel.getEarnerData().observe(getViewLifecycleOwner(), new Observer<EarnerInterface.EarnerGlobalData>() {
|
||||
@Override
|
||||
public void onChanged(EarnerInterface.EarnerGlobalData earnerGlobalData) {
|
||||
if (earnerGlobalData != null) {
|
||||
earnerCardAdapter.populateStatusBar(statusBar, earnerGlobalData);
|
||||
earnerCardAdapter.updateData(earnerGlobalData.getEarnerList());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardLongClick(String exchange, View view) {
|
||||
if (view != null) {
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), view);
|
||||
popupMenu.getMenuInflater().inflate(R.menu.earner_popup_menu, popupMenu.getMenu());
|
||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.earnerMenuGlobalStatus) {
|
||||
EarnerInterface.sendRequestGlobalData(getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuTotalBalance) {
|
||||
EarnerInterface.sendRequestTotalBalance(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuGetStepSize) {
|
||||
EarnerInterface.sendRequestGetStepSize(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSetStepSize) {
|
||||
EarnerInterface.sendRequestSetStepSize(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuLastSubscription) {
|
||||
EarnerInterface.sendRequestLastSubscription(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuLastRedemption) {
|
||||
EarnerInterface.sendRequestLastRedemption(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuTogglePause) {
|
||||
EarnerInterface.sendRequestTogglePause(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuGetPercentage) {
|
||||
EarnerInterface.sendRequestGetPercentage(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSetPercentage) {
|
||||
EarnerInterface.sendRequestSetPercentage(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuGetTimeBetweenSubscriptions) {
|
||||
EarnerInterface.sendRequestGetTimeBetweenSubscriptions(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSetTimeBetweenSubscriptions) {
|
||||
EarnerInterface.sendRequestSetTimeBetweenSubscriptions(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuGetTimeBetweenRedemptions) {
|
||||
EarnerInterface.sendRequestGetTimeBetweenRedemptions(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSetTimeBetweenRedemptions) {
|
||||
EarnerInterface.sendRequestSetTimeBetweenRedemptions(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuGetMinimumAmountInTradingAccount) {
|
||||
EarnerInterface.sendRequestGetMinimumAmountInTradingAccount(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSetMinimumAmountInTradingAccount) {
|
||||
EarnerInterface.sendRequestSetMinimumAmountInTradingAccount(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuSubscribe){
|
||||
EarnerInterface.sendRequestSubscribeFunds(exchange, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.earnerMenuRedeem) {
|
||||
EarnerInterface.sendRequestRedeemFunds(exchange, getContext());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
popupMenu.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
package com.example.dcav2gui.ui.earners;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.example.dcav2gui.EarnerInterface;
|
||||
import com.example.dcav2gui.InstanceInterface;
|
||||
import com.example.dcav2gui.R;
|
||||
import com.example.dcav2gui.ui.home.HomeFragment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class EarnerCardAdapter {
|
||||
|
||||
private final ViewGroup container;
|
||||
|
||||
public EarnerCardAdapter(ViewGroup container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public void updateData(List<EarnerData> earnerDataList) {
|
||||
container.removeAllViews(); // Clear existing views
|
||||
for (EarnerData earner : earnerDataList) {
|
||||
View cardView = LayoutInflater.from(container.getContext()).inflate(R.layout.earner_card, container, false);
|
||||
addCard(earner, cardView);
|
||||
container.addView(cardView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface OnCardLongClickListener {
|
||||
void onCardLongClick(String exchange, View v);
|
||||
}
|
||||
|
||||
private EarnerCardAdapter.OnCardLongClickListener onCardLongClickListener;
|
||||
|
||||
public void setOnCardLongClickListener(EarnerCardAdapter.OnCardLongClickListener listener) {
|
||||
this.onCardLongClickListener = listener;
|
||||
}
|
||||
|
||||
private void addCard(EarnerData earner, View view) {
|
||||
TextView broker = view.findViewById(R.id.earnerCardExchange);
|
||||
TextView tradingBalance = view.findViewById(R.id.earnerCardTradingBalanceValue);
|
||||
TextView earningBalance = view.findViewById(R.id.earnerCardEarningBalanceValue);
|
||||
TextView percentage = view.findViewById(R.id.earnerCardPercentage);
|
||||
TextView lastSubscription = view.findViewById(R.id.earnerCardLastSubscriptionDateTime);
|
||||
TextView lastRedemption = view.findViewById(R.id.earnerCardLastRedemptionDateTime);
|
||||
LinearLayout cardLayout = view.findViewById(R.id.earnerCard);
|
||||
|
||||
if (broker == null || tradingBalance == null || earningBalance == null || lastSubscription == null ||
|
||||
lastRedemption == null || percentage == null ||cardLayout == null) {
|
||||
System.out.println("One or more views are null");
|
||||
return;
|
||||
}
|
||||
|
||||
broker.setText(earner.getBrokerName().toUpperCase(Locale.ROOT));
|
||||
tradingBalance.setText(String.format(Locale.ROOT,"%.2f", earner.getTradingBalance()));
|
||||
earningBalance.setText(String.format(Locale.ROOT, "%.2f", earner.getEarningBalance()));
|
||||
double occupation = earner.getEarningBalance()/(earner.getEarningBalance() + earner.getTradingBalance()) * 100;
|
||||
String percentageString = String.format(Locale.ROOT, "%.2f", occupation) + "%";
|
||||
percentage.setText(percentageString);
|
||||
|
||||
lastSubscription.setText(HomeFragment.timeStampConverter(earner.getLastSubscription().getAsJsonObject().get(earner.getBrokerName()).getAsDouble(), false));
|
||||
lastRedemption.setText(HomeFragment.timeStampConverter(earner.getLastRedemption().getAsJsonObject().get(earner.getBrokerName()).getAsDouble(), false));
|
||||
|
||||
cardLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (onCardLongClickListener != null) {
|
||||
onCardLongClickListener.onCardLongClick(earner.getBrokerName(), v);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static String formatSeconds(double seconds) {
|
||||
long days = TimeUnit.SECONDS.toDays((long) seconds);
|
||||
long hours = TimeUnit.SECONDS.toHours((long) seconds) % 24;
|
||||
long minutes = TimeUnit.SECONDS.toMinutes((long) seconds) % 60;
|
||||
long secs = (long) (seconds % 60);
|
||||
|
||||
return String.format(Locale.ROOT,"%03d:%02d:%02d:%02d", days, hours, minutes, secs);
|
||||
|
||||
}
|
||||
|
||||
public void populateStatusBar(TextView statusBar, EarnerInterface.EarnerGlobalData earnerData) {
|
||||
double uptime = earnerData.getUptime();
|
||||
//Loop through all the earners in earnerData and calculate total funds
|
||||
double totalEarningFunds = 0;
|
||||
double totalTradingFunds = 0;
|
||||
for (EarnerData earner : earnerData.getEarnerList()) {
|
||||
totalEarningFunds += earner.getEarningBalance();
|
||||
totalTradingFunds += earner.getTradingBalance();
|
||||
}
|
||||
double totalFunds = totalEarningFunds + totalTradingFunds;
|
||||
String earningPercentage = String.format(Locale.ROOT, "%.2f", totalEarningFunds/totalFunds*100);
|
||||
|
||||
List<EarnerData> earnerList = earnerData.getEarnerList();
|
||||
|
||||
String statusBarText = "Uptime: " + formatSeconds(uptime) + " | Total funds: " +
|
||||
String.format(Locale.ROOT, "%.2f", totalFunds) + " USDT \n On Earn: " +
|
||||
String.format(Locale.ROOT, "%.2f", totalEarningFunds) + " USDT (" + earningPercentage + "%)";
|
||||
statusBar.setText(statusBarText);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package com.example.dcav2gui.ui.earners;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class EarnerData {
|
||||
private final String brokerName;
|
||||
private final double tradingBalance;
|
||||
private final double earningBalance;
|
||||
private final boolean isPaused;
|
||||
private final double stepSize;
|
||||
private final double percentage;
|
||||
private final double minimumAmountInTradingAccount;
|
||||
private final double timeBetweenSubscriptions;
|
||||
private final double timeBetweenRedemptions;
|
||||
private final JsonObject lastSubscription;
|
||||
private final JsonObject lastRedemption;
|
||||
|
||||
public EarnerData(String brokerName, double tradingBalance, double earningBalance, boolean isPaused, double stepSize, double percentage, double minimumAmountInTradingAccount,
|
||||
double timeBetweenSubscriptions, double timeBetweenRedemptions, JsonObject lastSubscription, JsonObject lastRedemption) {
|
||||
this.brokerName = brokerName;
|
||||
this.tradingBalance = tradingBalance;
|
||||
this.earningBalance = earningBalance;
|
||||
this.isPaused = isPaused;
|
||||
this.stepSize = stepSize;
|
||||
this.percentage = percentage;
|
||||
this.minimumAmountInTradingAccount = minimumAmountInTradingAccount;
|
||||
this.timeBetweenSubscriptions = timeBetweenSubscriptions;
|
||||
this.timeBetweenRedemptions = timeBetweenRedemptions;
|
||||
this.lastSubscription = lastSubscription;
|
||||
this.lastRedemption = lastRedemption;
|
||||
}
|
||||
|
||||
public String getBrokerName() {return brokerName;}
|
||||
public double getTradingBalance() {return tradingBalance;}
|
||||
public double getEarningBalance() {return earningBalance;}
|
||||
public double getPercentage() {return percentage;}
|
||||
public boolean getIsPaused() {return isPaused;}
|
||||
public double setStepSize() {return stepSize;}
|
||||
public double getMinimumAmountInTradingAccount() {return minimumAmountInTradingAccount;}
|
||||
public double getTimeBetweenSubscriptions() {return timeBetweenSubscriptions;}
|
||||
public double getTimeBetweenRedemptions() {return timeBetweenRedemptions;}
|
||||
public JsonObject getLastSubscription() {return lastSubscription;}
|
||||
public JsonObject getLastRedemption() {return lastRedemption;}
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package com.example.dcav2gui.ui.earners;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.example.dcav2gui.EarnerInterface;
|
||||
import com.example.dcav2gui.MainActivity;
|
||||
import com.example.dcav2gui.ui.settings.SettingsData;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class EarnerViewModel extends AndroidViewModel {
|
||||
|
||||
private final MutableLiveData<EarnerInterface.EarnerGlobalData> earnerGlobalData;
|
||||
SettingsData settingsData = MainActivity.getGlobalSettings();
|
||||
|
||||
public EarnerViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
earnerGlobalData = new MutableLiveData<>();
|
||||
fetchEarnerData(); // Initial data fetch
|
||||
}
|
||||
|
||||
public LiveData<EarnerInterface.EarnerGlobalData> getEarnerData() {
|
||||
|
||||
if (earnerGlobalData.getValue() == null) {
|
||||
fetchEarnerData();
|
||||
}
|
||||
return earnerGlobalData;
|
||||
}
|
||||
|
||||
private void fetchEarnerData() {
|
||||
HandlerThread handlerThread = new HandlerThread("FetchEarnerDataThread");
|
||||
handlerThread.start();
|
||||
Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Fetch and update the data
|
||||
EarnerInterface.EarnerGlobalData newData = EarnerInterface.getEarnerGlobalData(true);
|
||||
earnerGlobalData.postValue(newData);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Schedule the next execution
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fetchEarnerData();
|
||||
}
|
||||
}, (long) settingsData.timeBetweenQueries * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -100,12 +100,6 @@ public class BinanceFragment extends Fragment implements WorkerCardAdapter.OnCar
|
|||
} else if (item.getItemId() == R.id.switchQuoteCurrency) {
|
||||
WorkerInterface.sendSwitchQuoteCurrencyCall("binance", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||
WorkerInterface.sendModifyOrderSizeCall("binance", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||
WorkerInterface.sendAddSafetyOrdersCall("binance", pair, getContext());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ public class GateioFragment extends Fragment implements WorkerCardAdapter.OnCard
|
|||
WorkerInterface.sendAddTraderCall("gateio",getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.removeTrader) {
|
||||
WorkerInterface.sendRemoveTraderCall("gateio",pair, getContext());
|
||||
System.err.println(pair + " Remove trader option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.restartTrader) {
|
||||
WorkerInterface.sendRestartTraderCall("gateio",pair, getContext());
|
||||
System.err.println(pair + " Restart option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.importTrader) {
|
||||
WorkerInterface.sendImportTraderCall("gateio",getContext());
|
||||
|
|
@ -99,12 +99,6 @@ public class GateioFragment extends Fragment implements WorkerCardAdapter.OnCard
|
|||
} else if (item.getItemId() == R.id.switchQuoteCurrency) {
|
||||
WorkerInterface.sendSwitchQuoteCurrencyCall("gateio", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("gateio", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||
WorkerInterface.sendModifyOrderSizeCall("gateio", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||
WorkerInterface.sendAddSafetyOrdersCall("gateio", pair, getContext());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ public class KucoinFragment extends Fragment implements WorkerCardAdapter.OnCard
|
|||
WorkerInterface.sendAddTraderCall("kucoin",getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.removeTrader) {
|
||||
WorkerInterface.sendRemoveTraderCall("kucoin",pair,getContext());
|
||||
System.err.println(pair + " Remove trader option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.restartTrader) {
|
||||
WorkerInterface.sendRestartTraderCall("kucoin",pair,getContext());
|
||||
System.err.println(pair + " Restart option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.importTrader) {
|
||||
WorkerInterface.sendImportTraderCall("kucoin",getContext());
|
||||
|
|
@ -99,12 +99,6 @@ public class KucoinFragment extends Fragment implements WorkerCardAdapter.OnCard
|
|||
} else if (item.getItemId() == R.id.switchQuoteCurrency) {
|
||||
WorkerInterface.sendSwitchQuoteCurrencyCall("kucoin", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("kucoin", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||
WorkerInterface.sendModifyOrderSizeCall("kucoin", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||
WorkerInterface.sendAddSafetyOrdersCall("kucoin", pair, getContext());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ public class OkxFragment extends Fragment implements WorkerCardAdapter.OnCardLon
|
|||
WorkerInterface.sendAddTraderCall("okex",getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.removeTrader) {
|
||||
WorkerInterface.sendRemoveTraderCall("okex",pair,getContext());
|
||||
System.err.println(pair + " Remove trader option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.restartTrader) {
|
||||
WorkerInterface.sendRestartTraderCall("okex", pair, getContext());
|
||||
System.err.println(pair + " Restart option clicked");
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.importTrader) {
|
||||
WorkerInterface.sendImportTraderCall("okex",getContext());
|
||||
|
|
@ -99,12 +99,6 @@ public class OkxFragment extends Fragment implements WorkerCardAdapter.OnCardLon
|
|||
} else if (item.getItemId() == R.id.switchQuoteCurrency) {
|
||||
WorkerInterface.sendSwitchQuoteCurrencyCall("okex", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("okex", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||
WorkerInterface.sendModifyOrderSizeCall("okex", pair, getContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||
WorkerInterface.sendAddSafetyOrdersCall("okex", pair, getContext());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.example.dcav2gui.InstanceInterface;
|
|||
public class WorkerData {
|
||||
private final String pair;
|
||||
private final int amountOfSafetyOrders;
|
||||
private final int safetyOrdersFilled;
|
||||
private final int maxSafetyOrders;
|
||||
private final double uptime;
|
||||
private final double nextSoPrice;
|
||||
|
|
@ -20,14 +19,13 @@ public class WorkerData {
|
|||
private final boolean stopWhenProfit;
|
||||
private final InstanceInterface.OldLongDictionary oldLongDictionary;
|
||||
|
||||
public WorkerData(String pair, int amountOfSafetyOrders, int safetyOrdersFilled, int maxSafetyOrders, double uptime,
|
||||
public WorkerData(String pair, int amountOfSafetyOrders, int maxSafetyOrders, double uptime,
|
||||
double nextSoPrice, double price, double takeProfitPrice, double totalAmountOfQuote, double totalAmountOfBase, boolean isShort,
|
||||
boolean isBoosted, boolean isAuto, boolean isPaused, boolean stopWhenProfit,
|
||||
InstanceInterface.OldLongDictionary oldLongDictionary) {
|
||||
|
||||
this.pair = pair;
|
||||
this.amountOfSafetyOrders = amountOfSafetyOrders;
|
||||
this.safetyOrdersFilled = safetyOrdersFilled;
|
||||
this.maxSafetyOrders = maxSafetyOrders;
|
||||
this.uptime = uptime;
|
||||
this.nextSoPrice = nextSoPrice;
|
||||
|
|
@ -45,7 +43,6 @@ public class WorkerData {
|
|||
|
||||
public String getPair() { return pair; }
|
||||
public int getAmountOfSafetyOrders() { return amountOfSafetyOrders; }
|
||||
public int getSafetyOrdersFilled() { return safetyOrdersFilled; }
|
||||
public int getMaxSafetyOrders() { return maxSafetyOrders; }
|
||||
public double getUptime() { return uptime; }
|
||||
public double getNextSoPrice() { return nextSoPrice; }
|
||||
|
|
|
|||
|
|
@ -81,13 +81,8 @@ public class WorkerCardAdapter{
|
|||
}
|
||||
|
||||
price.setText(String.format(Locale.ROOT, "%.8f", worker.getPrice()));
|
||||
if (worker.isShort()
|
||||
&& worker.getOldLongDictionary()!=null
|
||||
&& worker.getPrice()>worker.getOldLongDictionary().getTpPrice()) {
|
||||
price.setTextColor(Color.parseColor("#00FF00"));
|
||||
}
|
||||
|
||||
|
||||
//TODO: If short and old_long and next_so_price<switch_price, set color to green
|
||||
nextSoPrice.setText(String.format(Locale.ROOT, "%.8f", worker.getNextSoPrice()));
|
||||
if (worker.isShort() &&
|
||||
worker.getOldLongDictionary()!=null &&
|
||||
|
|
@ -96,7 +91,6 @@ public class WorkerCardAdapter{
|
|||
worker.getNextSoPrice()>worker.getMinSwitchPrice()) {
|
||||
//Green
|
||||
nextSoPrice.setTextColor(Color.parseColor("#00FF00"));
|
||||
nextSoPrice.setText(String.format(Locale.ROOT, "%.8f", worker.getMinSwitchPrice()));
|
||||
}
|
||||
takeProfitPrice.setText(String.format(Locale.ROOT, "%.8f", worker.getTakeProfitPrice()));
|
||||
|
||||
|
|
@ -116,7 +110,7 @@ public class WorkerCardAdapter{
|
|||
percentage.setTextColor(Color.parseColor("#CACACA"));
|
||||
}
|
||||
|
||||
String safetyOrdersToDisplay = worker.getSafetyOrdersFilled() + "/" + worker.getMaxSafetyOrders();
|
||||
String safetyOrdersToDisplay = worker.getAmountOfSafetyOrders()-1 + "/" + worker.getMaxSafetyOrders();
|
||||
safetyOrders.setText(safetyOrdersToDisplay);
|
||||
|
||||
uptime.setText(formatSeconds(worker.getUptime()));
|
||||
|
|
@ -148,17 +142,10 @@ public class WorkerCardAdapter{
|
|||
workerStatusString.setText(R.string.last_deal_notice);
|
||||
workerStatusString.setVisibility(View.VISIBLE);
|
||||
} else if (worker.isPaused()) {
|
||||
workerStatusString.setText(R.string.pause_notice);
|
||||
workerStatusString.setVisibility(View.VISIBLE);
|
||||
cardLayout.setBackgroundColor(Color.parseColor("#C5C281"));
|
||||
workerStatusString.setVisibility(View.INVISIBLE);
|
||||
} else if (worker.isAuto()) {
|
||||
String stringToDisplay = "AUTO";
|
||||
if (worker.getPrice()!=0) {
|
||||
int multiplier = (int) (worker.getOldLongDictionary().getTpPrice() / worker.getPrice());
|
||||
if (multiplier>1) {
|
||||
stringToDisplay = stringToDisplay + " x" + multiplier;
|
||||
}
|
||||
}
|
||||
workerStatusString.setText(stringToDisplay);
|
||||
workerStatusString.setText(R.string.autoswitch_notice);
|
||||
workerStatusString.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
workerStatusString.setText("");
|
||||
|
|
|
|||
|
|
@ -1,16 +1,13 @@
|
|||
package com.example.dcav2gui.ui.home;
|
||||
|
||||
import static com.example.dcav2gui.InstanceInterface.getLastNTrades;
|
||||
import static com.example.dcav2gui.WorkerInterface.showToggleDialog;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.InputType;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
|
@ -19,7 +16,6 @@ import android.view.LayoutInflater;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
|
|
@ -38,7 +34,6 @@ import com.example.dcav2gui.InstanceInterface;
|
|||
import com.example.dcav2gui.MainActivity;
|
||||
import com.example.dcav2gui.R;
|
||||
import com.example.dcav2gui.TickerTracker;
|
||||
import com.example.dcav2gui.WorkerInterface;
|
||||
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
|
|
@ -353,9 +348,6 @@ public class HomeFragment extends Fragment {
|
|||
} else if (item.getItemId() == R.id.exchangeMenuConfigFile) {
|
||||
fetchExchangeConfig(exchange, true);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.exchangeModDefaultOrderSize) {
|
||||
sendModifyDefaultOrderSizeCall(exchange, getContext());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -548,43 +540,6 @@ public class HomeFragment extends Fragment {
|
|||
return shortWorkers;
|
||||
}
|
||||
|
||||
|
||||
public static void sendModifyDefaultOrderSizeCall(String exchange, Context context) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Modify default order size of "+ exchange);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Modify", (dialog, which) -> {
|
||||
final double newOrderSize = Double.parseDouble(input.getText().toString());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
JsonObject response = InstanceInterface.modDefaultOrderSize(exchange, newOrderSize, true);
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
showToggleDialog(response, context);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Show an error dialog on the main thread
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||
errorBuilder.setTitle("Error");
|
||||
errorBuilder.setMessage("Failed to modify default order size: " + e.getMessage());
|
||||
errorBuilder.setPositiveButton("OK", null);
|
||||
errorBuilder.show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
|
||||
private void showLastTradesDetailsDialog(List<InstanceInterface.DealData> result) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
List<String> shortWorkers = new ArrayList<>();
|
||||
|
|
@ -1066,11 +1021,7 @@ public class HomeFragment extends Fragment {
|
|||
if (binanceData.getFundsNeeded() != 0) {
|
||||
binanceFundsPercentage = 100 - (binanceData.getFundsNeeded() - binanceData.getFundsAvailable()) / binanceData.getFundsNeeded() * 100;
|
||||
}
|
||||
String percentageFormat = "%.2f";
|
||||
if (binanceFundsPercentage>=100) {
|
||||
percentageFormat = "%.1f";
|
||||
}
|
||||
String binanceFundsPercentageString = String.format(Locale.ROOT, percentageFormat, binanceFundsPercentage) + "%";
|
||||
String binanceFundsPercentageString = String.format(Locale.ROOT, "%.2f", binanceFundsPercentage) + "%";
|
||||
exchange1Funds.setText(binanceFunds);
|
||||
exchange1FundsPercentage.setText(binanceFundsPercentageString);
|
||||
}
|
||||
|
|
@ -1083,11 +1034,7 @@ public class HomeFragment extends Fragment {
|
|||
if (gateioData.getFundsNeeded() != 0) {
|
||||
gateioFundsPercentage = 100 - (gateioData.getFundsNeeded() - gateioData.getFundsAvailable()) / gateioData.getFundsNeeded() * 100;
|
||||
}
|
||||
String percentageFormat = "%.2f";
|
||||
if (gateioFundsPercentage>=100) {
|
||||
percentageFormat = "%.1f";
|
||||
}
|
||||
String gateioFundsPercentageString = String.format(Locale.ROOT, percentageFormat, gateioFundsPercentage) + "%";
|
||||
String gateioFundsPercentageString = String.format(Locale.ROOT, "%.2f", gateioFundsPercentage) + "%";
|
||||
exchange2Funds.setText(gateioFunds);
|
||||
exchange2FundsPercentage.setText(gateioFundsPercentageString);
|
||||
}
|
||||
|
|
@ -1100,11 +1047,7 @@ public class HomeFragment extends Fragment {
|
|||
if (kucoinData.getFundsNeeded() != 0) {
|
||||
kucoinFundsPercentage = 100 - (kucoinData.getFundsNeeded() - kucoinData.getFundsAvailable()) / kucoinData.getFundsNeeded() * 100;
|
||||
}
|
||||
String percentageFormat = "%.2f";
|
||||
if (kucoinFundsPercentage>=100) {
|
||||
percentageFormat = "%.1f";
|
||||
}
|
||||
String kucoinFundsPercentageString = String.format(Locale.ROOT, percentageFormat, kucoinFundsPercentage) + "%";
|
||||
String kucoinFundsPercentageString = String.format(Locale.ROOT, "%.2f", kucoinFundsPercentage) + "%";
|
||||
exchange3Funds.setText(kucoinFunds);
|
||||
exchange3FundsPercentage.setText(kucoinFundsPercentageString);
|
||||
}
|
||||
|
|
@ -1117,11 +1060,7 @@ public class HomeFragment extends Fragment {
|
|||
if (okexData.getFundsNeeded() != 0) {
|
||||
okexFundsPercentage = 100 - (okexData.getFundsNeeded() - okexData.getFundsAvailable()) / okexData.getFundsNeeded() * 100;
|
||||
}
|
||||
String percentageFormat = "%.2f";
|
||||
if (okexFundsPercentage>=100) {
|
||||
percentageFormat = "%.1f";
|
||||
}
|
||||
String okexFundsPercentageString = String.format(Locale.ROOT, percentageFormat, okexFundsPercentage) + "%";
|
||||
String okexFundsPercentageString = String.format(Locale.ROOT, "%.2f", okexFundsPercentage) + "%";
|
||||
exchange4Funds.setText(okexFunds);
|
||||
exchange4FundsPercentage.setText(okexFundsPercentageString);
|
||||
}
|
||||
|
|
@ -1235,9 +1174,9 @@ public class HomeFragment extends Fragment {
|
|||
public static String timeStampConverter(double timestamp, boolean noDate) {
|
||||
long linuxTimestamp = (long) timestamp; // Replace with your timestamp
|
||||
Date date = new Date(linuxTimestamp * 1000);
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);// Multiply by 1000 to convert to milliseconds
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// Multiply by 1000 to convert to milliseconds
|
||||
if (noDate) {
|
||||
formatter = new SimpleDateFormat("HH:mm:ss", Locale.ROOT);
|
||||
formatter = new SimpleDateFormat("HH:mm:ss");
|
||||
}
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ public class SettingsData {
|
|||
public String profileName;
|
||||
public String apiUrl;
|
||||
public String apiKey;
|
||||
public boolean useEarn;
|
||||
public String earnApiKey;
|
||||
public boolean useTelegram;
|
||||
public String botToken;
|
||||
public String chatId;
|
||||
|
|
@ -18,8 +16,6 @@ public class SettingsData {
|
|||
String profileName,
|
||||
String apiUrl,
|
||||
String apiKey,
|
||||
boolean useEarn,
|
||||
String earnApiKey,
|
||||
boolean useTelegram,
|
||||
String botToken,
|
||||
String chatId,
|
||||
|
|
@ -30,8 +26,6 @@ public class SettingsData {
|
|||
this.profileName = profileName;
|
||||
this.apiUrl = apiUrl;
|
||||
this.apiKey = apiKey;
|
||||
this.useEarn = useEarn;
|
||||
this.earnApiKey = earnApiKey;
|
||||
this.useTelegram = useTelegram;
|
||||
this.botToken = botToken;
|
||||
this.chatId = chatId;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ public class SettingsFragment extends Fragment {
|
|||
EditText editProfileName = root.findViewById(R.id.editProfileName);
|
||||
EditText editApiUrl = root.findViewById(R.id.editApiUrl);
|
||||
EditText editApiKey = root.findViewById(R.id.editApiKey);
|
||||
CheckBox checkUseEarn = root.findViewById(R.id.useEarn);
|
||||
EditText editEarnApiKey = root.findViewById(R.id.earnApiKey);
|
||||
CheckBox checkBox = root.findViewById(R.id.useTelegram);
|
||||
EditText editBotToken = root.findViewById(R.id.editBotToken);
|
||||
EditText editChatId = root.findViewById(R.id.editChatId);
|
||||
|
|
@ -39,7 +37,6 @@ public class SettingsFragment extends Fragment {
|
|||
EditText editAmountOfLogLines = root.findViewById(R.id.editAmountOfLogLines);
|
||||
EditText editAmountOfLastTrades = root.findViewById(R.id.editAmountOfLastTrades);
|
||||
|
||||
|
||||
Button buttonSaveSettings = root.findViewById(R.id.buttonSaveSettings);
|
||||
|
||||
//Load settings if settings.json exists
|
||||
|
|
@ -49,8 +46,6 @@ public class SettingsFragment extends Fragment {
|
|||
editProfileName.setText(settingsData.profileName);
|
||||
editApiUrl.setText(settingsData.apiUrl);
|
||||
editApiKey.setText(settingsData.apiKey);
|
||||
checkUseEarn.setChecked(settingsData.useEarn);
|
||||
editEarnApiKey.setText(settingsData.earnApiKey);
|
||||
checkBox.setChecked(settingsData.useTelegram);
|
||||
editBotToken.setText(settingsData.botToken);
|
||||
editChatId.setText(settingsData.chatId);
|
||||
|
|
@ -77,8 +72,6 @@ public class SettingsFragment extends Fragment {
|
|||
String profileName = editProfileName.getText().toString();
|
||||
String apiUrl = editApiUrl.getText().toString();
|
||||
String apiKey = editApiKey.getText().toString();
|
||||
boolean useEarn = checkUseEarn.isChecked();
|
||||
String earnApiKey = editEarnApiKey.getText().toString();
|
||||
boolean useTelegram = checkBox.isChecked();
|
||||
String botToken = editBotToken.getText().toString();
|
||||
String chatId = editChatId.getText().toString();
|
||||
|
|
@ -126,8 +119,6 @@ public class SettingsFragment extends Fragment {
|
|||
profileName,
|
||||
apiUrl,
|
||||
apiKey,
|
||||
useEarn,
|
||||
earnApiKey,
|
||||
useTelegram,
|
||||
botToken,
|
||||
chatId,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ public class SettingsViewModel extends ViewModel {
|
|||
public String profileName;
|
||||
public String apiUrl;
|
||||
public String apiKey;
|
||||
public boolean useEarn;
|
||||
public String earnApiKey;
|
||||
public boolean useTelegram;
|
||||
public String botToken;
|
||||
public String chatId;
|
||||
|
|
@ -31,8 +29,6 @@ public class SettingsViewModel extends ViewModel {
|
|||
String profileName,
|
||||
String apiUrl,
|
||||
String apiKey,
|
||||
boolean useEarn,
|
||||
String earnApiKey,
|
||||
boolean useTelegram,
|
||||
String botToken,
|
||||
String chatId,
|
||||
|
|
@ -45,8 +41,6 @@ public class SettingsViewModel extends ViewModel {
|
|||
this.profileName = profileName;
|
||||
this.apiUrl = apiUrl;
|
||||
this.apiKey = apiKey;
|
||||
this.useEarn = useEarn;
|
||||
this.earnApiKey = earnApiKey;
|
||||
this.useTelegram = useTelegram;
|
||||
this.botToken = botToken;
|
||||
this.chatId = chatId;
|
||||
|
|
@ -60,8 +54,6 @@ public class SettingsViewModel extends ViewModel {
|
|||
profileName,
|
||||
apiUrl,
|
||||
apiKey,
|
||||
useEarn,
|
||||
earnApiKey,
|
||||
useTelegram,
|
||||
botToken,
|
||||
chatId,
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
|
|
@ -1,130 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:longClickable="true">
|
||||
<LinearLayout
|
||||
android:id="@+id/earnerCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/price_card_background"
|
||||
android:padding="2dp"
|
||||
tools:ignore="MissingConstraints">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="28dp"
|
||||
android:orientation="horizontal"
|
||||
android:padding="2dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
<TextView
|
||||
android:id="@+id/earnerCardExchange"
|
||||
android:layout_width="84dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="Cryptopia"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardTradingBalanceLabel"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="Trading:"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardTradingBalanceValue"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="3203.40"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardTradingBalanceCurrency"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="USDT"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textSize="10sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardEarningBalanceLabel"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="Earning:"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardEarningBalanceValue"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="3203.40"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardEarningBalanceCurrency"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="USDT"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textSize="10sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardPercentage"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="71.77%"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="normal" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:padding="3dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
<TextView
|
||||
android:id="@+id/earnerCardLastSubscriptionLabel"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="18dp"
|
||||
android:text="Last subscription:"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardLastSubscriptionDateTime"
|
||||
android:layout_width="104dp"
|
||||
android:layout_height="18dp"
|
||||
android:text="2025/03/08 04:20"
|
||||
android:textColor="@color/bright_green"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardLastRedemptionLabel"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="18dp"
|
||||
android:text="Last redemption:"
|
||||
android:textColor="@color/secondary_text_color"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/earnerCardLastRedemptionDateTime"
|
||||
android:layout_width="104dp"
|
||||
android:layout_height="18dp"
|
||||
android:text="2025/03/08 04:20"
|
||||
android:textColor="@color/red"
|
||||
android:textAlignment="center"
|
||||
android:textSize="11sp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="24dp">
|
||||
<LinearLayout
|
||||
android:id="@+id/earners_cards_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible">
|
||||
|
||||
<!-- Each card will be added dynamically here -->
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
<TextView
|
||||
android:id="@+id/earners_status_bar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/status_bar_background"
|
||||
android:text="Loading..."
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:padding="6dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -69,20 +69,6 @@
|
|||
android:inputType="text"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/useEarn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Earn" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/earnApiKey"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/earn_key_hint"
|
||||
android:textStyle="italic"
|
||||
android:inputType="text"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/useTelegram"
|
||||
|
|
|
|||
|
|
@ -24,9 +24,5 @@
|
|||
android:id="@+id/nav_okx"
|
||||
android:icon="@drawable/ic_okx"
|
||||
android:title="@string/menu_okx" />
|
||||
<item
|
||||
android:id="@+id/nav_earn"
|
||||
android:icon="@drawable/piggy_bank"
|
||||
android:title="Earn" />
|
||||
</group>
|
||||
</menu>
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/earnerMenuGlobalStatus"
|
||||
android:title="Global status" />
|
||||
<item android:id="@+id/earnerMenuTotalBalance"
|
||||
android:title="Total balance" />
|
||||
<item android:id="@+id/earnerMenuLastSubscription"
|
||||
android:title="Last subscription" />
|
||||
<item android:id="@+id/earnerMenuLastRedemption"
|
||||
android:title="Last redemption" />
|
||||
<item android:id="@+id/earnerMenuTogglePause"
|
||||
android:title="Toggle pause" />
|
||||
<item android:id="@+id/earnerMenuSubscribe"
|
||||
android:title="Subscribe" />
|
||||
<item android:id="@+id/earnerMenuRedeem"
|
||||
android:title="Redeem" />
|
||||
<item android:id="@+id/earnerMenuGet"
|
||||
android:title="Get..." >
|
||||
<menu>
|
||||
<item android:id="@+id/earnerMenuGetPercentage"
|
||||
android:title="Get percentage" />
|
||||
<item android:id="@+id/earnerMenuGetStepSize"
|
||||
android:title="Get step size" />
|
||||
<item android:id="@+id/earnerMenuGetTimeBetweenSubscriptions"
|
||||
android:title="Get time between subscriptions" />
|
||||
<item android:id="@+id/earnerMenuGetTimeBetweenRedemptions"
|
||||
android:title="Get time between redemptions" />
|
||||
<item android:id="@+id/earnerMenuGetMinimumAmountInTradingAccount"
|
||||
android:title="Get minimum amount in trading account" />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/earnerMenuSet"
|
||||
android:title="Set..." >
|
||||
<menu>
|
||||
<item android:id="@+id/earnerMenuSetPercentage"
|
||||
android:title="Set percentage" />
|
||||
<item android:id="@+id/earnerMenuSetStepSize"
|
||||
android:title="Set step size" />
|
||||
<item android:id="@+id/earnerMenuSetTimeBetweenSubscriptions"
|
||||
android:title="Set time between subscriptions" />
|
||||
<item android:id="@+id/earnerMenuSetTimeBetweenRedemptions"
|
||||
android:title="Set time between redemptions" />
|
||||
<item android:id="@+id/earnerMenuSetMinimumAmountInTradingAccount"
|
||||
android:title="Set minimum amount in trading account" />
|
||||
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
||||
|
|
@ -12,6 +12,4 @@
|
|||
android:title="View paused traders" />
|
||||
<item android:id="@+id/exchangeMenuConfigFile"
|
||||
android:title="View config file" />
|
||||
<item android:id="@+id/exchangeModDefaultOrderSize"
|
||||
android:title="Modify default order size" />
|
||||
</menu>
|
||||
|
|
@ -42,10 +42,6 @@
|
|||
<item android:id="@+id/workerMenuAdd"
|
||||
android:title="Add...">
|
||||
<menu>
|
||||
<item android:id="@+id/modOrderSize"
|
||||
android:title="Modify order size"/>
|
||||
<item android:id="@+id/modConcurrentSafetyOrders"
|
||||
android:title="Modify concurrent safety orders"/>
|
||||
<item android:id="@+id/addSafetyOrders"
|
||||
android:title="Add safety orders"/>
|
||||
<item android:id="@+id/addQuote"
|
||||
|
|
|
|||
|
|
@ -35,12 +35,6 @@
|
|||
android:label="@string/menu_okx"
|
||||
tools:layout="@layout/fragment_okx" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_earn"
|
||||
android:name="com.example.dcav2gui.ui.earners.EarnFragment"
|
||||
android:label="Earn"
|
||||
tools:layout="@layout/fragment_okx" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_settings"
|
||||
android:name="com.example.dcav2gui.ui.settings.SettingsFragment"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<resources>
|
||||
<string name="app_name" translatable="false">DCAv2GUI</string>
|
||||
<string name="nav_header_title" translatable="false">DCAv2</string>
|
||||
<string name="nav_header_subtitle">Version 2025.09.06</string>
|
||||
<string name="navigation_drawer_open">Open navigation drawer</string>
|
||||
<string name="navigation_drawer_close">Close navigation drawer</string>
|
||||
<string name="nav_header_title" translatable="false">DCAv2</string>
|
||||
<string name="nav_header_subtitle">nicolassanchez@tutanota.com</string>
|
||||
<string name="nav_header_desc">Navigation header</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
<string name="profile_name_hint">Enter the profile name</string>
|
||||
<string name="api_url_hint">Enter the API URL</string>
|
||||
<string name="api_key_hint">Enter the API key</string>
|
||||
<string name="earn_key_hint">Enter the Earn API key</string>
|
||||
<string name="api_key_hint">Enter the API Key</string>
|
||||
<string name="use_telegram">Use Telegram</string>
|
||||
<string name="bot_token_hint">Enter the bot token</string>
|
||||
<string name="chat_id_hint">Enter the chat ID</string>
|
||||
|
|
@ -81,7 +80,6 @@
|
|||
<string name="exchange_4_log_title" translatable="false">OKX log</string>
|
||||
<string name="loading_message">Querying data sources…</string>
|
||||
<string name="last_deal_notice">LAST DEAL</string>
|
||||
<string name="pause_notice">PAUSED</string>
|
||||
<string name="autoswitch_notice">AUTO</string>
|
||||
<string name="fire_icon_legend">Fire icon</string>
|
||||
</resources>
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
[versions]
|
||||
activity = "1.10.1"
|
||||
agp = "8.9.0"
|
||||
biometric = "1.1.0"
|
||||
fragment = "1.8.6"
|
||||
agp = "8.7.3"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.2.1"
|
||||
espressoCore = "3.6.1"
|
||||
|
|
@ -21,9 +18,6 @@ recyclerview = "1.3.2"
|
|||
recyclerviewVersion = "1.2.1"
|
||||
|
||||
[libraries]
|
||||
activity = { module = "androidx.activity:activity", version.ref = "activity" }
|
||||
biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" }
|
||||
fragment = { module = "androidx.fragment:fragment", version.ref = "fragment" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#Mon Dec 09 08:04:51 ART 2024
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
|||
Loading…
Reference in New Issue