changed display filters and saving logic

displyed global feed.

and in incoming notifications, only showed notifications for follows.

In writing events, only writing follow's events. and the ones they interact with.

now all follows have a tick; no tick for defaults
This commit is contained in:
Vishal 2022-12-29 02:20:58 +05:30
parent 9085c8a64a
commit dd9e9a3c02
6 changed files with 120 additions and 74 deletions

View File

@ -30,6 +30,7 @@ Future<void> processAnyIncomingEvents(Store node, [bool printNotifications = tru
List<int> numPrinted1 = [0,0,0];
if( printNotifications) {
// print all the new trees, the ones that we want to print
numPrinted1 = node.printTreeNotifications(newEventIds);
// need to clear because only top 20 events in each thread are printed or cleared with above
@ -303,7 +304,7 @@ void printProfile(Store node, String profilePubkey) {
node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), onlyUserPostAndLike);
// if contact list was found, get user's feed, and keep the contact list for later use
String authorName = getAuthorName(profilePubkey, addTickForWellKnown: false );
String authorName = getAuthorName(profilePubkey);
String pronoun = "";
if( profilePubkey == userPublicKey) {
printUnderlined("\nYour profile - $authorName:");
@ -1280,9 +1281,9 @@ Future<void> socialMenuUi(Store node) async {
// the main menu
int option = showMenu([
'All Posts', // 1
'Your Feed', // 1
'Post/Reply/Like', // 2
'Your notifications',// 3
'Replies/Likes to you',// 3
'Your Posts', // 4
'Your Replies/Likes',//5
'Follows\' Posts/Replies/Likes', // 6
@ -1295,7 +1296,8 @@ Future<void> socialMenuUi(Store node) async {
switch(option) {
case 1:
node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), selectorTrees_all);
bool selectorTrees_followActionsNoNotifications (Tree t) => t.treeSelectorUserPostAndLike(getFollows( userPublicKey), enableNotifications: false);
node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), selectorTrees_followActionsNoNotifications);
await processAnyIncomingEvents(node, true);
break;
@ -1341,9 +1343,9 @@ Future<void> socialMenuUi(Store node) async {
int notificationHours = gHoursDefaultPrint>24? gHoursDefaultPrint: 24; // minimum 24
List<int> numPrinted = node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:notificationHours)), selectorTrees_userNotifications);
if( numPrinted[2] > 0) {
print("Showed ${numPrinted[2]} notifications.\n");
print("Showed ${numPrinted[2]} replies/likes that were made to your posts.\n");
} else {
print("No notifications.");
print("No replies or likes.");
}
await processAnyIncomingEvents(node, true);
@ -1351,8 +1353,8 @@ Future<void> socialMenuUi(Store node) async {
case 4:
clearScreen();
List<int> numPrinted = node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), selectorTrees_selfPosts);
if( numPrinted[2] > 0) {
print("Showed ${numPrinted[2]} posts made by you in last $gHoursDefaultPrint hours.\n");
if( numPrinted[0] > 0) {
print("Showed ${numPrinted[0]} posts made by you in last $gHoursDefaultPrint hours.\n");
} else {
print("No posts made by you in last $gHoursDefaultPrint hours.");
}
@ -1373,8 +1375,8 @@ Future<void> socialMenuUi(Store node) async {
case 6:
clearScreen();
bool selectorTrees_followActions (Tree t) => t.treeSelectorUserPostAndLike(getFollows( userPublicKey));
List<int> numPrinted = node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), selectorTrees_followActions);
bool selectorTrees_followActionsWithNotifications (Tree t) => t.treeSelectorUserPostAndLike(getFollows( userPublicKey), enableNotifications: true);
List<int> numPrinted = node.printStoreTrees(0, DateTime.now().subtract(Duration(hours:gHoursDefaultPrint)), selectorTrees_followActionsWithNotifications);
if( numPrinted[0] > 0) {
print("Showed ${numPrinted[0]} threads where your follows participated.\n");
} else {
@ -1580,8 +1582,8 @@ Future<void> mainMenuUi(Store node) async {
firstTime = false;
// the main menu
int option = showMenu(['Home Page', // 1
'Social Network', // 2
int option = showMenu(['Global Feed', // 1
'Social Network', // 2
'Public Channels', // 3
'Encrypted Channels',// 4
'Private Messages', // 5

View File

@ -4,6 +4,7 @@ import 'dart:math';
import 'package:bip340/bip340.dart';
import 'package:intl/intl.dart';
import 'package:nostr_console/tree_ds.dart';
import 'package:nostr_console/user.dart';
import 'package:nostr_console/utils.dart';
import 'package:translator/translator.dart';
import 'package:crypto/crypto.dart';
@ -1246,7 +1247,12 @@ String getNip05Name( String pubkey) {
}
// returns name by looking up global list gKindONames, which is populated by kind 0 events
String getAuthorName(String pubkey, {bool addTickForWellKnown = true, int maxDisplayLen = gMaxInteger, int pubkeyLenShown = 5}) {
String getAuthorName(String pubkey, {int maxDisplayLen = gMaxInteger, int pubkeyLenShown = 5}) {
if( gFollowList.length == 0) {
gFollowList = getFollows(userPublicKey);
}
bool isFollow = gFollowList.contains(pubkey) && (pubkey != userPublicKey);
String maxLen(String pubkey) => pubkey.length > pubkeyLenShown? pubkey.substring(0,pubkeyLenShown) : pubkey.substring(0, pubkey.length);
String name = "";
@ -1256,19 +1262,19 @@ String getAuthorName(String pubkey, {bool addTickForWellKnown = true, int maxDis
name = (gKindONames[pubkey]?.name)??maxLen(pubkey);
}
if( addTickForWellKnown) {
// first remove the check mark if its in any name
// then add valid check mark in default follows
if( isFollow) {
if( name.length >= maxDisplayLen ) {
name = name.substring(0, maxDisplayLen-1) + gValidCheckMark;
} else {
name = name + gValidCheckMark;
}
} else {
// make this tick a specil character
name = name.replaceAll(gValidCheckMark, "");
// then add valid check mark in default follows
if( gDefaultFollows.contains(pubkey)) {
if( name.length >= maxDisplayLen ) {
name = name.substring(0, maxDisplayLen-1) + gValidCheckMark;
} else {
name = name + gValidCheckMark;
}
}
}
return name;
}

View File

@ -3,7 +3,7 @@ import 'package:logging/logging.dart';
// name of executable
const String exename = "nostr_console";
const String version = "0.3.1-beta-b";
const String version = "0.3.2-beta";
int gDebug = 0;
int gSpecificDebug = 0;

View File

@ -559,8 +559,39 @@ class Tree {
return false;
}
// returns true if the tree or its children has a post or like by user; and notification flags are set for such events
bool treeSelectorUserPostAndLike(Set<String> pubkeys) {
// returns true if the tree has a reply by any of the pubkeys sent
// only used by writefile
bool treeSelectorUserPosted(Set<String> pubkeys, [bool checkChildrenToo = false]) {
if( pubkeys.contains(event.eventData.pubkey)) {
return true;
}
for( int i = 0; i < children.length; i++ ) {
if( children[i].treeSelectorUserPosted(pubkeys)) {
return true;
}
}
return false;
}
// returns true if the tree has a reply by any of the pubkeys sent
// only used by writefile
bool treeSelectorUserReplies(Set<String> pubkeys) {
for( int i = 0; i < children.length; i++ ) {
if( children[i].treeSelectorUserPosted(pubkeys)) {
return true;
}
}
return false;
}
// returns true if the tree (or its children, depending on flag) has a post or like by user; and notification flags are set for such events
bool treeSelectorUserPostAndLike(Set<String> pubkeys, { bool enableNotifications = true, bool checkChildrenToo = true}) {
bool hasReacted = false;
if( gReactions.containsKey(event.eventData.id)) {
@ -568,7 +599,8 @@ class Tree {
if( reactions != null) {
for( int i = 0; i < reactions.length; i++) {
if( pubkeys.contains(reactions[i][0]) ) {
event.eventData.newLikes.add(reactions[i][0]);
if( enableNotifications)
event.eventData.newLikes.add(reactions[i][0]);
hasReacted = true;
}
}
@ -576,15 +608,19 @@ class Tree {
}
bool childMatches = false;
for( int i = 0; i < children.length; i++ ) {
if( children[i].treeSelectorUserPostAndLike(pubkeys)) {
childMatches = true;
if( checkChildrenToo ) {
for( int i = 0; i < children.length; i++ ) {
if( children[i].treeSelectorUserPostAndLike(pubkeys)) {
childMatches = true;
}
}
}
// if event is by user(s)
if( pubkeys.contains(event.eventData.pubkey)) {
event.eventData.isNotification = true;
if( enableNotifications)
event.eventData.isNotification = true;
return true;
}
if( hasReacted || childMatches) {
@ -1605,13 +1641,19 @@ class Store {
Store.reCalculateMarkerStr();
// update this list, because it is internally used by printEvent
gFollowList = getFollows(userPublicKey);
List<int> ret = [0,0,0];
topNotificationTree.forEach( (t) {
List<int> temp = Store.printTopPost(t, 0, DateTime(0));
ret[0] += temp[0];
ret[1] += temp[1];
ret[2] += temp[2];
print("\n");
topNotificationTree.forEach( (t) {
bool selectorTrees_followActionsWithNotifications (Tree t) => t.treeSelectorUserPostAndLike(getFollows( userPublicKey), enableNotifications: true);
if( selectorTrees_followActionsWithNotifications(t)) {
List<int> temp = Store.printTopPost(t, 0, DateTime(0));
ret[0] += temp[0];
ret[1] += temp[1];
ret[2] += temp[2];
print("\n");
}
});
return ret;
@ -1642,6 +1684,9 @@ class Store {
*/
List<int> printStoreTrees(int depth, DateTime newerThan, fTreeSelector treeSelector, [int maxToPrint = gMaxEventsInThreadPrinted]) {
// update this list, because it is internally used by printEvent
gFollowList = getFollows(userPublicKey);
topPosts.sort(sortTreeNewestReply); // sorting done only for top most threads. Lower threads aren't sorted so save cpu etc TODO improve top sorting
// https://gist.github.com/dsample/79a97f38bf956f37a0f99ace9df367b9
@ -2046,18 +2091,26 @@ class Store {
return room;
}
// TODO to be finished
// threads where the user and follows have involved themselves are returnes as true ( relevant)
bool isRelevant(Tree tree) {
//Set<String> contacts = getContactList(userPublicKey);
//contacts = contacts.union(gDefaultFollows);
if( tree.treeSelectorUserPostAndLike(gFollowList)
|| tree.treeSelectorUserPostAndLike({userPublicKey})
|| tree.treeSelectorUserReplies(gFollowList)) {
return true;
}
return true;
return false;
}
// Write the tree's events to file as one event's json per line
Future<void> writeEventsToFile(String filename) async {
// this variable will be used later; update it if needed
if( gFollowList.length == 0) {
gFollowList = getFollows(userPublicKey);
}
if( gDebug > 0) print("opening $filename to write to.");
try {
final File file = File(filename);
@ -2075,7 +2128,9 @@ class Store {
int linesWritten = 0;
for( var tree in allChildEventsMap.values) {
if( tree.event.eventData.isDeleted) { // dont write those deleted
if( tree.event.eventData.isDeleted // dont write those deleted
|| gDummyAccountPubkey == tree.event.eventData.pubkey // dont write dummy events
|| tree.event.originalJson.length < 10) {
continue;
}
@ -2085,18 +2140,9 @@ class Store {
}
}
if( gDummyAccountPubkey == tree.event.eventData.pubkey) {
continue; // dont write dummy events
}
if( tree.event.originalJson.length < 10) {
continue;
}
if( !isRelevant(tree)) {
continue;
}
String temp = tree.event.originalJson.trim();
String line = "${temp}\n";

View File

@ -3,6 +3,10 @@ import 'package:nostr_console/event_ds.dart';
import 'package:nostr_console/settings.dart';
import 'package:nostr_console/utils.dart';
// is set intermittently by functions. and used as required. Should be kept in sync as the kind 3 for user are received.
Set<String> gFollowList = {};
// From the list of events provided, lookup the lastst contact information for the given user/pubkey
Event? getContactEvent(String pubkey) {
@ -28,6 +32,7 @@ Set<String> getFollows(String pubkey) {
return followPubkeys;
}
Set<String> getUserChannels(Set<Event> userEvents, String userPublicKey) {
Set<String> userChannels = {};
@ -94,21 +99,3 @@ Set<String> getOnlyUserEvents(Set<Event> initialEvents, String userPubkey) {
return userEvents;
}
Set<String> getContactList(String pubkey) {
Set<String> contacts = {};
if( pubkey != "") {
// get the latest kind 3 event for the user, which has the 'follows' list
Event? contactEvent = getContactEvent(userPublicKey);
// if contact list was found, get user's feed; also get some default contacts
if (contactEvent != null ) {
contactEvent.eventData.contactList.forEach((contact) {
contacts.add(contact.contactPubkey);
});
} else {
}
}
return contacts;
}

View File

@ -1,12 +1,17 @@
name: nostr_console
description: A multi-platform nostr client built for terminal/console
version: 0.3.1-beta-b
version: 0.3.2-beta
homepage: https://github.com/vishalxl/nostr_console
# 0.3.2
# added build for ubuntu arm 64, and mac arm 64
# matrix change , removed old build entries in dart.yml files
# one off build with num channel messages = 40
# fixed or improved mention expansion
# displyed global feed. which has all latest in last 2 hours
# in incoming notifications, only showed notifications for follows.
# In writing events, only writing follow's events. and the ones they interact with.
# now friends have a tick; no tick for defaults
# fixed likes colors issue for notification likes
# 0.3.1
# added nostr.ch as another default relay to sync with anigma