mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-04-17 08:11:50 +02:00
improved processReaction so double reactions aren't printed, only 1 as needed for each reaction
This commit is contained in:
parent
29a925512a
commit
5a86a0e663
@ -21,21 +21,16 @@ const String maxDepthArg = "maxdepth";
|
||||
const String eventFileArg = "file";
|
||||
const String translateArg = "translate";
|
||||
|
||||
|
||||
void printUsage() {
|
||||
|
||||
print(gUsage);
|
||||
}
|
||||
|
||||
|
||||
Future<void> main(List<String> arguments) async {
|
||||
|
||||
final parser = ArgParser()..addOption(requestArg, abbr: 'q') ..addOption(pubkeyArg, abbr:"p")..addOption(prikeyArg, abbr:"k")
|
||||
..addOption(lastdaysArg, abbr:"d") ..addOption(relayArg, abbr:"r")
|
||||
..addFlag(helpArg, abbr:"h", defaultsTo: false)..addOption(alignArg, abbr:"a")
|
||||
..addOption(widthArg, abbr:"w")..addOption(maxDepthArg, abbr:"m")
|
||||
..addOption(eventFileArg, abbr:"f")..addFlag(translateArg, abbr: "t", defaultsTo: false);
|
||||
|
||||
try {
|
||||
ArgResults argResults = parser.parse(arguments);
|
||||
if( argResults[helpArg]) {
|
||||
@ -53,23 +48,19 @@ Future<void> main(List<String> arguments) async {
|
||||
userPrivateKey = "";
|
||||
print("Going to use public key $userPublicKey. You will not be able to send posts/replies.");
|
||||
}
|
||||
|
||||
if( argResults[prikeyArg] != null) {
|
||||
userPrivateKey = argResults[prikeyArg];
|
||||
userPublicKey = getPublicKey(userPrivateKey);
|
||||
print("Going to use the provided private key");
|
||||
}
|
||||
|
||||
if( argResults[relayArg] != null) {
|
||||
defaultServerUrl = argResults[relayArg];
|
||||
print("Going to use relay: $defaultServerUrl");
|
||||
}
|
||||
|
||||
if( argResults[lastdaysArg] != null) {
|
||||
gNumLastDays = int.parse(argResults[lastdaysArg]);
|
||||
print("Going to show posts for last $gNumLastDays days");
|
||||
}
|
||||
|
||||
if( argResults[widthArg] != null) {
|
||||
int tempTextWidth = int.parse(argResults[widthArg]);
|
||||
if( tempTextWidth < gMinValidTextWidth ) {
|
||||
@ -79,7 +70,6 @@ Future<void> main(List<String> arguments) async {
|
||||
print("Going to use $gTextWidth columns for text on screen.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// can be computed only after textWidth has been found
|
||||
if( gTextWidth > stdout.terminalColumns) {
|
||||
@ -90,7 +80,6 @@ Future<void> main(List<String> arguments) async {
|
||||
print("Cannot find terminal size. Left aligning by default.");
|
||||
gNumLeftMarginSpaces = 0;
|
||||
}
|
||||
|
||||
// undo above if left option is given
|
||||
if( argResults[alignArg] != null ) {
|
||||
if( argResults[alignArg] == "left" ) {
|
||||
@ -99,9 +88,7 @@ Future<void> main(List<String> arguments) async {
|
||||
gNumLeftMarginSpaces = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( argResults[maxDepthArg] != null) {
|
||||
|
||||
int tempMaxDepth = int.parse(argResults[maxDepthArg]);
|
||||
if( tempMaxDepth < gMinimumDepthAllowed || tempMaxDepth > gMaximumDepthAllowed) {
|
||||
print("Maximum depth cannot be less than $gMinimumDepthAllowed and cannot be more than $gMaximumDepthAllowed. Going to use the default maximum depth, which is $gDefaultMaxDepth.");
|
||||
@ -110,28 +97,23 @@ Future<void> main(List<String> arguments) async {
|
||||
print("Going to take threads to maximum depth of $gNumLastDays days");
|
||||
}
|
||||
}
|
||||
|
||||
if( argResults[eventFileArg] != null) {
|
||||
gEventsFilename = argResults[eventFileArg];
|
||||
if( gEventsFilename != "") {
|
||||
print("Going to use file to read from and store events: $gEventsFilename");
|
||||
}
|
||||
}
|
||||
|
||||
if( gEventsFilename != "") {
|
||||
print("\n");
|
||||
stdout.write('Reading events from the given file.......');
|
||||
List<Event> eventsFromFile = readEventsFromFile(gEventsFilename);
|
||||
|
||||
setRelaysIntialEvents(eventsFromFile);
|
||||
eventsFromFile.forEach((element) { element.eventData.kind == 1? numFileEvents++: numFileEvents;});
|
||||
print("read $numFileEvents posts from file \"$gEventsFilename\"");
|
||||
}
|
||||
|
||||
if( argResults[requestArg] != null) {
|
||||
//stdout.write("Got argument request: ${argResults[requestArg]}");
|
||||
stdout.write('Sending request and waiting for events...');
|
||||
|
||||
sendRequest(gListRelayUrls, argResults[requestArg]);
|
||||
Future.delayed(const Duration(milliseconds: 6000), () {
|
||||
List<Event> receivedEvents = getRecievedEvents();
|
||||
@ -152,7 +134,6 @@ Future<void> main(List<String> arguments) async {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
} on FormatException catch (e) {
|
||||
print(e.message);
|
||||
return;
|
||||
@ -167,15 +148,6 @@ Future<void> main(List<String> arguments) async {
|
||||
// get a user's events, then from its type 3 event, gets events of its follows,
|
||||
// then get the events of user-id's mentioned in p-tags of received events
|
||||
// then display them all
|
||||
|
||||
/* getUserEvents(defaultServerUrl, userPublicKey, 1000, 0);
|
||||
getUserEvents("wss://relay.damus.io", userPublicKey, 1000, 0);
|
||||
getUserEvents("wss://nostr-relay.wlvs.space", userPublicKey, 1000, 0);
|
||||
getUserEvents("wss://nostr-pub.wellorder.net ", userPublicKey, 1000, 0);
|
||||
getUserEvents("wss://relay.damus.io", userPublicKey, 1000, 0);
|
||||
|
||||
*/
|
||||
|
||||
stdout.write('Waiting for user posts to come in.....');
|
||||
Future.delayed(const Duration(milliseconds: numWaitSeconds), () {
|
||||
// count user events
|
||||
|
@ -302,7 +302,7 @@ Future<void> otherMenuUi(Tree node, var contactList) async {
|
||||
break;
|
||||
|
||||
case 10:
|
||||
stdout.write("Enter client name whose events you want to see: ");
|
||||
stdout.write("Enter nostr client name whose events you want to see: ");
|
||||
String? $tempWords = stdin.readLineSync();
|
||||
String clientName = $tempWords??"";
|
||||
if( clientName != "") {
|
||||
@ -384,12 +384,12 @@ Future<void> channelMenuUI(Tree node, var contactList) async {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Future<void> mainMenuUi(Tree node, var contactList) async {
|
||||
gDebug = 0;
|
||||
// at the very beginning, show the tree as it is, and them show the options menu
|
||||
// at the very beginning, show the tree as it is, and then show the options menu
|
||||
|
||||
//bool repliesAndLikes (Tree t) => t.repliesAndLikes(userPublicKey);
|
||||
node.printTree(0, DateTime.now().subtract(Duration(days:gNumLastDays)), selectAll);
|
||||
//relays.printInfo();
|
||||
|
||||
bool userContinue = true;
|
||||
while(userContinue) {
|
||||
@ -447,7 +447,6 @@ Future<void> mainMenuUi(Tree node, var contactList) async {
|
||||
}
|
||||
|
||||
await sendReplyPostLike(node, replyToId, replyKind, content);
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -70,9 +70,9 @@ Map< String, List<List<String>> > gReactions = {};
|
||||
List<String> gBots = [ "3b57518d02e6acfd5eb7198530b2e351e5a52278fb2499d14b66db2b5791c512", // robosats orderbook
|
||||
"887645fef0ce0c3c1218d2f5d8e6132a19304cdc57cd20281d082f38cfea0072", // bestofhn
|
||||
"f4161c88558700d23af18d8a6386eb7d7fed769048e1297811dcc34e86858fb2", // bitcoin_bot
|
||||
"105dfb7467b6286f573cae17146c55133d0dcc8d65e5239844214412218a6c36", // zerohedge
|
||||
"105dfb7467b6286f573cae17146c55133d0dcc8d65e5239844214412218a6c36", // zerohedge
|
||||
"e89538241bf737327f80a9e31bb5771ccbe8a4508c04f1d1c0ce7336706f1bee", // Bitcoin news
|
||||
""
|
||||
"6a9eb714c2889aa32e449cfbb7854bc9780feed4ff3d887e03910dcb22aa560a" // "bible bot"
|
||||
];
|
||||
|
||||
//const String gDefaultEventsFilename = "events_store_nostr.txt";
|
||||
|
@ -31,8 +31,6 @@ class Tree {
|
||||
Map<String, Tree> tempChildEventsMap = {};
|
||||
events.forEach((event) {
|
||||
// only add in map those kinds that are supported or supposed to be added ( 0 1 3 7 40)
|
||||
//if( event.eventData.kind == 40 || event.eventData.kind == 42) if( gDebug > 0) print("in from Events: got a kind 40/42 event of id ${event.eventData.id} and kind ${event.eventData.kind}" );
|
||||
//event.printEvent(0);
|
||||
if( typesInEventMap.contains(event.eventData.kind)) {
|
||||
tempChildEventsMap[event.eventData.id] = Tree(event, [], {}, [], false, {});
|
||||
}
|
||||
@ -87,6 +85,7 @@ class Tree {
|
||||
if( json.containsKey('name') ) {
|
||||
roomName = json['name'];
|
||||
}
|
||||
|
||||
if( json.containsKey('about')) {
|
||||
roomAbout = json['about'];
|
||||
}
|
||||
@ -116,13 +115,11 @@ class Tree {
|
||||
if(gDebug > 0) print("In Tree FromEvents: got id: $gCheckEventId");
|
||||
}
|
||||
|
||||
|
||||
if(tempChildEventsMap.containsKey( parentId)) {
|
||||
if( tempChildEventsMap[parentId]?.e.eventData.kind != 1) { // since parent can only be a kind 1 event
|
||||
if( gDebug > 0) print("In Tree.fromEvents: got a kind 1 event whose parent is not a type 1 post: $id");
|
||||
return;
|
||||
}
|
||||
|
||||
tempChildEventsMap[parentId]?.addChildNode(value); // in this if condition this will get called
|
||||
} else {
|
||||
if( gDebug > 0 && key == "e9c0c91d52a2cf000bb2460406139a99dd5b7823165be435e96433a600be8e41" || parentId == "f377a303a852c8821069714f43b4eef5e341c03892eacf49abb594660b2fbb00") {
|
||||
@ -132,7 +129,6 @@ class Tree {
|
||||
print("----------------------------------------------/constructor from json");
|
||||
}
|
||||
|
||||
|
||||
// in case where the parent of the new event is not in the pool of all events,
|
||||
// then we create a dummy event and put it at top ( or make this a top event?) TODO handle so that this can be replied to, and is fetched
|
||||
Tree dummyTopNode = Tree(Event("","",
|
||||
@ -187,7 +183,7 @@ class Tree {
|
||||
newEventsId.add(newEvent.eventData.id); // add here to process/give notification about this new reaction
|
||||
if(gDebug > 0) print("In insertEvents: got a new reaction by: ${newEvent.eventData.id} to $reactedTo");
|
||||
} else {
|
||||
if(gDebug > 0) print("In insertEvents: For new reaction ${newEvent.eventData.id} could not find reactedTo");
|
||||
if(gDebug > 0) print("In insertEvents: For new reaction ${newEvent.eventData.id} could not find reactedTo or reaction was already present by this reactor");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -244,7 +240,6 @@ class Tree {
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 42:
|
||||
// add 42 chat message event id to its chat room
|
||||
String channelId = newTree.e.eventData.getParent();
|
||||
@ -252,12 +247,10 @@ class Tree {
|
||||
if( chatRooms.containsKey(channelId)) {
|
||||
if( gDebug > 0) print("added event to chat room in insert event");
|
||||
addMessageToChannel(channelId, newTree.e.eventData.id, allChildEventsMap, chatRooms);
|
||||
//chatRooms[channelId]?.messageIds.add(newTree.e.eventData.id);
|
||||
}
|
||||
} else {
|
||||
print("info: in insert events, could not find parent/channel id");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -688,6 +681,42 @@ class Tree {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO
|
||||
// returns true if the treee or its children has a post or like by user; and notification flags are set for such events
|
||||
bool repliesAndLikes(String pubkey) {
|
||||
bool hasReacted = false;
|
||||
|
||||
if( gReactions.containsKey(e.eventData.id)) {
|
||||
List<List<String>>? reactions = gReactions[e.eventData.id];
|
||||
if( reactions != null) {
|
||||
for( int i = 0; i < reactions.length; i++) {
|
||||
if( reactions[i][0] == pubkey) {
|
||||
e.eventData.newLikes.add(pubkey);
|
||||
hasReacted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool childMatches = false;
|
||||
for( int i = 0; i < children.length; i++ ) {
|
||||
if( children[i].hasUserPostAndLike(pubkey)) {
|
||||
childMatches = true;
|
||||
}
|
||||
}
|
||||
if( e.eventData.pubkey == pubkey) {
|
||||
e.eventData.isNotification = true;
|
||||
return true;
|
||||
}
|
||||
if( hasReacted || childMatches) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// returns true if the treee or its children has a post or like by user; and notification flags are set for such events
|
||||
bool hasUserPostAndLike(String pubkey) {
|
||||
bool hasReacted = false;
|
||||
@ -773,8 +802,11 @@ class Tree {
|
||||
}
|
||||
}
|
||||
if( byClient || childMatch) {
|
||||
//print("SOME matched $clientName ");
|
||||
return true;
|
||||
}
|
||||
//print("none matched $clientName ");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -942,6 +974,17 @@ String processReaction(Event event) {
|
||||
int lastEIndex = event.eventData.eTagsRest.length - 1;
|
||||
String reactedTo = event.eventData.eTagsRest[lastEIndex];
|
||||
if( gReactions.containsKey(reactedTo)) {
|
||||
// check if the reaction already exists by this user
|
||||
for( int i = 0; i < ((gReactions[reactedTo]?.length)??0); i++) {
|
||||
List<String> oldReaction = (gReactions[reactedTo]?[i])??[];
|
||||
if( oldReaction.length == 2) {
|
||||
//valid reaction
|
||||
if(oldReaction[0] == reactorId) {
|
||||
return ""; // reaction by this user already exists so return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> temp = [reactorId, comment];
|
||||
gReactions[reactedTo]?.add(temp);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user