Move updates to Java

This commit is contained in:
KoalaSat 2023-03-01 16:53:54 +01:00
parent c28ad79d53
commit 9751b6a553
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
20 changed files with 453 additions and 394 deletions

View File

@ -4,6 +4,8 @@ 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.nostros.classes.Database;
import com.nostros.modules.DatabaseModule;
import com.nostros.modules.RelayPoolModule;
import java.util.ArrayList;
@ -21,7 +23,9 @@ public class NostrosPackage implements ReactPackage {
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new RelayPoolModule(reactContext));
Database database = new Database(reactContext.getFilesDir().getAbsolutePath());
modules.add(new DatabaseModule(reactContext, database));
modules.add(new RelayPoolModule(reactContext, database));
return modules;
}

View File

@ -0,0 +1,269 @@
package com.nostros.classes;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Database {
public SQLiteDatabase instance;
public Database(String absoluteFilesPath) {
instance = SQLiteDatabase.openDatabase( absoluteFilesPath + "/nostros.sqlite", null, SQLiteDatabase.CREATE_IF_NECESSARY);
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_notes(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" main_event_id TEXT,\n" +
" reply_event_id TEXT\n" +
" );");
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_users(\n" +
" id TEXT PRIMARY KEY NOT NULL,\n" +
" name TEXT,\n" +
" picture TEXT,\n" +
" about TEXT,\n" +
" main_relay TEXT,\n" +
" contact INT DEFAULT 0,\n" +
" follower INT DEFAULT 0\n" +
" );");
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_relays(\n" +
" url TEXT PRIMARY KEY NOT NULL,\n" +
" pet INTEGER\n" +
" );");
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_direct_messages(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" conversation_id TEXT NOT NULL,\n" +
" read INT DEFAULT 0\n" +
" );");
try {
instance.execSQL("ALTER TABLE nostros_notes ADD COLUMN user_mentioned INT DEFAULT 0;");
instance.execSQL("ALTER TABLE nostros_notes ADD COLUMN seen INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN lnurl TEXT;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN created_at INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_reactions(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" positive INT DEFAULT 1,\n" +
" reacted_event_id TEXT,\n" +
" reacted_user_id TEXT\n" +
" );");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN nip05 TEXT;");
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN valid_nip05 INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_notes ADD COLUMN repost_id TEXT;");
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN active INT DEFAULT 1;");
} catch (SQLException e) { }
try {
instance.execSQL("DROP TABLE IF EXISTS nostros_config;");
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN blocked INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_notes_relays(\n" +
" note_id TEXT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" relay_url INT NOT NULL,\n" +
" PRIMARY KEY (note_id, relay_url)\n" +
" );");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN pet_at INT;");
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN follower_at INT;");
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN global_feed INT DEFAULT 1;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN resilient INT DEFAULT 0;");
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN manual INT DEFAULT 1;");
} catch (SQLException e) { }
try {
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_group_meta(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT,\n" +
" created_at INT,\n" +
" kind INT,\n" +
" pubkey TEXT,\n" +
" sig TEXT,\n" +
" tags TEXT,\n" +
" name TEXT,\n" +
" about TEXT,\n" +
" picture TEXT\n" +
" );");
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_group_messages(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" group_id TEXT NOT NULL,\n" +
" hidden INT DEFAULT 0\n" +
" );");
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN muted_groups INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_group_meta ADD COLUMN deleted INT DEFAULT 0;");
instance.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN read INT DEFAULT 0;");
instance.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN user_mentioned INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN updated_at INT DEFAULT 0;");
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN mode TEXT;");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN ln_address TEXT;");
instance.execSQL("UPDATE nostros_users SET ln_address=lnurl;");
instance.execSQL("ALTER TABLE nostros_users ADD COLUMN zap_pubkey TEXT;");
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_zaps(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" amount FLOAT NOT NULL,\n" +
" zapped_user_id TEXT NOT NULL,\n" +
" zapper_user_id TEXT NOT NULL,\n" +
" zapped_event_id TEXT\n" +
" );");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_relays ADD COLUMN deleted_at INT DEFAULT 0;");
} catch (SQLException e) { }
try {
instance.execSQL("DROP INDEX nostros_notes_notifications_index;");
} catch (SQLException e) { }
try {
instance.execSQL("CREATE INDEX nostros_zaps_list_index ON nostros_zaps(zapper_user_id);");
instance.execSQL("CREATE INDEX nostros_zaps_user_index ON nostros_zaps(zapper_user_id, zapped_event_id);");
instance.execSQL("CREATE INDEX nostros_zaps_most_zapped_index ON nostros_zaps(zapped_user_id, created_at, contact);");
instance.execSQL("CREATE INDEX nostros_users_names_index ON nostros_users(id, name); ");
instance.execSQL("CREATE INDEX nostros_users_contacts_index ON nostros_users(id, contact); ");
instance.execSQL("CREATE INDEX nostros_users_blocked_index ON nostros_users(id, blocked); ");
instance.execSQL("CREATE INDEX nostros_users_muted_index ON nostros_users(id, muted_groups); ");
instance.execSQL("CREATE INDEX nostros_users_contact_index ON nostros_users(contact); ");
instance.execSQL("CREATE INDEX nostros_notes_home_index ON nostros_notes(pubkey, created_at, main_event_id, repost_id); ");
instance.execSQL("CREATE INDEX nostros_notes_notifications_index ON nostros_notes(pubkey, user_mentioned, reply_event_id, created_at); ");
instance.execSQL("CREATE INDEX nostros_notes_reply_index ON nostros_notes(reply_event_id); ");
instance.execSQL("CREATE INDEX nostros_notes_list_index ON nostros_notes(pubkey, created_at); ");
instance.execSQL("CREATE INDEX nostros_notes_repost_count_index ON nostros_notes(pubkey, repost_id, created_at); ");
instance.execSQL("CREATE INDEX nostros_group_messages_mentions_index ON nostros_group_messages(group_id, pubkey, created_at);");
instance.execSQL("CREATE INDEX nostros_group_messages_group_index ON nostros_group_messages(group_id, created_at);");
instance.execSQL("CREATE INDEX nostros_group_messages_feed_index ON nostros_group_messages(user_mentioned, read, group_id);");
instance.execSQL("CREATE INDEX nostros_notes_relays_notes_index ON nostros_notes_relays(note_id, relay_url);");
instance.execSQL("CREATE INDEX nostros_notes_relays_users_index ON nostros_notes_relays(pubkey, relay_url);");
instance.execSQL("CREATE INDEX nostros_direct_messages_feed_index ON nostros_direct_messages(pubkey, created_at); ");
instance.execSQL("CREATE INDEX nostros_direct_messages_notification_index ON nostros_direct_messages(pubkey, read); ");
instance.execSQL("CREATE INDEX nostros_direct_messages_conversation_index ON nostros_direct_messages(created_at, conversation_id); ");
// Previous
instance.execSQL("CREATE INDEX nostros_users_contact_follower_index ON nostros_users(contact, follower); ");
instance.execSQL("CREATE INDEX nostros_reactions_created_at_reacted_event_id_index ON nostros_reactions(created_at, reacted_event_id); ");
instance.execSQL("CREATE INDEX nostros_notes_pubkey_index ON nostros_notes(pubkey); ");
instance.execSQL("CREATE INDEX nostros_notes_main_event_id_index ON nostros_notes(main_event_id); ");
instance.execSQL("CREATE INDEX nostros_direct_messages_pubkey_index ON nostros_direct_messages(pubkey); ");
instance.execSQL("CREATE INDEX nostros_direct_messages_conversation_id_index ON nostros_direct_messages(conversation_id); ");
instance.execSQL("CREATE INDEX nostros_reactions_reacted_event_id_index ON nostros_reactions(reacted_event_id); ");
instance.execSQL("CREATE INDEX nostros_users_contact_index ON nostros_users(contact); ");
instance.execSQL("CREATE INDEX nostros_reactions_pubkey_index ON nostros_reactions(pubkey); ");
instance.execSQL("CREATE INDEX nostros_nostros_zaps_zapped_event_id_index ON nostros_zaps(zapped_event_id);");
} catch (SQLException e) { }
try {
instance.execSQL("CREATE TABLE IF NOT EXISTS nostros_lists(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL\n" +
" );");
instance.execSQL("CREATE INDEX nostros_nostros_list_index ON nostros_lists(kind, pubkey);");
} catch (SQLException e) { }
try {
instance.execSQL("ALTER TABLE nostros_lists ADD COLUMN list_tag TEXT;");
} catch (SQLException e) { }
}
public void saveEvent(JSONObject data, String userPubKey, String relayUrl) throws JSONException {
Event event = new Event(data);
event.save(instance, userPubKey, relayUrl);
}
public void saveRelay(Relay relay) {
relay.save(this);
}
public void deleteRelay(String relayUrl) {
String whereClause = "url = ?";
String[] whereArgs = new String[] {
relayUrl
};
ContentValues values = new ContentValues();
values.put("deleted_at", System.currentTimeMillis() / 1000L);
instance.update ("nostros_relays", values, whereClause, whereArgs);
}
public List<Relay> getRelays(ReactApplicationContext reactContext) {
List<Relay> relayList = new ArrayList<>();
String query = "SELECT url, active, global_feed FROM nostros_relays WHERE deleted_at = 0 AND active = 1;";
@SuppressLint("Recycle") Cursor cursor = instance.rawQuery(query, new String[] {});
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
try {
String relayUrl = cursor.getString(0);
int active = cursor.getInt(1);
int globalFeed = cursor.getInt(2);
Relay relay = new Relay(relayUrl, active, globalFeed,this, reactContext);
relayList.add(relay);
} catch (IOException e) {
Log.d("WebSocket", e.toString());
}
cursor.moveToNext();
}
}
return relayList;
}
}

