From f7b78aa17117172dd378b46e3da7967b4981544d Mon Sep 17 00:00:00 2001 From: vishalxl <> Date: Thu, 18 Aug 2022 18:34:37 +0530 Subject: [PATCH] added options align and width, which control display. now text can be left or center aligned. default is center. fixed issue with dashes when re-aligning tree --- bin/nostr_console.dart | 41 ++++++++++++++++++++++++++++++++++++---- lib/event_ds.dart | 43 ++++++++++++++++++++++++++++++------------ lib/relays.dart | 9 +++------ lib/tree_ds.dart | 14 +++++++++----- 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/bin/nostr_console.dart b/bin/nostr_console.dart index c46df28..1e143f6 100644 --- a/bin/nostr_console.dart +++ b/bin/nostr_console.dart @@ -23,6 +23,8 @@ const String prikeyArg = "prikey"; const String lastdaysArg = "days"; const String relayArg = "relay"; const String helpArg = "help"; +const String alignArg = "align"; // can be "left" +const String widthArg = "width"; // By default the threads that were started in last one day are shown // this can be changed with 'days' command line argument @@ -38,9 +40,13 @@ usage: $exename [OPTIONS] --prikey The hex private key of user whose events and feed are shown. Also used to sign events sent. Default is a hard-coded well known private key. Same as -p --relay The relay url that is used as main relay. Default is $defaultServerUrl . Same as -r - --days The latest number of days for which events are shown. Default is 1. Same as -d + --days The latest number of days for which events are shown. Default is 1. Same as -d --request This request is sent verbatim to the default relay. It can be used to recieve all events from a relay. If not provided, then events for default or given user are shown. Same as -q + --align When "left" is given as option to this argument, then the text is aligned to left. By default + the posts or text is aligned to the center of the terminal. Same as -a + --width This specifies how wide you want the text to be, in number of columns. Default is 80. + Cant be less than $gMinValidScreenWidth. Same as -c --help Print this usage message and exit. Same as -h """; @@ -116,7 +122,11 @@ Future terminalMenuUi(Tree node, var contactList) async { print('You picked: $option'); switch(option) { case 1: - //print("in display events option"); + // align the text again in case the window size has been changed + if( gAlignment == "center") { + gNumLeftMarginSpaces = (stdout.terminalColumns - 80 )~/2; + } + node.printTree(0, true, DateTime.now().subtract(Duration(days:numLastDays))); break; @@ -161,7 +171,8 @@ Future main(List arguments) async { final parser = ArgParser()..addOption(requestArg, abbr: 'q') ..addOption(prikeyArg, abbr:"p") ..addOption(lastdaysArg, abbr:"d") ..addOption(relayArg, abbr:"r") - ..addFlag(helpArg, abbr:"h", defaultsTo: false); + ..addFlag(helpArg, abbr:"h", defaultsTo: false)..addOption(alignArg, abbr:"a") + ..addOption(widthArg, abbr:"c"); try { ArgResults argResults = parser.parse(arguments); @@ -179,12 +190,34 @@ Future main(List arguments) async { userPrivateKey = argResults[prikeyArg]; userPublicKey = getPublicKey(userPrivateKey); } - if( argResults[lastdaysArg] != null) { + if( argResults[lastdaysArg] != null) { numLastDays = int.parse(argResults[lastdaysArg]); print("Going to show posts for last $numLastDays days"); } + if( argResults[widthArg] != null) { + int tempScreenWidth = int.parse(argResults[widthArg]); + if( tempScreenWidth < gMinValidScreenWidth ) { + print("Screen-width cannot be less than $gMinValidScreenWidth. Going to use the defalt value of $screenWidth"); + } else { + print("Going to use $screenWidth columns for text on screen."); + screenWidth = tempScreenWidth; + } + } + + // can be computed only after screenWidth has been found + gNumLeftMarginSpaces = (stdout.terminalColumns - 80 )~/2; + + // undo above if left option is given + if( argResults[alignArg] != null) { + if( argResults[alignArg] == "left" ) { + print("Going to align to left."); + gAlignment = "left"; + gNumLeftMarginSpaces = 0; + } + } + if( argResults[requestArg] != null) { stdout.write("Got argument request ${argResults[requestArg]}"); sendRequest("wss://nostr-pub.wellorder.net", argResults[requestArg]); diff --git a/lib/event_ds.dart b/lib/event_ds.dart index 2b39f56..60ec374 100644 --- a/lib/event_ds.dart +++ b/lib/event_ds.dart @@ -2,15 +2,21 @@ import 'dart:io'; import 'dart:convert'; import 'package:intl/intl.dart'; -const int screenWidth = 120; +const int gMinValidScreenWidth = 60; +const int defaultScreenWidth = 80; +int screenWidth = defaultScreenWidth; const int spacesPerDepth = 8; +int gNumLeftMarginSpaces = 0; // this number is modified in main +String gAlignment = "center"; // is modified in main if --align argument is given -const int maxDepthAllowed = 7; -const int leftShiftThreadsBy = 3; +const int maxDepthAllowed = 4; +const int leftShiftThreadsBy = 2; // 33 yellow, 31 red, 34 blue, 35 magenta. Add 60 for bright versions. const String commentColor = "\x1B[32m"; // green const String notificationColor = "\x1b[36m"; // cyan +const String warningColor = "\x1B[31m"; // red +const String colorEndMarker = "\x1B[0m"; //String defaultServerUrl = 'wss://relay.damus.io'; String defaultServerUrl = 'wss://nostr-relay.untethr.me'; @@ -26,19 +32,32 @@ List gBots = [ "3b57518d02e6acfd5eb7198530b2e351e5a52278fb2499d14b66db2 int gDebug = 0; void printDepth(int d) { - for( int i = 0; i < spacesPerDepth * d ; i++) { + for( int i = 0; i < spacesPerDepth * d + gNumLeftMarginSpaces; i++) { stdout.write(" "); } - } +} + +String getNumSpaces(int num) { + String s = ""; + for( int i = 0; i < num; i++) { + s += " "; + } + return s; +} + +String getNumDashes(int num) { + String s = ""; + for( int i = 0; i < num; i++) { + s += "-"; + } + return s; +} + String rightShiftContent(String s, int numSpaces) { String newString = ""; int newlineCounter = 0; - String spacesString = ""; - - for( int i = 0; i < numSpaces ; i++) { - spacesString += " "; - } + String spacesString = getNumSpaces(numSpaces + gNumLeftMarginSpaces); for(int i = 0; i < s.length; i++) { if( s[i] == '\n') { @@ -182,7 +201,7 @@ class EventData { void printEventData(int depth) { int n = 3; String maxN(String v) => v.length > n? v.substring(0,n) : v.substring(0, v.length); - void printGreen(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s\x1B[0m"):stdout.write(s); + void printGreen(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$colorEndMarker"):stdout.write(s); DateTime dTime = DateTime.fromMillisecondsSinceEpoch(createdAt *1000); @@ -202,7 +221,7 @@ class EventData { stdout.write("+-------+\n"); 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"); printDepth(depth); stdout.write("|Message: "); if( isNotification) { diff --git a/lib/relays.dart b/lib/relays.dart index ba46569..06a8ec4 100644 --- a/lib/relays.dart +++ b/lib/relays.dart @@ -56,7 +56,7 @@ class Relays { } } - // following is too restrictive. TODO improve it + // following is too restrictive casuse changed sinceWhen is not considered. TODO improve it for(int i = 0; i < users.length; i++) { if( users[i] == publicKey) { return; @@ -118,8 +118,8 @@ class Relays { print( 'exception in fromJson for event'); } }, - onError: (e) { print("in onError"); print(e); }, - onDone: () { print('in onDone'); } + onError: (e) { print("\n${warningColor}Warning: In SendRequest creating connection onError. Kindly check your internet connection or change the relay by command line --relay="); print(colorEndMarker); }, + onDone: () { print('Info: In onDone'); } ); } on WebSocketException { print('WebSocketException exception'); @@ -172,8 +172,6 @@ class Relays { relays.forEach((key, value) { print("for relay: $key"); print("$value\n"); - - String? reason = value.closeReason; print( reason??"reason not found"); }); @@ -214,7 +212,6 @@ void getMultiUserEvents(serverUrl, publicKeys, numUserEvents) { relays.getMultiUserEvents(serverUrl, publicKeys, numUserEvents); } - void sendRequest(serverUrl, request) { relays.sendRequest(serverUrl, request); } diff --git a/lib/tree_ds.dart b/lib/tree_ds.dart index 4f28624..74df90b 100644 --- a/lib/tree_ds.dart +++ b/lib/tree_ds.dart @@ -34,8 +34,8 @@ class Tree { mAllEvents[parentId]?.addChildNode(value); // in this if condition this will get called } else { // 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?) - Tree dummyTopNode = Tree(Event("","",EventData("Unk","Non", value.e.eventData.createdAt , 0, "Unknown/Dummy Event", [], [], [], [[]]), [""], "[json]"), [], {}, []); + // 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("","",EventData("Unk" ,"Non", value.e.eventData.createdAt , 0, "Unknown parent event", [], [], [], [[]]), [""], "[json]"), [], {}, []); dummyTopNode.addChildNode(value); tempWithoutParent.add(value.e.eventData.id); @@ -142,8 +142,7 @@ class Tree { if( depth > maxDepthAllowed) { depth = maxDepthAllowed - leftShiftThreadsBy; printDepth(depth+1); - stdout.write("+-------------------------------+\n"); - + stdout.write("+${getNumDashes((leftShiftThreadsBy + 1) * 8 - 1)}+\n"); } children[i].printTree(depth+1, false, newerThan); } @@ -225,10 +224,15 @@ class Tree { } } + if( latestEventId.isEmpty) { + // search for it in the dummy event id's + + } + //print("latestEventId = $latestEventId"); if( latestEventId.isNotEmpty) { strTags = '["e","$latestEventId"]'; - } + } if( strTags != "") {