mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-11-30 15:56:51 +01:00
support for delete and hiding, fixed and new code
This commit is contained in:
@@ -81,8 +81,8 @@ nostr_console.exe --file=eventsFile.txt --prikey=K
|
|||||||
 showing re-alignment of threads for easier reading.
|
 showing re-alignment of threads for easier reading.
|
||||||
|
|
||||||
|
|
||||||
|
# Contact
|
||||||
|
|
||||||
|
[Nostr Telegram Channel](https://t.me/nostr_protocol) or at Nostr Pulic Channel 52cab2e3e504ad6447d284b85b5cc601ca0613b151641e77facfec851c2ca816
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -673,6 +673,9 @@ Future<void> mainMenuUi(Store node) async {
|
|||||||
if( content == "+") {
|
if( content == "+") {
|
||||||
print("Sending a like to given post.");
|
print("Sending a like to given post.");
|
||||||
replyKind = "7";
|
replyKind = "7";
|
||||||
|
} else if( content == "!") {
|
||||||
|
print("Hiding the given post.");
|
||||||
|
replyKind = "7";
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendReplyPostLike(node, replyToId, replyKind, content);
|
await sendReplyPostLike(node, replyToId, replyKind, content);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class EventData {
|
|||||||
int createdAt;
|
int createdAt;
|
||||||
int kind;
|
int kind;
|
||||||
String content;
|
String content;
|
||||||
List<String> eTagsRest;// rest of e tags
|
List<String> eTags;// rest of e tags
|
||||||
List<String> pTags;// list of p tags for kind:1
|
List<String> pTags;// list of p tags for kind:1
|
||||||
List<List<String>> tags;
|
List<List<String>> tags;
|
||||||
bool isNotification; // whether its to be highlighted using highlight color
|
bool isNotification; // whether its to be highlighted using highlight color
|
||||||
@@ -63,13 +63,13 @@ class EventData {
|
|||||||
bool isDeleted; // deleted by kind 5 event
|
bool isDeleted; // deleted by kind 5 event
|
||||||
|
|
||||||
String getParent() {
|
String getParent() {
|
||||||
if( eTagsRest.isNotEmpty) {
|
if( eTags.isNotEmpty) {
|
||||||
return eTagsRest[eTagsRest.length - 1];
|
return eTags[eTags.length - 1];
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData(this.id, this.pubkey, this.createdAt, this.kind, this.content, this.eTagsRest, this.pTags,
|
EventData(this.id, this.pubkey, this.createdAt, this.kind, this.content, this.eTags, this.pTags,
|
||||||
this.contactList, this.tags, this.newLikes, {this.isNotification = false, this.evaluatedContent = "", this.isHidden = false, this.isDeleted = false});
|
this.contactList, this.tags, this.newLikes, {this.isNotification = false, this.evaluatedContent = "", this.isHidden = false, this.isDeleted = false});
|
||||||
|
|
||||||
factory EventData.fromJson(dynamic json) {
|
factory EventData.fromJson(dynamic json) {
|
||||||
@@ -205,19 +205,15 @@ class EventData {
|
|||||||
if(!isUserDirectMessage(this)) {
|
if(!isUserDirectMessage(this)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//print("in translateAndExpandMentions() for a dm \npubkey = $pubkey \ncontent = $content");
|
|
||||||
//print("tags = $tags\n");
|
|
||||||
int ivIndex = content.indexOf("?iv=");
|
int ivIndex = content.indexOf("?iv=");
|
||||||
var enc_str = content.substring(0, ivIndex);
|
var enc_str = content.substring(0, ivIndex);
|
||||||
var iv = content.substring( ivIndex + 4, content.length);
|
var iv = content.substring( ivIndex + 4, content.length);
|
||||||
//print("enc_str = $enc_str ; iv = $iv");
|
|
||||||
|
|
||||||
String userKey = userPrivateKey ;
|
String userKey = userPrivateKey ;
|
||||||
String otherUserPubKey = "02" + pubkey;
|
String otherUserPubKey = "02" + pubkey;
|
||||||
if( pubkey == userPublicKey) {
|
if( pubkey == userPublicKey) {
|
||||||
userKey = userPrivateKey;
|
userKey = userPrivateKey;
|
||||||
otherUserPubKey = "02" + pubkey;
|
otherUserPubKey = "02" + pubkey;
|
||||||
//iv = "";
|
|
||||||
}
|
}
|
||||||
var decryptd = myPrivateDecrypt( userKey, otherUserPubKey, enc_str, iv); // use bob's privatekey and alic's publickey means bob can read message from alic
|
var decryptd = myPrivateDecrypt( userKey, otherUserPubKey, enc_str, iv); // use bob's privatekey and alic's publickey means bob can read message from alic
|
||||||
evaluatedContent = decryptd;
|
evaluatedContent = decryptd;
|
||||||
@@ -236,28 +232,41 @@ class EventData {
|
|||||||
|
|
||||||
// prints event data in the format that allows it to be shown in tree form by the Tree class
|
// prints event data in the format that allows it to be shown in tree form by the Tree class
|
||||||
void printEventData(int depth) {
|
void printEventData(int depth) {
|
||||||
if( id == gCheckEventId) {
|
if( !(kind == 1 || kind == 4 || kind == 42)) {
|
||||||
if(gDebug > 0) {
|
return; // only print kind 1 and 42 and 4
|
||||||
print("In Event printEventData: got message: $gCheckEventId");
|
|
||||||
isNotification = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = 4;
|
int n = 4;
|
||||||
String maxN(String v) => v.length > n? v.substring(0,n) : v.substring(0, v.length);
|
String maxN(String v) => v.length > n? v.substring(0,n) : v.substring(0, v.length);
|
||||||
void printInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$gColorEndMarker"):stdout.write(s);
|
void printInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$gColorEndMarker"):stdout.write(s);
|
||||||
|
|
||||||
|
String name = getAuthorName(pubkey);
|
||||||
String strDate = getPrintableDate(createdAt);
|
String strDate = getPrintableDate(createdAt);
|
||||||
|
String tempEvaluatedContent = evaluatedContent;
|
||||||
|
String tempContent = content;
|
||||||
|
|
||||||
|
if( isHidden) {
|
||||||
|
name = "<hidden>";
|
||||||
|
strDate = "<hidden>";
|
||||||
|
tempEvaluatedContent = tempContent = "<You have hidden this post>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete supercedes hidden
|
||||||
|
if( isDeleted) {
|
||||||
|
name = "<deleted>";
|
||||||
|
strDate = "<deleted>";
|
||||||
|
tempEvaluatedContent = tempContent = content; // content would be changed so show that
|
||||||
|
}
|
||||||
|
|
||||||
if( createdAt == 0) {
|
if( createdAt == 0) {
|
||||||
print("debug: createdAt == 0 for event $content");
|
print("debug: createdAt == 0 for event $content");
|
||||||
}
|
}
|
||||||
|
|
||||||
String contentShifted = rightShiftContent(evaluatedContent==""?content: evaluatedContent, gSpacesPerDepth * depth + 10);
|
String contentShifted = rightShiftContent(tempEvaluatedContent==""?tempContent: tempEvaluatedContent, gSpacesPerDepth * depth + 10);
|
||||||
|
|
||||||
printDepth(depth);
|
printDepth(depth);
|
||||||
stdout.write("+-------+\n");
|
stdout.write("+-------+\n");
|
||||||
printDepth(depth);
|
printDepth(depth);
|
||||||
String name = getAuthorName(pubkey);
|
|
||||||
stdout.write("|Author : $name id: ${maxN(id)} Time: $strDate\n");
|
stdout.write("|Author : $name id: ${maxN(id)} Time: $strDate\n");
|
||||||
printReaction(depth); // only prints if there are any likes/reactions
|
printReaction(depth); // only prints if there are any likes/reactions
|
||||||
printDepth(depth);
|
printDepth(depth);
|
||||||
@@ -283,24 +292,32 @@ class EventData {
|
|||||||
void printReaction(int depth) {
|
void printReaction(int depth) {
|
||||||
if( gReactions.containsKey(id)) {
|
if( gReactions.containsKey(id)) {
|
||||||
String reactorNames = "|Likes : ";
|
String reactorNames = "|Likes : ";
|
||||||
printDepth(depth);
|
|
||||||
//print("All Likes:");
|
|
||||||
int numReactions = gReactions[id]?.length??0;
|
int numReactions = gReactions[id]?.length??0;
|
||||||
List<List<String>> reactors = gReactions[id]??[];
|
List<List<String>> reactors = gReactions[id]??[];
|
||||||
|
bool firstEntry = true;
|
||||||
for( int i = 0; i <numReactions; i++) {
|
for( int i = 0; i <numReactions; i++) {
|
||||||
|
|
||||||
|
String comma = (firstEntry)?"":", ";
|
||||||
|
|
||||||
String reactorId = reactors[i][0];
|
String reactorId = reactors[i][0];
|
||||||
if( newLikes.contains(reactorId)) {
|
if( newLikes.contains(reactorId) && reactors[i][1] == "+") {
|
||||||
// colorify
|
// this is a notifications, print it and then later empty newLikes
|
||||||
reactorNames += gNotificationColor + getAuthorName(reactorId) + gColorEndMarker;
|
reactorNames += gNotificationColor + getAuthorName(reactorId) + gColorEndMarker + comma;
|
||||||
|
firstEntry = false;
|
||||||
} else {
|
} else {
|
||||||
reactorNames += getAuthorName(reactorId);
|
// this is normal printing of the reaction. only print for + for now
|
||||||
|
if( reactors[i][1] == "+")
|
||||||
|
reactorNames += getAuthorName(reactorId);
|
||||||
|
firstEntry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i < numReactions -1) {
|
} // end for
|
||||||
reactorNames += ", ";
|
|
||||||
}
|
if( !isHidden && !isDeleted) {
|
||||||
|
printDepth(depth);
|
||||||
|
print(reactorNames);
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
print(reactorNames);
|
|
||||||
newLikes.clear();
|
newLikes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
175
lib/tree_ds.dart
175
lib/tree_ds.dart
@@ -65,7 +65,8 @@ class ChatRoom extends ScrollableMessages {
|
|||||||
String picture;
|
String picture;
|
||||||
|
|
||||||
ChatRoom(this.chatRoomId, this.internalChatRoomName, this.about, this.picture, List<String> messageIds) :
|
ChatRoom(this.chatRoomId, this.internalChatRoomName, this.about, this.picture, List<String> messageIds) :
|
||||||
super ( "${internalChatRoomName} ( ${chatRoomId.substring(0, 6)}", messageIds);
|
super ( internalChatRoomName.isEmpty? chatRoomId: internalChatRoomName + "( " + chatRoomId + " )" ,
|
||||||
|
messageIds);
|
||||||
|
|
||||||
String get chatRoomName {
|
String get chatRoomName {
|
||||||
return internalChatRoomName;
|
return internalChatRoomName;
|
||||||
@@ -459,6 +460,9 @@ class Store {
|
|||||||
|
|
||||||
processDeleteEvents(tempChildEventsMap); // handle returned values perhaps later
|
processDeleteEvents(tempChildEventsMap); // handle returned values perhaps later
|
||||||
|
|
||||||
|
processReactions(events, tempChildEventsMap);
|
||||||
|
|
||||||
|
|
||||||
// once tempChildEventsMap has been created, create connections between them so we get a tree structure from all these events.
|
// once tempChildEventsMap has been created, create connections between them so we get a tree structure from all these events.
|
||||||
List<Tree> topLevelTrees = [];// this will become the children of the main top node. These are events without parents, which are printed at top.
|
List<Tree> topLevelTrees = [];// this will become the children of the main top node. These are events without parents, which are printed at top.
|
||||||
List<String> tempWithoutParent = [];
|
List<String> tempWithoutParent = [];
|
||||||
@@ -480,14 +484,13 @@ class Store {
|
|||||||
handleDirectMessages(tempDirectRooms, tempChildEventsMap, tree.event);
|
handleDirectMessages(tempDirectRooms, tempChildEventsMap, tree.event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// only posts, of kind 1, are added to the main tree structure
|
// only posts, of kind 1, are added to the main tree structure
|
||||||
if( eKind != 1) {
|
if( eKind != 1) {
|
||||||
numEventsNotPosts++;
|
numEventsNotPosts++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tree.event.eventData.eTagsRest.isNotEmpty ) {
|
if(tree.event.eventData.eTags.isNotEmpty ) {
|
||||||
// is not a parent, find its parent and then add this element to that parent Tree
|
// is not a parent, find its parent and then add this element to that parent Tree
|
||||||
String parentId = tree.event.eventData.getParent();
|
String parentId = tree.event.eventData.getParent();
|
||||||
if( tree.event.eventData.id == gCheckEventId) {
|
if( tree.event.eventData.id == gCheckEventId) {
|
||||||
@@ -518,7 +521,7 @@ class Store {
|
|||||||
|
|
||||||
// add parent trees as top level child trees of this tree
|
// add parent trees as top level child trees of this tree
|
||||||
for( var tree in tempChildEventsMap.values) {
|
for( var tree in tempChildEventsMap.values) {
|
||||||
if( tree.event.eventData.kind == 1 && tree.event.eventData.eTagsRest.isEmpty) { // only posts which are parents
|
if( tree.event.eventData.kind == 1 && tree.event.eventData.eTags.isEmpty) { // only posts which are parents
|
||||||
topLevelTrees.add(tree);
|
topLevelTrees.add(tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -550,7 +553,8 @@ class Store {
|
|||||||
|
|
||||||
// handle reaction events and return if we could not find the reacted to. Continue otherwise to add this to notification set newEventIdsSet
|
// handle reaction events and return if we could not find the reacted to. Continue otherwise to add this to notification set newEventIdsSet
|
||||||
if( newEvent.eventData.kind == 7) {
|
if( newEvent.eventData.kind == 7) {
|
||||||
if( processReaction(newEvent) == "") {
|
//print("going to call processRreactin");
|
||||||
|
if( processReaction(newEvent, allChildEventsMap) == "") {
|
||||||
if(gDebug > 0) print("In insertEvents: For new reaction ${newEvent.eventData.id} could not find reactedTo or reaction was already present by this reactor");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -598,7 +602,7 @@ class Store {
|
|||||||
switch(newTree.event.eventData.kind) {
|
switch(newTree.event.eventData.kind) {
|
||||||
case 1:
|
case 1:
|
||||||
// only kind 1 events are added to the overall tree structure
|
// only kind 1 events are added to the overall tree structure
|
||||||
if( newTree.event.eventData.eTagsRest.isEmpty) {
|
if( newTree.event.eventData.eTags.isEmpty) {
|
||||||
// if its a new parent event, then add it to the main top parents ( this.children)
|
// if its a new parent event, then add it to the main top parents ( this.children)
|
||||||
topPosts.add(newTree);
|
topPosts.add(newTree);
|
||||||
} else {
|
} else {
|
||||||
@@ -719,17 +723,21 @@ class Store {
|
|||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
Event event = t.event;
|
Event event = t.event;
|
||||||
if(gDebug >= 0) ("Got notification of type 7");
|
if(gDebug > 0) ("Got notification of type 7");
|
||||||
String reactorId = event.eventData.pubkey;
|
String reactorId = event.eventData.pubkey;
|
||||||
int lastEIndex = event.eventData.eTagsRest.length - 1;
|
int lastEIndex = event.eventData.eTags.length - 1;
|
||||||
String reactedTo = event.eventData.eTagsRest[lastEIndex];
|
String reactedTo = event.eventData.eTags[lastEIndex];
|
||||||
Event? reactedToEvent = allChildEventsMap[reactedTo]?.event;
|
Event? reactedToEvent = allChildEventsMap[reactedTo]?.event;
|
||||||
if( reactedToEvent != null) {
|
if( reactedToEvent != null) {
|
||||||
Tree? reactedToTree = allChildEventsMap[reactedTo];
|
Tree? reactedToTree = allChildEventsMap[reactedTo];
|
||||||
if( reactedToTree != null) {
|
if( reactedToTree != null) {
|
||||||
reactedToTree.event.eventData.newLikes.add( reactorId);
|
if(event.eventData.content == "+" ) {
|
||||||
Tree topTree = getTopTree(reactedToTree);
|
reactedToTree.event.eventData.newLikes.add( reactorId);
|
||||||
topNotificationTree.add(topTree);
|
Tree topTree = getTopTree(reactedToTree);
|
||||||
|
topNotificationTree.add(topTree);
|
||||||
|
} else if(event.eventData.content == "!" ) {
|
||||||
|
reactedToTree.event.eventData.isHidden = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(gDebug > 0) print("Could not find reactedTo tree");
|
if(gDebug > 0) print("Could not find reactedTo tree");
|
||||||
}
|
}
|
||||||
@@ -961,7 +969,7 @@ class Store {
|
|||||||
int linesWritten = 0;
|
int linesWritten = 0;
|
||||||
for( var tree in allChildEventsMap.values) {
|
for( var tree in allChildEventsMap.values) {
|
||||||
|
|
||||||
if( tree.event.readFromFile) { // ignore those already in file; only the new ones are writen/appended to file
|
if( tree.event.readFromFile || tree.event.eventData.isDeleted) { // ignore those already in file; only the new ones are writen/appended to file, or those deleted
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1161,7 +1169,7 @@ class Store {
|
|||||||
if( deletedEvent != null) {
|
if( deletedEvent != null) {
|
||||||
if( deletedEvent.eventData.kind == 1 && deletedEvent.eventData.pubkey == deleterEvent.eventData.pubkey) {
|
if( deletedEvent.eventData.kind == 1 && deletedEvent.eventData.pubkey == deleterEvent.eventData.pubkey) {
|
||||||
deletedEvent.eventData.isDeleted = true;
|
deletedEvent.eventData.isDeleted = true;
|
||||||
deletedEvent.eventData.content = gDeletedEventMessage + " on ${getPrintableDate(deleterEvent.eventData.createdAt)}";
|
deletedEvent.eventData.content = gDeletedEventMessage;
|
||||||
deletedEvent.eventData.evaluatedContent = "";
|
deletedEvent.eventData.evaluatedContent = "";
|
||||||
EventData ed = deletedEvent.eventData;
|
EventData ed = deletedEvent.eventData;
|
||||||
deletedEvent.originalJson = '["EVENT","none",{"id":${ed.id},"pubkey":${ed.pubkey},"createdAt":${ed.createdAt},"kind":1,"tags":[],"sig":"invalid","comment":"deleted"}]';
|
deletedEvent.originalJson = '["EVENT","none",{"id":${ed.id},"pubkey":${ed.pubkey},"createdAt":${ed.createdAt},"kind":1,"tags":[],"sig":"invalid","comment":"deleted"}]';
|
||||||
@@ -1201,7 +1209,80 @@ class Store {
|
|||||||
return foundEventIds;
|
return foundEventIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end Store
|
// for the given reaction event of kind 7, will update the global gReactions appropriately, returns
|
||||||
|
// the reactedTo event's id, blank if invalid reaction etc
|
||||||
|
static String processReaction(Event event, Map<String, Tree> tempChildEventsMap) {
|
||||||
|
|
||||||
|
if( gDebug > 0 && event.eventData.id == "e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e")
|
||||||
|
print("in processReaction: 0 got reaction e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e");
|
||||||
|
|
||||||
|
|
||||||
|
List<String> validReactionList = ["+", "!"]; // TODO support opposite reactions
|
||||||
|
List<String> opppositeReactions = ['-', "~"];
|
||||||
|
|
||||||
|
if( event.eventData.kind == 7
|
||||||
|
&& event.eventData.eTags.isNotEmpty) {
|
||||||
|
|
||||||
|
if(gDebug > 1) ("Got event of type 7"); // this can be + or !, which means 'hide' event for me
|
||||||
|
String reactorPubkey = event.eventData.pubkey;
|
||||||
|
String comment = event.eventData.content;
|
||||||
|
int lastEIndex = event.eventData.eTags.length - 1;
|
||||||
|
String reactedTo = event.eventData.eTags[lastEIndex];
|
||||||
|
|
||||||
|
if( gDebug > 0 && event.eventData.id == "e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e")
|
||||||
|
print("in processReaction: 1 got reaction e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e");
|
||||||
|
|
||||||
|
if( !validReactionList.any((element) => element == comment)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the reaction already exists by this user
|
||||||
|
if( gReactions.containsKey(reactedTo)) {
|
||||||
|
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] == reactorPubkey && oldReaction[1] == comment) {
|
||||||
|
|
||||||
|
return ""; // reaction by this user already exists so return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> temp = [reactorPubkey, comment];
|
||||||
|
gReactions[reactedTo]?.add(temp);
|
||||||
|
} else {
|
||||||
|
// first reaction to this event, create the entry in global map
|
||||||
|
List<List<String>> newReactorList = [];
|
||||||
|
List<String> temp = [reactorPubkey, comment];
|
||||||
|
newReactorList.add(temp);
|
||||||
|
gReactions[reactedTo] = newReactorList;
|
||||||
|
}
|
||||||
|
// set isHidden for reactedTo if it exists in map
|
||||||
|
|
||||||
|
if( gDebug > 0 && event.eventData.id == "e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e")
|
||||||
|
print("in processReaction: 2 got reaction e8a8a1f526af1023ba85ab3874d2310871e034eb8a0bcb3c289be671065ad03e");
|
||||||
|
|
||||||
|
if( comment == "!" && event.eventData.pubkey == userPublicKey) {
|
||||||
|
tempChildEventsMap[reactedTo]?.event.eventData.isHidden = true;
|
||||||
|
}
|
||||||
|
return reactedTo;
|
||||||
|
} else {
|
||||||
|
// case where its not a kind 7 event, or we can't find the reactedTo event due to absense of e tag.
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// will go over the list of events, and update the global gReactions appropriately
|
||||||
|
static void processReactions(Set<Event> events, Map<String, Tree> tempChildEventsMap) {
|
||||||
|
print("in processReactions");
|
||||||
|
for (Event event in events) {
|
||||||
|
processReaction(event, tempChildEventsMap);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //================================================================================================================================ end Store
|
||||||
|
|
||||||
void addMessageToChannel(String channelId, String messageId, Map<String, Tree> tempChildEventsMap, var chatRooms) {
|
void addMessageToChannel(String channelId, String messageId, Map<String, Tree> tempChildEventsMap, var chatRooms) {
|
||||||
int newEventTime = (tempChildEventsMap[messageId]?.event.eventData.createdAt??0);
|
int newEventTime = (tempChildEventsMap[messageId]?.event.eventData.createdAt??0);
|
||||||
@@ -1309,62 +1390,6 @@ int sortTreeNewestReply(Tree a, Tree b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for the given reaction event of kind 7, will update the global gReactions appropriately, returns
|
|
||||||
// the reactedTo event's id, blank if invalid reaction etc
|
|
||||||
String processReaction(Event event) {
|
|
||||||
if( event.eventData.kind == 7
|
|
||||||
&& event.eventData.eTagsRest.isNotEmpty) {
|
|
||||||
if(gDebug > 1) ("Got event of type 7"); // this can be + or !, which means 'hide' event for me
|
|
||||||
String reactorId = event.eventData.pubkey;
|
|
||||||
String comment = event.eventData.content;
|
|
||||||
int lastEIndex = event.eventData.eTagsRest.length - 1;
|
|
||||||
String reactedTo = event.eventData.eTagsRest[lastEIndex];
|
|
||||||
|
|
||||||
if( event.eventData.content == "+") {
|
|
||||||
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 {
|
|
||||||
// first reaction + to this event, create the entry in global map
|
|
||||||
List<List<String>> newReactorList = [];
|
|
||||||
List<String> temp = [reactorId, comment];
|
|
||||||
newReactorList.add(temp);
|
|
||||||
gReactions[reactedTo] = newReactorList;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if( event.eventData.content == "!") {
|
|
||||||
//reactedTo needs to ve hidden if we have it in the main tree map
|
|
||||||
// Tree? treeReactedTo =
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reactedTo;
|
|
||||||
} else {
|
|
||||||
// case where its not a kind 7 event, or we can't find the reactedTo event due to absense of e tag.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// will go over the list of events, and update the global gReactions appropriately
|
|
||||||
void processReactions(Set<Event> events) {
|
|
||||||
for (Event event in events) {
|
|
||||||
processReaction(event);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @function getTree Creates a Tree out of these received List of events.
|
* @function getTree Creates a Tree out of these received List of events.
|
||||||
@@ -1391,7 +1416,7 @@ Store getTree(Set<Event> events) {
|
|||||||
if( gDebug > 0) print("In getTree: totalKind3Processed = $totalKind3Processed notProcessed = $notProcessed3 gKindONames.length = ${gKindONames.length}");
|
if( gDebug > 0) print("In getTree: totalKind3Processed = $totalKind3Processed notProcessed = $notProcessed3 gKindONames.length = ${gKindONames.length}");
|
||||||
|
|
||||||
// process kind 7 events or reactions
|
// process kind 7 events or reactions
|
||||||
processReactions(events);
|
//processReactions(events);
|
||||||
|
|
||||||
// remove bot events
|
// remove bot events
|
||||||
events.removeWhere( (event) => gBots.contains(event.eventData.pubkey));
|
events.removeWhere( (event) => gBots.contains(event.eventData.pubkey));
|
||||||
@@ -1412,7 +1437,7 @@ Store getTree(Set<Event> events) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort all participants by id; then create a large string with them together, thats the unique id for now
|
// returns the id of event since only one p is expected in an event ( for future: sort all participants by id; then create a large string with them together, thats the unique id for now)
|
||||||
String getDirectRoomId(EventData eventData) {
|
String getDirectRoomId(EventData eventData) {
|
||||||
|
|
||||||
List<String> participantIds = [];
|
List<String> participantIds = [];
|
||||||
@@ -1427,8 +1452,10 @@ String getDirectRoomId(EventData eventData) {
|
|||||||
|
|
||||||
participantIds.sort();
|
participantIds.sort();
|
||||||
String uniqueId = "";
|
String uniqueId = "";
|
||||||
participantIds.forEach((element) {uniqueId += element;});
|
participantIds.forEach((element) {uniqueId += element;}); // TODO ensure its only one thats added s
|
||||||
|
|
||||||
|
|
||||||
|
// send the other persons pubkey as identifier
|
||||||
if( eventData.pubkey == userPublicKey) {
|
if( eventData.pubkey == userPublicKey) {
|
||||||
return uniqueId;
|
return uniqueId;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user