mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 12:11:35 +00:00
Fetch notifications
This commit is contained in:
parent
0e6ae63ac4
commit
7388b4f6de
25
api/lightning/pip-build-env-wwuhobll/site/sitecustomize.py
Normal file
25
api/lightning/pip-build-env-wwuhobll/site/sitecustomize.py
Normal file
@ -0,0 +1,25 @@
|
||||
import os
|
||||
import site
|
||||
import sys
|
||||
|
||||
# First, drop system-sites related paths.
|
||||
original_sys_path = sys.path[:]
|
||||
known_paths = set()
|
||||
for path in {"/usr/local/lib/python3.12/site-packages"}:
|
||||
site.addsitedir(path, known_paths=known_paths)
|
||||
system_paths = set(
|
||||
os.path.normcase(path) for path in sys.path[len(original_sys_path) :]
|
||||
)
|
||||
original_sys_path = [
|
||||
path for path in original_sys_path if os.path.normcase(path) not in system_paths
|
||||
]
|
||||
sys.path = original_sys_path
|
||||
|
||||
# Second, add lib directories.
|
||||
# ensuring .pth file are processed.
|
||||
for path in [
|
||||
"/tmp/pip-build-env-wwuhobll/overlay/lib/python3.12/site-packages",
|
||||
"/tmp/pip-build-env-wwuhobll/normal/lib/python3.12/site-packages",
|
||||
]:
|
||||
assert path not in sys.path
|
||||
site.addsitedir(path)
|
@ -0,0 +1 @@
|
||||
git+https://github.com/Reckless-Satoshi/drf-openapi-tester.git@soften-django-requirements (from -r requirements_dev.txt (line 3))
|
1
api/lightning/pip-req-build-bfeegnca
Submodule
1
api/lightning/pip-req-build-bfeegnca
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 2af4d20743439444054c5bf8a02c9f299b14491f
|
@ -7,6 +7,7 @@ import EncryptedStorage from 'react-native-encrypted-storage';
|
||||
import { name as app_name, version as app_version } from './package.json';
|
||||
import TorModule from './native/TorModule';
|
||||
import RoboIdentitiesModule from './native/RoboIdentitiesModule';
|
||||
import NotificationsModule from './native/NotificationsModule';
|
||||
|
||||
const backgroundColors = {
|
||||
light: 'white',
|
||||
@ -62,6 +63,7 @@ const App = () => {
|
||||
webViewRef.current?.injectJavaScript(
|
||||
`(function() {window.NativeRobosats?.loadCookie(${json});})();`,
|
||||
);
|
||||
return value;
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -72,7 +74,10 @@ const App = () => {
|
||||
loadCookie('settings_light_qr');
|
||||
loadCookie('settings_network');
|
||||
loadCookie('settings_use_proxy');
|
||||
loadCookie('garage_slots').then(() => injectMessageResolve(responseId));
|
||||
loadCookie('garage_slots').then((slots) => {
|
||||
NotificationsModule.monitorOrders(slots ?? '{}');
|
||||
injectMessageResolve(responseId);
|
||||
});
|
||||
};
|
||||
|
||||
const onCatch = (dataId: string, event: any) => {
|
||||
|
@ -13,6 +13,7 @@ import androidx.work.WorkManager;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.robosats.workers.NotificationWorker;
|
||||
|
||||
@ -75,7 +76,7 @@ public class MainActivity extends ReactActivity {
|
||||
// ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
|
||||
OneTimeWorkRequest workRequest =
|
||||
new OneTimeWorkRequest.Builder(NotificationWorker.class)
|
||||
.setInitialDelay(5, TimeUnit.SECONDS)
|
||||
.setInitialDelay(25, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
WorkManager.getInstance(getApplicationContext())
|
||||
|
@ -4,6 +4,7 @@ import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.robosats.modules.NotificationsModule;
|
||||
import com.robosats.modules.RoboIdentitiesModule;
|
||||
import com.robosats.modules.TorModule;
|
||||
|
||||
@ -23,6 +24,7 @@ public class RobosatsPackage implements ReactPackage {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new TorModule(reactContext));
|
||||
modules.add(new NotificationsModule(reactContext));
|
||||
modules.add(new RoboIdentitiesModule(reactContext));
|
||||
|
||||
return modules;
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.robosats.modules;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
|
||||
public class NotificationsModule extends ReactContextBaseJavaModule {
|
||||
public NotificationsModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NotificationsModule";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void monitorOrders(String slots_json) {
|
||||
String PREFS_NAME = "Notifications";
|
||||
String KEY_DATA = "Slots";
|
||||
SharedPreferences sharedPreferences = getReactApplicationContext().getSharedPreferences(PREFS_NAME, ReactApplicationContext.MODE_PRIVATE);
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(KEY_DATA, slots_json);
|
||||
|
||||
editor.apply();
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.robosats.modules;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -11,6 +12,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.robosats.tor.TorKmp;
|
||||
import com.robosats.tor.TorKmpManager;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -30,10 +32,11 @@ import okhttp3.Response;
|
||||
|
||||
|
||||
public class TorModule extends ReactContextBaseJavaModule {
|
||||
private TorKmpManager torKmpManager;
|
||||
private ReactApplicationContext context;
|
||||
public TorModule(ReactApplicationContext reactContext) {
|
||||
context = reactContext;
|
||||
TorKmp torKmpManager = new TorKmp((Application) context.getApplicationContext());
|
||||
TorKmpManager.INSTANCE.updateTorKmpObject(torKmpManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,7 +49,8 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout
|
||||
.readTimeout(30, TimeUnit.SECONDS) // Set read timeout
|
||||
.proxy(torKmpManager.getProxy()).build();
|
||||
.proxy(TorKmpManager.INSTANCE.getTorKmpObject().getProxy())
|
||||
.build();
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder().url(url);
|
||||
|
||||
@ -90,7 +94,7 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void getTorStatus() {
|
||||
String torState = torKmpManager.getTorState().getState().name();
|
||||
String torState = TorKmpManager.INSTANCE.getTorKmpObject().getTorState().getState().name();
|
||||
WritableMap payload = Arguments.createMap();
|
||||
payload.putString("torStatus", torState);
|
||||
context
|
||||
@ -100,7 +104,7 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void isConnected() {
|
||||
String isConnected = String.valueOf(torKmpManager.isConnected());
|
||||
String isConnected = String.valueOf(TorKmpManager.INSTANCE.getTorKmpObject().isConnected());
|
||||
WritableMap payload = Arguments.createMap();
|
||||
payload.putString("isConnected", isConnected);
|
||||
context
|
||||
@ -110,7 +114,7 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void isStarting() {
|
||||
String isStarting = String.valueOf(torKmpManager.isStarting());
|
||||
String isStarting = String.valueOf(TorKmpManager.INSTANCE.getTorKmpObject().isStarting());
|
||||
WritableMap payload = Arguments.createMap();
|
||||
payload.putString("isStarting", isStarting);
|
||||
context
|
||||
@ -120,7 +124,7 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void stop() {
|
||||
torKmpManager.getTorOperationManager().stopQuietly();
|
||||
TorKmpManager.INSTANCE.getTorKmpObject().getTorOperationManager().stopQuietly();
|
||||
WritableMap payload = Arguments.createMap();
|
||||
context
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
@ -129,8 +133,9 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void start() {
|
||||
torKmpManager = new TorKmpManager(context.getCurrentActivity().getApplication());
|
||||
torKmpManager.getTorOperationManager().startQuietly();
|
||||
TorKmp torKmp = new TorKmp(context.getCurrentActivity().getApplication());
|
||||
TorKmpManager.INSTANCE.updateTorKmpObject(torKmp);
|
||||
TorKmpManager.INSTANCE.getTorKmpObject().getTorOperationManager().startQuietly();
|
||||
WritableMap payload = Arguments.createMap();
|
||||
context
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
@ -139,8 +144,9 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void restart() {
|
||||
torKmpManager = new TorKmpManager(context.getCurrentActivity().getApplication());
|
||||
torKmpManager.getTorOperationManager().restartQuietly();
|
||||
TorKmp torKmp = new TorKmp(context.getCurrentActivity().getApplication());
|
||||
TorKmpManager.INSTANCE.updateTorKmpObject(torKmp);
|
||||
TorKmpManager.INSTANCE.getTorKmpObject().getTorOperationManager().restartQuietly();
|
||||
WritableMap payload = Arguments.createMap();
|
||||
context
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
@ -149,7 +155,7 @@ public class TorModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void newIdentity() {
|
||||
torKmpManager.newIdentity(context.getCurrentActivity().getApplication());
|
||||
TorKmpManager.INSTANCE.getTorKmpObject().newIdentity(context.getCurrentActivity().getApplication());
|
||||
WritableMap payload = Arguments.createMap();
|
||||
context
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
|
@ -28,7 +28,7 @@ import kotlinx.coroutines.*
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
|
||||
class TorKmpManager(application : Application) {
|
||||
class TorKmp(application : Application) {
|
||||
|
||||
private val TAG = "TorListener"
|
||||
|
||||
@ -387,3 +387,15 @@ class TorKmpManager(application : Application) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TorKmpManager {
|
||||
private lateinit var torKmp: TorKmp
|
||||
|
||||
fun getTorKmpObject(): TorKmp {
|
||||
return torKmp
|
||||
}
|
||||
|
||||
fun updateTorKmpObject(newKmpObject: TorKmp) {
|
||||
torKmp = newKmpObject
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,123 @@
|
||||
package com.robosats.workers;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
|
||||
import android.os.Build;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.robosats.R;
|
||||
import com.robosats.tor.TorKmpManager;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class NotificationWorker extends Worker {
|
||||
private static final String CHANNEL_ID = "robosats_notifications";
|
||||
private static final int NOTIFICATION_ID = 123;
|
||||
private static final String PREFS_NAME = "Notifications";
|
||||
private static final String KEY_DATA = "Slots";
|
||||
|
||||
public NotificationWorker(Context context, WorkerParameters params) {
|
||||
super(context, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result doWork() {
|
||||
displayNotification("Order #1111", "Test from the app");
|
||||
|
||||
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(PREFS_NAME, ReactApplicationContext.MODE_PRIVATE);
|
||||
String slotsJson = sharedPreferences.getString(KEY_DATA, null);
|
||||
|
||||
try {
|
||||
assert slotsJson != null;
|
||||
JSONObject slots = new JSONObject(slotsJson);
|
||||
Iterator<String> it = slots.keys();
|
||||
|
||||
while (it.hasNext()) {
|
||||
String robotToken = it.next();
|
||||
JSONObject slot = (JSONObject) slots.get(robotToken);
|
||||
|
||||
JSONObject robots = slot.getJSONObject("robots");
|
||||
String activeShortAlias = slot.getString("activeShortAlias");
|
||||
JSONObject coordinatorRobot = robots.getJSONObject(activeShortAlias);
|
||||
String coordinator = "satstralia";
|
||||
fetchNotifications(coordinatorRobot, coordinator);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
private void displayNotification(String title, String message) {
|
||||
private void fetchNotifications(JSONObject robot, String coordinator) throws JSONException {
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout
|
||||
.readTimeout(30, TimeUnit.SECONDS) // Set read timeout
|
||||
.proxy(TorKmpManager.INSTANCE.getTorKmpObject().getProxy())
|
||||
.build();
|
||||
Request.Builder requestBuilder = new Request.Builder().url("http://satstraoq35jffvkgpfoqld32nzw2siuvowanruindbfojowpwsjdgad.onion/api/notifications");
|
||||
|
||||
requestBuilder.addHeader("Authorization", "Token " + robot.getString("tokenSHA256"));
|
||||
|
||||
requestBuilder.get();
|
||||
Request request = requestBuilder.build();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
Log.d("RobosatsError", e.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
String body = response.body() != null ? response.body().string() : "{}";
|
||||
JSONObject headersJson = new JSONObject();
|
||||
response.headers().names().forEach(name -> {
|
||||
try {
|
||||
headersJson.put(name, response.header(name));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
try {
|
||||
JSONArray results = new JSONArray(body);
|
||||
for (int i = 0; i < results.length(); i++) {
|
||||
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(PREFS_NAME, ReactApplicationContext.MODE_PRIVATE);
|
||||
JSONObject notification = results.getJSONObject(i);
|
||||
Integer order_id = notification.getInt("order_id");
|
||||
|
||||
displayNotification(order_id, notification.getString("title"), coordinator);
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(coordinator + order_id, String.valueOf(notification.getInt("created_at")));
|
||||
editor.apply();
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void displayNotification(Integer order_id, String message, String coordinator) {
|
||||
NotificationManager notificationManager = (NotificationManager)
|
||||
getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
@ -37,12 +128,12 @@ public class NotificationWorker extends Worker {
|
||||
|
||||
NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
|
||||
.setContentTitle(title)
|
||||
.setContentTitle("Order #" + order_id)
|
||||
.setContentText(message)
|
||||
.setSmallIcon(R.mipmap.ic_launcher_round)
|
||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
||||
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build());
|
||||
notificationManager.notify(order_id, builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
mobile/android/app/src/main/jniLibs/x86_64/librobohash.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/x86_64/librobohash.so
Executable file
Binary file not shown.
BIN
mobile/android/app/src/main/jniLibs/x86_64/librobonames.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/x86_64/librobonames.so
Executable file
Binary file not shown.
8
mobile/native/NotificationsModule.ts
Normal file
8
mobile/native/NotificationsModule.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
const { NotificationsModule } = NativeModules;
|
||||
|
||||
interface NotificationsModuleInterface {
|
||||
monitorOrders: (slotsJson: string) => void;
|
||||
}
|
||||
|
||||
export default NotificationsModule as NotificationsModuleInterface;
|
@ -2,8 +2,8 @@ import { NativeModules } from 'react-native';
|
||||
const { RoboIdentitiesModule } = NativeModules;
|
||||
|
||||
interface RoboIdentitiesModuleInterface {
|
||||
generateRoboname: (initialString: String) => Promise<string>;
|
||||
generateRobohash: (initialString: String) => Promise<string>;
|
||||
generateRoboname: (initialString: string) => Promise<string>;
|
||||
generateRobohash: (initialString: string) => Promise<string>;
|
||||
}
|
||||
|
||||
export default RoboIdentitiesModule as RoboIdentitiesModuleInterface;
|
||||
|
Loading…
Reference in New Issue
Block a user