View File

@ -16,7 +16,7 @@ public class Relay {
public int active;
public int globalFeed;
public Relay(String serverUrl, int isActive, int showGlobalFeed, DatabaseModule database, ReactApplicationContext reactContext) throws IOException {
public Relay(String serverUrl, int isActive, int showGlobalFeed, Database database, ReactApplicationContext reactContext) throws IOException {
webSocket = new Websocket(serverUrl, database, reactContext);
url = serverUrl;
active = isActive;
@ -47,12 +47,12 @@ public class Relay {
webSocket.connect(userPubKey);
}
public void save(SQLiteDatabase database) {
public void save(Database database) {
ContentValues values = new ContentValues();
values.put("url", url);
values.put("active", active);
values.put("global_feed", globalFeed);
values.put("deleted_at", 0);
database.replace("nostros_relays", null, values);
database.instance.replace("nostros_relays", null, values);
}
}

View File

@ -19,13 +19,13 @@ import java.io.IOException;
public class Websocket {
private WebSocket webSocket;
private DatabaseModule database;
private Database database;
private String url;
private String pubKey;
private ReactApplicationContext context;
public Websocket(String serverUrl, DatabaseModule databaseModule, ReactApplicationContext reactContext) {
database = databaseModule;
public Websocket(String serverUrl, Database databaseEntity, ReactApplicationContext reactContext) {
database = databaseEntity;
url = serverUrl;
context = reactContext;
}

View File

@ -7,8 +7,13 @@ import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.nostros.classes.Database;
import com.nostros.classes.Event;
import com.nostros.classes.Relay;
@ -19,253 +24,103 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DatabaseModule {
public SQLiteDatabase database;
public class DatabaseModule extends ReactContextBaseJavaModule {
private Database database;
private ReactApplicationContext context;
DatabaseModule(String absoluteFilesPath) {
database = SQLiteDatabase.openDatabase( absoluteFilesPath + "/nostros.sqlite", null, SQLiteDatabase.CREATE_IF_NECESSARY);
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_notes(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" main_event_id TEXT,\n" +
" reply_event_id TEXT\n" +
" );");
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_users(\n" +
" id TEXT PRIMARY KEY NOT NULL,\n" +
" name TEXT,\n" +
" picture TEXT,\n" +
" about TEXT,\n" +
" main_relay TEXT,\n" +
" contact INT DEFAULT 0,\n" +
" follower INT DEFAULT 0\n" +
" );");
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_relays(\n" +
" url TEXT PRIMARY KEY NOT NULL,\n" +
" pet INTEGER\n" +
" );");
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_direct_messages(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" conversation_id TEXT NOT NULL,\n" +
" read INT DEFAULT 0\n" +
" );");
try {
database.execSQL("ALTER TABLE nostros_notes ADD COLUMN user_mentioned INT DEFAULT 0;");
database.execSQL("ALTER TABLE nostros_notes ADD COLUMN seen INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_users ADD COLUMN lnurl TEXT;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_users ADD COLUMN created_at INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_reactions(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" positive INT DEFAULT 1,\n" +
" reacted_event_id TEXT,\n" +
" reacted_user_id TEXT\n" +
" );");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_users ADD COLUMN nip05 TEXT;");
database.execSQL("ALTER TABLE nostros_users ADD COLUMN valid_nip05 INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_notes ADD COLUMN repost_id TEXT;");
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN active INT DEFAULT 1;");
} catch (SQLException e) { }
try {
database.execSQL("DROP TABLE IF EXISTS nostros_config;");
database.execSQL("ALTER TABLE nostros_users ADD COLUMN blocked INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_notes_relays(\n" +
" note_id TEXT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" relay_url INT NOT NULL,\n" +
" PRIMARY KEY (note_id, relay_url)\n" +
" );");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_users ADD COLUMN pet_at INT;");
database.execSQL("ALTER TABLE nostros_users ADD COLUMN follower_at INT;");
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN global_feed INT DEFAULT 1;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN resilient INT DEFAULT 0;");
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN manual INT DEFAULT 1;");
} catch (SQLException e) { }
try {
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_group_meta(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT,\n" +
" created_at INT,\n" +
" kind INT,\n" +
" pubkey TEXT,\n" +
" sig TEXT,\n" +
" tags TEXT,\n" +
" name TEXT,\n" +
" about TEXT,\n" +
" picture TEXT\n" +
" );");
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_group_messages(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" group_id TEXT NOT NULL,\n" +
" hidden INT DEFAULT 0\n" +
" );");
database.execSQL("ALTER TABLE nostros_users ADD COLUMN muted_groups INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_group_meta ADD COLUMN deleted INT DEFAULT 0;");
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN read INT DEFAULT 0;");
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN user_mentioned INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN updated_at INT DEFAULT 0;");
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN mode TEXT;");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_users ADD COLUMN ln_address TEXT;");
database.execSQL("UPDATE nostros_users SET ln_address=lnurl;");
database.execSQL("ALTER TABLE nostros_users ADD COLUMN zap_pubkey TEXT;");
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_zaps(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL,\n" +
" amount FLOAT NOT NULL,\n" +
" zapped_user_id TEXT NOT NULL,\n" +
" zapper_user_id TEXT NOT NULL,\n" +
" zapped_event_id TEXT\n" +
" );");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN deleted_at INT DEFAULT 0;");
} catch (SQLException e) { }
try {
database.execSQL("DROP INDEX nostros_notes_notifications_index;");
} catch (SQLException e) { }
try {
database.execSQL("CREATE INDEX nostros_zaps_list_index ON nostros_zaps(zapper_user_id);");
database.execSQL("CREATE INDEX nostros_zaps_user_index ON nostros_zaps(zapper_user_id, zapped_event_id);");
database.execSQL("CREATE INDEX nostros_zaps_most_zapped_index ON nostros_zaps(zapped_user_id, created_at, contact);");
database.execSQL("CREATE INDEX nostros_users_names_index ON nostros_users(id, name); ");
database.execSQL("CREATE INDEX nostros_users_contacts_index ON nostros_users(id, contact); ");
database.execSQL("CREATE INDEX nostros_users_blocked_index ON nostros_users(id, blocked); ");
database.execSQL("CREATE INDEX nostros_users_muted_index ON nostros_users(id, muted_groups); ");
database.execSQL("CREATE INDEX nostros_users_contact_index ON nostros_users(contact); ");
database.execSQL("CREATE INDEX nostros_notes_home_index ON nostros_notes(pubkey, created_at, main_event_id, repost_id); ");
database.execSQL("CREATE INDEX nostros_notes_notifications_index ON nostros_notes(pubkey, user_mentioned, reply_event_id, created_at); ");
database.execSQL("CREATE INDEX nostros_notes_reply_index ON nostros_notes(reply_event_id); ");
database.execSQL("CREATE INDEX nostros_notes_list_index ON nostros_notes(pubkey, created_at); ");
database.execSQL("CREATE INDEX nostros_notes_repost_count_index ON nostros_notes(pubkey, repost_id, created_at); ");
database.execSQL("CREATE INDEX nostros_group_messages_mentions_index ON nostros_group_messages(group_id, pubkey, created_at);");
database.execSQL("CREATE INDEX nostros_group_messages_group_index ON nostros_group_messages(group_id, created_at);");
database.execSQL("CREATE INDEX nostros_group_messages_feed_index ON nostros_group_messages(user_mentioned, read, group_id);");
database.execSQL("CREATE INDEX nostros_notes_relays_notes_index ON nostros_notes_relays(note_id, relay_url);");
database.execSQL("CREATE INDEX nostros_notes_relays_users_index ON nostros_notes_relays(pubkey, relay_url);");
database.execSQL("CREATE INDEX nostros_direct_messages_feed_index ON nostros_direct_messages(pubkey, created_at); ");
database.execSQL("CREATE INDEX nostros_direct_messages_notification_index ON nostros_direct_messages(pubkey, read); ");
database.execSQL("CREATE INDEX nostros_direct_messages_conversation_index ON nostros_direct_messages(created_at, conversation_id); ");
// Previous
database.execSQL("CREATE INDEX nostros_users_contact_follower_index ON nostros_users(contact, follower); ");
database.execSQL("CREATE INDEX nostros_reactions_created_at_reacted_event_id_index ON nostros_reactions(created_at, reacted_event_id); ");
database.execSQL("CREATE INDEX nostros_notes_pubkey_index ON nostros_notes(pubkey); ");
database.execSQL("CREATE INDEX nostros_notes_main_event_id_index ON nostros_notes(main_event_id); ");
database.execSQL("CREATE INDEX nostros_direct_messages_pubkey_index ON nostros_direct_messages(pubkey); ");
database.execSQL("CREATE INDEX nostros_direct_messages_conversation_id_index ON nostros_direct_messages(conversation_id); ");
database.execSQL("CREATE INDEX nostros_reactions_reacted_event_id_index ON nostros_reactions(reacted_event_id); ");
database.execSQL("CREATE INDEX nostros_users_contact_index ON nostros_users(contact); ");
database.execSQL("CREATE INDEX nostros_reactions_pubkey_index ON nostros_reactions(pubkey); ");
database.execSQL("CREATE INDEX nostros_nostros_zaps_zapped_event_id_index ON nostros_zaps(zapped_event_id);");
} catch (SQLException e) { }
try {
database.execSQL("CREATE TABLE IF NOT EXISTS nostros_lists(\n" +
" id TEXT PRIMARY KEY NOT NULL, \n" +
" content TEXT NOT NULL,\n" +
" created_at INT NOT NULL,\n" +
" kind INT NOT NULL,\n" +
" pubkey TEXT NOT NULL,\n" +
" sig TEXT NOT NULL,\n" +
" tags TEXT NOT NULL\n" +
" );");
database.execSQL("CREATE INDEX nostros_nostros_list_index ON nostros_lists(kind, pubkey);");
} catch (SQLException e) { }
try {
database.execSQL("ALTER TABLE nostros_lists ADD COLUMN list_tag TEXT;");
} catch (SQLException e) { }
public DatabaseModule(ReactApplicationContext reactContext, Database databaseEntity) {
database = databaseEntity;
context = reactContext;
}
public void saveEvent(JSONObject data, String userPubKey, String relayUrl) throws JSONException {
Event event = new Event(data);
event.save(database, userPubKey, relayUrl);
@Override
public String getName() {
return "DatabaseModule";
}
public void saveRelay(Relay relay) {
relay.save(database);
}
public void deleteRelay(String relayUrl) {
String whereClause = "url = ?";
@ReactMethod
public void updateConversationRead(String conversationId) {
String whereClause = "conversation_id = ?";
String[] whereArgs = new String[] {
relayUrl
conversationId
};
ContentValues values = new ContentValues();
values.put("deleted_at", System.currentTimeMillis() / 1000L);
database.update ("nostros_relays", values, whereClause, whereArgs);
values.put("read", 1);
database.instance.update("nostros_direct_messages", values, whereClause, whereArgs);
}
public List<Relay> getRelays(ReactApplicationContext reactContext) {
List<Relay> relayList = new ArrayList<>();
String query = "SELECT url, active, global_feed FROM nostros_relays WHERE deleted_at = 0 AND active = 1;";
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {});
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
try {
String relayUrl = cursor.getString(0);
int active = cursor.getInt(1);
int globalFeed = cursor.getInt(2);
Relay relay = new Relay(relayUrl, active, globalFeed,this, reactContext);
relayList.add(relay);
} catch (IOException e) {
Log.d("WebSocket", e.toString());
}
cursor.moveToNext();
}
}
return relayList;
@ReactMethod
public void updateAllDirectMessagesRead() {
String whereClause = "";
String[] whereArgs = new String[] {};
ContentValues values = new ContentValues();
values.put("read", 1);
database.instance.update("nostros_direct_messages", values, whereClause, whereArgs);
}
@ReactMethod
public void updateUserContact(String userId, boolean contact, Callback callback) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { userId };
ContentValues values = new ContentValues();
values.put("contact", contact ? 1 : 0);
database.instance.update("nostros_users", values, whereClause, whereArgs);
callback.invoke();
}
@ReactMethod
public void updateUserBlock(String userId, boolean blocked, Callback callback) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { userId };
ContentValues values = new ContentValues();
values.put("blocked", blocked ? 1 : 0);
database.instance.update("nostros_users", values, whereClause, whereArgs);
callback.invoke();
}
@ReactMethod
public void updateUserMutesGroups(String userId, boolean muted, Callback callback) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { userId };
ContentValues values = new ContentValues();
values.put("muted_groups", muted ? 1 : 0);
database.instance.update("nostros_users", values, whereClause, whereArgs);
callback.invoke();
}
@ReactMethod
public void updateAllGroupMessagesRead() {
String whereClause = "";
String[] whereArgs = new String[] { };
ContentValues values = new ContentValues();
values.put("read", 1);
database.instance.update("nostros_group_messages", values, whereClause, whereArgs);
}
@ReactMethod
public void updateGroupRead(String groupId) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { groupId };
ContentValues values = new ContentValues();
values.put("read", 1);
database.instance.update("nostros_group_messages", values, whereClause, whereArgs);
}
@ReactMethod
public void deleteGroup(String groupId) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { groupId };
ContentValues values = new ContentValues();
values.put("deleted", 1);
database.instance.update("nostros_group_meta", values, whereClause, whereArgs);
}
@ReactMethod
public void activateGroup(String groupId) {
String whereClause = "id = ?";
String[] whereArgs = new String[] { groupId };
ContentValues values = new ContentValues();
values.put("deleted", 0);
database.instance.update("nostros_group_meta", values, whereClause, whereArgs);
}
}

View File

@ -1,5 +1,6 @@
package com.nostros.modules;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.facebook.react.bridge.Callback;
@ -7,6 +8,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.nostros.classes.Database;
import com.nostros.classes.Relay;
import java.io.IOException;
@ -16,11 +18,11 @@ import java.util.ListIterator;
public class RelayPoolModule extends ReactContextBaseJavaModule {
protected List<Relay> relays;
private String userPubKey;
private DatabaseModule database;
private Database database;
private ReactApplicationContext context;
public RelayPoolModule(ReactApplicationContext reactContext) {
database = new DatabaseModule(reactContext.getFilesDir().getAbsolutePath());
public RelayPoolModule(ReactApplicationContext reactContext, Database databaseEntity) {
database = databaseEntity;
context = reactContext;
}
@ -72,7 +74,7 @@ public class RelayPoolModule extends ReactContextBaseJavaModule {
relay.connect(userPubKey);
relay.setActive(active);
relay.setGlobalFeed(globalFeed);
relay.save(database.database);
relay.save(database);
this.relays.set(index, relay);
relayExists = true;
}

View File

@ -11,7 +11,7 @@ import {
TouchableRipple,
useTheme,
} from 'react-native-paper'
import { deleteGroup, getGroup, Group } from '../../Functions/DatabaseFunctions/Groups'
import { getGroup, Group } from '../../Functions/DatabaseFunctions/Groups'
import { AppContext } from '../../Contexts/AppContext'
import { validImageUrl } from '../../Functions/NativeFunctions'
import FastImage from 'react-native-fast-image'
@ -27,6 +27,7 @@ import { goBack } from '../../lib/Navigation'
import { getUser, User } from '../../Functions/DatabaseFunctions/Users'
import ProfileData from '../ProfileData'
import GroupShare from '../GroupShare'
import DatabaseModule from '../../lib/Native/DatabaseModule'
interface GroupHeaderIconProps {
groupId: string
@ -71,7 +72,7 @@ export const GroupHeaderIcon: React.FC<GroupHeaderIconProps> = ({ groupId }) =>
const onDeleteGroup: () => void = () => {
if (database && group?.id) {
deleteGroup(database, group?.id)
DatabaseModule.deleteGroup(group?.id)
bottomSheetActionsGroupRef.current?.close()
goBack()
}

View File

@ -5,14 +5,7 @@ import { Button, IconButton, List, Snackbar, Text, useTheme } from 'react-native
import { AppContext } from '../../Contexts/AppContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { UserContext } from '../../Contexts/UserContext'
import {
addUser,
getUser,
updateUserBlock,
updateUserContact,
updateUserMutesGroups,
User,
} from '../../Functions/DatabaseFunctions/Users'
import { addUser, getUser, User } from '../../Functions/DatabaseFunctions/Users'
import { populatePets, username } from '../../Functions/RelayFunctions/Users'
import LnPayment from '../LnPayment'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
@ -25,6 +18,7 @@ import ProfileShare from '../ProfileShare'
import { ScrollView } from 'react-native-gesture-handler'
import { Kind } from 'nostr-tools'
import { getUnixTime } from 'date-fns'
import DatabaseModule from '../../lib/Native/DatabaseModule'
interface ProfileActionsProps {
user: User
@ -69,7 +63,7 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
})
.then(() => {
if (database) {
updateUserMutesGroups(database, user.id, true).then(() => {
DatabaseModule.updateUserMutesGroups(user.id, true, () => {
setIsMuted(true)
bottomSheetMuteRef.current?.close()
})
@ -108,7 +102,7 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
const onChangeBlockUser: () => void = () => {
if (database && publicKey) {
addUser(user.id, database).then(() => {
updateUserBlock(user.id, database, !isBlocked).then(() => {
DatabaseModule.updateUserBlock(user.id, !isBlocked, () => {
loadUser()
setShowNotificationRelay(isBlocked ? 'userUnblocked' : 'userBlocked')
})
@ -118,7 +112,7 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
const removeContact: () => void = () => {
if (relayPool && database && publicKey) {
updateUserContact(user.id, database, false).then(() => {
DatabaseModule.updateUserContact(user.id, false, () => {
populatePets(relayPool, database, publicKey)
setIsContact(false)
setShowNotification('contactRemoved')
@ -128,7 +122,7 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
const addContact: () => void = () => {
if (relayPool && database && publicKey) {
updateUserContact(user.id, database, true).then(() => {
DatabaseModule.updateUserContact(user.id, true, () => {
populatePets(relayPool, database, publicKey)
setIsContact(true)
setShowNotification('contactAdded')

View File

@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from 'react'
import ParsedText from 'react-native-parsed-text'
import { Event } from '../../lib/nostr/Events'
import { Linking, StyleSheet, View } from 'react-native'
import { Clipboard, Linking, StyleSheet, View } from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
import { getUser, User } from '../../Functions/DatabaseFunctions/Users'
import { formatPubKey } from '../../Functions/RelayFunctions/Users'
@ -21,6 +21,7 @@ interface TextContentProps {
showPreview?: boolean
onPressUser?: (user: User) => void
numberOfLines?: number
copyText?: boolean
}
export const TextContent: React.FC<TextContentProps> = ({
@ -29,6 +30,7 @@ export const TextContent: React.FC<TextContentProps> = ({
showPreview = true,
onPressUser = () => {},
numberOfLines,
copyText = false,
}) => {
const theme = useTheme()
const { t } = useTranslation('common')
@ -153,6 +155,10 @@ export const TextContent: React.FC<TextContentProps> = ({
return matchingString
}
const onLongPress: () => void = () => {
if (copyText) Clipboard.setString(text)
}
const preview = React.useMemo(() => {
if (!showPreview) return <></>
@ -265,6 +271,7 @@ export const TextContent: React.FC<TextContentProps> = ({
]}
childrenProps={{ allowFontScaling: false }}
numberOfLines={numberOfLines}
onLongPress={onLongPress}
>
{text}
</ParsedText>

View File

@ -13,7 +13,7 @@ interface UploadImageProps {
setImageUri: (uri: string) => void
uploadingFile: boolean
setUploadingFile: (uploading: boolean) => void
onError: () => void
onError?: () => void
}
export const UploadImage: React.FC<UploadImageProps> = ({
@ -22,7 +22,7 @@ export const UploadImage: React.FC<UploadImageProps> = ({
setImageUri,
uploadingFile,
setUploadingFile,
onError,
onError = () => {},
}) => {
const { getImageHostingService } = useContext(AppContext)
const theme = useTheme()

View File

@ -1,4 +1,4 @@
import { QueryResult, QuickSQLiteConnection } from 'react-native-quick-sqlite'
import { QuickSQLiteConnection } from 'react-native-quick-sqlite'
import { getItems } from '..'
import { Event, evetDatabaseToEntity } from '../../../lib/nostr/Events'
@ -29,21 +29,6 @@ export const getRawUserConversation: (
return notes
}
export const updateConversationRead: (
conversationId: string,
db: QuickSQLiteConnection,
) => Promise<QueryResult | null> = async (conversationId, db) => {
const userQuery = `UPDATE nostros_direct_messages SET read = ? WHERE conversation_id = ?`
return db.execute(userQuery, [1, conversationId])
}
export const updateAllDirectMessagesRead: (
db: QuickSQLiteConnection,
) => Promise<QueryResult | null> = async (db) => {
const userQuery = `UPDATE nostros_direct_messages SET read = ?`
return db.execute(userQuery, [1])
}
export const getDirectMessagesCount: (
db: QuickSQLiteConnection,
pubKey: string,

View File

@ -27,13 +27,6 @@ const databaseToGroupMessage: (object: any) => GroupMessage = (object = {}) => {
return object as GroupMessage
}
export const updateAllGroupMessagesRead: (
db: QuickSQLiteConnection,
) => Promise<QueryResult | null> = async (db) => {
const userQuery = `UPDATE nostros_group_messages SET read = ?`
return db.execute(userQuery, [1])
}
export const getGroups: (db: QuickSQLiteConnection) => Promise<Group[]> = async (db) => {
const groupsQuery = `
SELECT
@ -130,37 +123,6 @@ export const deleteGroupMessages: (
return db.execute(deleteQuery, [pubkey])
}
export const deleteGroup: (
db: QuickSQLiteConnection,
groupId: string,
) => Promise<QueryResult> = async (db, groupId) => {
const userQuery = `UPDATE nostros_group_meta SET deleted = 1 WHERE id = ?;`
return db.execute(userQuery, [groupId])
}
export const updateAllDirectMessagesRead: (
db: QuickSQLiteConnection,
) => Promise<QueryResult | null> = async (db) => {
const userQuery = `UPDATE nostros_group_messages SET read = ?`
return db.execute(userQuery, [1])
}
export const activateGroup: (
db: QuickSQLiteConnection,
groupId: string,
) => Promise<QueryResult> = async (db, groupId) => {
const userQuery = `UPDATE nostros_group_meta SET deleted = 0 WHERE id = ?;`
return db.execute(userQuery, [groupId])
}
export const updateGroupRead: (
db: QuickSQLiteConnection,
groupId: string,
) => Promise<QueryResult | null> = async (db, groupId) => {
const userQuery = `UPDATE nostros_group_messages SET read = ? WHERE group_id = ?`
return db.execute(userQuery, [1, groupId])
}
export const getUserGroupMessagesCount: (
db: QuickSQLiteConnection,
publicKey: string,

View File

@ -23,39 +23,6 @@ const databaseToEntity: (object: object) => User = (object) => {
return object as User
}
export const updateUserContact: (
userId: string,
db: QuickSQLiteConnection,
contact: boolean,
) => Promise<QueryResult | null> = async (userId, db, contact) => {
const userQuery = `UPDATE nostros_users SET contact = ? WHERE id = ?`
await addUser(userId, db)
return db.execute(userQuery, [contact ? 1 : 0, userId])
}
export const updateUserBlock: (
userId: string,
db: QuickSQLiteConnection,
blocked: boolean,
) => Promise<QueryResult | null> = async (userId, db, blocked) => {
const userQuery = `UPDATE nostros_users SET blocked = ? WHERE id = ?`
await addUser(userId, db)
return db.execute(userQuery, [blocked ? 1 : 0, userId])
}
export const updateUserMutesGroups: (
db: QuickSQLiteConnection,
userId: string,
muted: boolean,
) => Promise<QueryResult | null> = async (db, userId, muted) => {
const userQuery = `UPDATE nostros_users SET muted_groups = ? WHERE id = ?`
await addUser(userId, db)
return db.execute(userQuery, [muted ? 1 : 0, userId])
}
export const getUser: (pubkey: string, db: QuickSQLiteConnection) => Promise<User | null> = async (
pubkey,
db,

View File

@ -5,13 +5,7 @@ import { AppContext } from '../../Contexts/AppContext'
import { Kind } from 'nostr-tools'
import { useTranslation } from 'react-i18next'
import { FlashList, ListRenderItem } from '@shopify/flash-list'
import {
getBlocked,
getFollowersAndFollowing,
updateUserBlock,
updateUserContact,
User,
} from '../../Functions/DatabaseFunctions/Users'
import { getBlocked, getFollowersAndFollowing, User } from '../../Functions/DatabaseFunctions/Users'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { populatePets } from '../../Functions/RelayFunctions/Users'
import { getNip19Key, getNpub } from '../../lib/nostr/Nip19'
@ -33,6 +27,7 @@ import ProfileData from '../../Components/ProfileData'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import { queryProfile } from 'nostr-tools/nip05'
import { navigate } from '../../lib/Navigation'
import DatabaseModule from '../../lib/Native/DatabaseModule'
export const ContactsPage: React.FC = () => {
const { t } = useTranslation('common')
@ -136,17 +131,12 @@ export const ContactsPage: React.FC = () => {
}
if (hexKey) {
updateUserContact(hexKey, database, true)
.then(() => {
populatePets(relayPool, database, publicKey)
loadUsers()
setIsAddingContact(false)
setShowNotification('contactAdded')
})
.catch(() => {
setIsAddingContact(false)
setShowNotification('addContactError')
})
DatabaseModule.updateUserContact(hexKey, true, () => {
populatePets(relayPool, database, publicKey)
loadUsers()
setIsAddingContact(false)
setShowNotification('contactAdded')
})
} else {
setIsAddingContact(false)
setShowNotification('addContactError')
@ -162,7 +152,7 @@ export const ContactsPage: React.FC = () => {
const removeContact: (user: User) => void = (user) => {
if (relayPool && database && publicKey) {
updateUserContact(user.id, database, false).then(() => {
DatabaseModule.updateUserContact(user.id, false, () => {
populatePets(relayPool, database, publicKey)
setShowNotification('contactRemoved')
loadUsers()
@ -172,9 +162,9 @@ export const ContactsPage: React.FC = () => {
const addContact: (user: User) => void = (user) => {
if (relayPool && database && publicKey) {
updateUserContact(user.id, database, true).then(() => {
DatabaseModule.updateUserContact(user.id, true, () => {
populatePets(relayPool, database, publicKey)
setShowNotification('contactAdded')
setShowNotification('contactRemoved')
loadUsers()
})
}
@ -182,7 +172,7 @@ export const ContactsPage: React.FC = () => {
const unblock: (user: User) => void = (user) => {
if (relayPool && database && publicKey) {
updateUserBlock(user.id, database, false).then(() => {
DatabaseModule.updateUserBlock(user.id, false, () => {
setShowNotification('contactUnblocked')
loadUsers()
})

View File

@ -12,11 +12,7 @@ import {
import { AppContext } from '../../Contexts/AppContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { Event } from '../../lib/nostr/Events'
import {
DirectMessage,
getDirectMessages,
updateConversationRead,
} from '../../Functions/DatabaseFunctions/DirectMessages'
import { DirectMessage, getDirectMessages } from '../../Functions/DatabaseFunctions/DirectMessages'
import { getUser, User } from '../../Functions/DatabaseFunctions/Users'
import { useTranslation } from 'react-i18next'
import { username, usernamePubKey, usersToTags } from '../../Functions/RelayFunctions/Users'
@ -41,6 +37,7 @@ import NostrosAvatar from '../../Components/NostrosAvatar'
import UploadImage from '../../Components/UploadImage'
import { Swipeable } from 'react-native-gesture-handler'
import { getETags } from '../../Functions/RelayFunctions/Events'
import DatabaseModule from '../../lib/Native/DatabaseModule'
interface ConversationPageProps {
route: { params: { pubKey: string; conversationId: string } }
@ -87,7 +84,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
const loadDirectMessages: (subscribe: boolean) => void = (subscribe) => {
if (database && publicKey && privateKey) {
const conversationId = route.params?.conversationId
updateConversationRead(conversationId, database)
DatabaseModule.updateConversationRead(conversationId)
setRefreshBottomBarAt(getUnixTime(new Date()))
getUser(otherPubKey, database).then((user) => {
if (user) setOtherUser(user)
@ -254,6 +251,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
content={message?.content}
event={message}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
copyText
/>
) : (
<Text>{t('groupPage.replyText')}</Text>

View File

@ -18,14 +18,13 @@ import ConfigPage from '../ConfigPage'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { AppContext } from '../../Contexts/AppContext'
import RelayCard from '../../Components/RelayCard'
import { updateAllDirectMessagesRead } from '../../Functions/DatabaseFunctions/DirectMessages'
import { getUnixTime } from 'date-fns'
import ContactsPage from '../ContactsPage'
import GroupPage from '../GroupPage'
import GroupHeaderIcon from '../../Components/GroupHeaderIcon'
import NoteActions from '../../Components/NoteActions'
import { updateAllGroupMessagesRead } from '../../Functions/DatabaseFunctions/Groups'
import QrReaderPage from '../QrReaderPage'
import DatabaseModule from '../../lib/Native/DatabaseModule'
export const HomeNavigator: React.FC = () => {
const theme = useTheme()
@ -71,12 +70,12 @@ export const HomeNavigator: React.FC = () => {
}
const onMesssagesPressCheckAll: () => void = () => {
if (database) updateAllDirectMessagesRead(database)
if (database) DatabaseModule.updateAllDirectMessagesRead()
setRefreshBottomBarAt(getUnixTime(new Date()))
}
const onGroupsPressCheckAll: () => void = () => {
if (database) updateAllGroupMessagesRead(database)
if (database) DatabaseModule.updateAllGroupMessagesRead()
setRefreshBottomBarAt(getUnixTime(new Date()))
}

View File

@ -31,16 +31,13 @@ import { Kind } from 'nostr-tools'
import { formatDate, handleInfinityScroll } from '../../Functions/NativeFunctions'
import NostrosAvatar from '../../Components/NostrosAvatar'
import UploadImage from '../../Components/UploadImage'
import {
getGroupMessages,
GroupMessage,
updateGroupRead,
} from '../../Functions/DatabaseFunctions/Groups'
import { getGroupMessages, GroupMessage } from '../../Functions/DatabaseFunctions/Groups'
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
import { getUsers, User } from '../../Functions/DatabaseFunctions/Users'
import ProfileData from '../../Components/ProfileData'
import { ScrollView, Swipeable } from 'react-native-gesture-handler'
import { getETags } from '../../Functions/RelayFunctions/Events'
import DatabaseModule from '../../lib/Native/DatabaseModule'
interface GroupPageProps {
route: { params: { groupId: string } }
@ -82,7 +79,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
if (database && publicKey && route.params.groupId) {
updateGroupRead(database, route.params.groupId)
DatabaseModule.updateGroupRead(route.params.groupId)
getGroupMessages(database, route.params.groupId, {
order: 'DESC',
limit: pageSize,
@ -312,6 +309,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
content={message?.content}
event={message}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
copyText
/>
) : (
<Text>{t('groupPage.replyText')}</Text>

View File

@ -24,7 +24,6 @@ import { getUnixTime } from 'date-fns'
import { useFocusEffect } from '@react-navigation/native'
import { AppContext } from '../../Contexts/AppContext'
import {
activateGroup,
addGroup,
getGroupMessagesCount,
getGroupMessagesMentionsCount,
@ -38,6 +37,7 @@ import { FlashList, ListRenderItem } from '@shopify/flash-list'
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
import { validNip21 } from '../../Functions/NativeFunctions'
import { getNip19Key } from '../../lib/nostr/Nip19'
import DatabaseModule from '../../lib/Native/DatabaseModule'
export const GroupsFeed: React.FC = () => {
const { t } = useTranslation('common')
@ -151,11 +151,11 @@ export const GroupsFeed: React.FC = () => {
const key = getNip19Key(searchGroup)
if (key) {
addGroup(database, searchGroup, '', '').then(() => loadGroups())
activateGroup(database, searchGroup)
DatabaseModule.activateGroup(searchGroup)
}
} else {
addGroup(database, searchGroup, '', '').then(() => loadGroups())
activateGroup(database, searchGroup)
DatabaseModule.activateGroup(searchGroup)
}
setSearchGroup(undefined)
bottomSheetSearchRef.current?.close()

View File

@ -46,6 +46,7 @@ export const NotificationsFeed: React.FC = () => {
'notification-feed',
'notification-replies',
'notification-reactions',
'notification-reposts',
])
updateLastSeen()
}
@ -119,6 +120,9 @@ export const NotificationsFeed: React.FC = () => {
if (notes.length > 0) {
const notedIds = notes.map((note) => note.id ?? '')
const authors = notes.map((note) => note.pubkey ?? '')
const repostIds = notes
.filter((note) => note.repost_id)
.map((note) => note.repost_id ?? '')
relayPool?.subscribe('notification-reactions', [
{
@ -130,6 +134,14 @@ export const NotificationsFeed: React.FC = () => {
'#e': notedIds,
},
])
if (repostIds.length > 0) {
relayPool?.subscribe('notification-reposts', [
{
kinds: [Kind.Text],
ids: repostIds,
},
])
}
}
})
}

View File

@ -0,0 +1,16 @@
import { NativeModules } from 'react-native'
const { DatabaseModule } = NativeModules
interface DatabaseModuleInterface {
updateConversationRead: (conversationId: string) => void
updateAllDirectMessagesRead: () => void
updateUserContact: (userId: string, contact: boolean, callback: () => void) => void
updateUserBlock: (userId: string, blocked: boolean, callback: () => void) => void
updateUserMutesGroups: (userId: string, muted: boolean, callback: () => void) => void
updateAllGroupMessagesRead: () => void
updateGroupRead: (groupId: string) => void
deleteGroup: (groupId: string) => void
activateGroup: (groupId: string) => void
}
export default DatabaseModule as DatabaseModuleInterface