Skip to content

Commit

Permalink
changed display filters and saving logic
Browse files Browse the repository at this point in the history
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
  • Loading branch information
vishalxl committed Dec 28, 2022
1 parent 9085c8a commit dd9e9a3
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 74 deletions.
26 changes: 14 additions & 12 deletions lib/console_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:");
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -1341,18 +1343,18 @@ 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);
break;
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.");
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
28 changes: 17 additions & 11 deletions lib/event_ds.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 = "";
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
102 changes: 74 additions & 28 deletions lib/tree_ds.dart
Original file line number Diff line number Diff line change
Expand Up @@ -559,32 +559,68 @@ 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)) {
List<List<String>>? reactions = gReactions[event.eventData.id];
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;
}
}
}
}

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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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";
Expand Down
23 changes: 5 additions & 18 deletions lib/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand All @@ -28,6 +32,7 @@ Set<String> getFollows(String pubkey) {
return followPubkeys;
}


Set<String> getUserChannels(Set<Event> userEvents, String userPublicKey) {
Set<String> userChannels = {};

Expand Down Expand Up @@ -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;
}
13 changes: 9 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit dd9e9a3

Please sign in to comment.