-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
393 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import '../../domain_layer/entities/nostr_list.dart'; | ||
import 'package:ndk/entities.dart' as ndk_entities; | ||
|
||
class NostrListModel extends NostrList { | ||
NostrListModel({ | ||
required super.pubKey, | ||
required super.kind, | ||
required super.createdAt, | ||
required super.elements, | ||
}); | ||
|
||
// Convert from Nip51List (NDK) to NostrListModel | ||
static NostrListModel fromNDK(ndk_entities.Nip51List ndkList) { | ||
return NostrListModel( | ||
pubKey: ndkList.pubKey, | ||
kind: ndkList.kind, | ||
createdAt: ndkList.createdAt, | ||
elements: ndkList.elements | ||
.map((e) => NostrListElementModel.fromNDK(e)) | ||
.toList(), | ||
)..id = ndkList.id; | ||
} | ||
|
||
// Convert from NostrListModel to Nip51List (NDK) | ||
ndk_entities.Nip51List toNDK() { | ||
return ndk_entities.Nip51List( | ||
pubKey: pubKey, | ||
kind: kind, | ||
createdAt: createdAt, | ||
elements: elements | ||
.map((e) => NostrListElementModel( | ||
tag: e.tag, | ||
value: e.value, | ||
private: e.private, | ||
).toNDK()) | ||
.toList(), | ||
)..id = id; | ||
} | ||
} | ||
|
||
class NostrSetModel extends NostrSet { | ||
//String name; | ||
//String? title; | ||
String? description; | ||
String? image; | ||
|
||
NostrSetModel({ | ||
required super.pubKey, | ||
required super.name, | ||
required super.createdAt, | ||
required super.elements, | ||
super.kind = NostrList.FOLLOW_SET, | ||
super.title, | ||
this.description, | ||
this.image, | ||
}); | ||
|
||
// Convert from Nip51Set (NDK) to NostrSetModel | ||
static NostrSetModel fromNDK(ndk_entities.Nip51Set ndkSet) { | ||
return NostrSetModel( | ||
pubKey: ndkSet.pubKey, | ||
name: ndkSet.name, | ||
createdAt: ndkSet.createdAt, | ||
elements: | ||
ndkSet.elements.map((e) => NostrListElementModel.fromNDK(e)).toList(), | ||
title: ndkSet.title, | ||
description: ndkSet.description, | ||
image: ndkSet.image, | ||
)..id = ndkSet.id; | ||
} | ||
|
||
// Convert from NostrSetModel to Nip51Set (NDK) | ||
@override | ||
ndk_entities.Nip51Set toNDK() { | ||
return ndk_entities.Nip51Set( | ||
pubKey: pubKey, | ||
name: name, | ||
createdAt: createdAt, | ||
elements: elements | ||
.map((e) => NostrListElementModel( | ||
tag: e.tag, | ||
value: e.value, | ||
private: e.private, | ||
).toNDK()) | ||
.toList(), | ||
title: title, | ||
) | ||
..id = id | ||
..description = description | ||
..image = image; | ||
} | ||
} | ||
|
||
class NostrListElementModel extends NostrListElement { | ||
NostrListElementModel({ | ||
required super.tag, | ||
required super.value, | ||
required super.private, | ||
}); | ||
|
||
// Convert from Nip51ListElement (NDK) to Nip51ListElementModel | ||
static NostrListElementModel fromNDK( | ||
ndk_entities.Nip51ListElement ndkElement) { | ||
return NostrListElementModel( | ||
tag: ndkElement.tag, | ||
value: ndkElement.value, | ||
private: ndkElement.private, | ||
); | ||
} | ||
|
||
// Convert from Nip51ListElementModel to Nip51ListElement (NDK) | ||
ndk_entities.Nip51ListElement toNDK() { | ||
return ndk_entities.Nip51ListElement( | ||
tag: tag, | ||
value: value, | ||
private: private, | ||
); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
lib/data_layer/repositories/nostr_list_repository_impl.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import 'dart:developer'; | ||
|
||
import 'package:camelus/domain_layer/entities/nostr_list.dart'; | ||
import 'package:ndk/entities.dart' as ndk_entities; | ||
import 'package:ndk/ndk.dart' as ndk; | ||
import 'package:rxdart/rxdart.dart'; | ||
|
||
import '../../domain_layer/entities/nostr_note.dart'; | ||
import '../../domain_layer/repositories/nostr_list_repository.dart'; | ||
import '../data_sources/dart_ndk_source.dart'; | ||
import '../models/nostr_lists_model.dart'; | ||
import '../models/nostr_note_model.dart'; | ||
|
||
class NostrListRepositoryImpl implements NostrListRepository { | ||
final DartNdkSource dartNdkSource; | ||
final ndk.EventVerifier eventVerifier; | ||
|
||
NostrListRepositoryImpl( | ||
{required this.dartNdkSource, required this.eventVerifier, r}); | ||
|
||
@override | ||
Stream<NostrNote> getAllNotes() { | ||
ndk.Filter filter = ndk.Filter( | ||
authors: [], | ||
kinds: [ndk_entities.Nip01Event.TEXT_NODE_KIND], | ||
); | ||
|
||
final response = dartNdkSource.dartNdk.requests | ||
.query(filters: [filter], name: 'getAllNotes-'); | ||
|
||
return response.stream.map( | ||
(event) => NostrNoteModel.fromNDKEvent(event), | ||
); | ||
} | ||
|
||
@override | ||
Future<NostrSet?> getNostrFollowSet({ | ||
required String pubKey, | ||
required String name, | ||
}) async { | ||
final ndkSet = | ||
await dartNdkSource.dartNdk.lists.getSinglePublicNip51RelaySet( | ||
name: name, | ||
publicKey: pubKey, | ||
); | ||
|
||
if (ndkSet == null) { | ||
return null; | ||
} | ||
final listSet = NostrSetModel.fromNDK(ndkSet); | ||
return listSet; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
class NostrList { | ||
static const int MUTE = 10000; | ||
static const int PIN = 10001; | ||
static const int BOOKMARKS = 10003; | ||
static const int COMMUNITIES = 10004; | ||
static const int PUBLIC_CHATS = 10005; | ||
static const int BLOCKED_RELAYS = 10006; | ||
static const int SEARCH_RELAYS = 10007; | ||
static const int INTERESTS = 10015; | ||
static const int EMOJIS = 10030; | ||
|
||
static const int FOLLOW_SET = 30000; | ||
static const int RELAY_SET = 30002; | ||
static const int BOOKMARKS_SET = 30003; | ||
static const int CURATION_SET = 30004; | ||
static const int INTERESTS_SET = 30015; | ||
static const int EMOJIS_SET = 30030; | ||
|
||
static const String RELAY = "relay"; | ||
static const String PUB_KEY = "p"; | ||
static const String HASHTAG = "t"; | ||
static const String WORD = "word"; | ||
static const String THREAD = "e"; | ||
static const String RESOURCE = "r"; | ||
static const String EMOJI = "emoji"; | ||
static const String A = "a"; | ||
|
||
static const List<int> POSSIBLE_KINDS = [ | ||
MUTE, | ||
PIN, | ||
BOOKMARKS, | ||
COMMUNITIES, | ||
PUBLIC_CHATS, | ||
BLOCKED_RELAYS, | ||
SEARCH_RELAYS, | ||
INTERESTS, | ||
EMOJIS, | ||
FOLLOW_SET, | ||
RELAY_SET, | ||
BOOKMARKS_SET, | ||
CURATION_SET, | ||
INTERESTS_SET, | ||
EMOJIS_SET | ||
]; | ||
|
||
static const List<String> POSSIBLE_TAGS = [ | ||
RELAY, | ||
PUB_KEY, | ||
HASHTAG, | ||
WORD, | ||
THREAD, | ||
RESOURCE, | ||
EMOJI, | ||
A | ||
]; | ||
|
||
late String id; | ||
late String pubKey; | ||
late int kind; | ||
|
||
List<NostrListElement> elements = []; | ||
|
||
List<NostrListElement> byTag(String tag) => | ||
elements.where((element) => element.tag == tag).toList(); | ||
|
||
List<NostrListElement> get relays => byTag(RELAY); | ||
List<NostrListElement> get pubKeys => byTag(PUB_KEY); | ||
List<NostrListElement> get hashtags => byTag(HASHTAG); | ||
List<NostrListElement> get words => byTag(WORD); | ||
List<NostrListElement> get threads => byTag(THREAD); | ||
|
||
List<String> get publicRelays => | ||
relays.where((element) => !element.private).map((e) => e.value).toList(); | ||
List<String> get privateRelays => | ||
relays.where((element) => !element.private).map((e) => e.value).toList(); | ||
|
||
set privateRelays(List<String> list) { | ||
elements.removeWhere((element) => element.tag == RELAY && element.private); | ||
elements.addAll(list | ||
.map((url) => NostrListElement(tag: RELAY, value: url, private: true))); | ||
} | ||
|
||
set publicRelays(List<String> list) { | ||
elements.removeWhere((element) => element.tag == RELAY && !element.private); | ||
elements.addAll(list.map( | ||
(url) => NostrListElement(tag: RELAY, value: url, private: false))); | ||
} | ||
|
||
late int createdAt; | ||
|
||
@override | ||
// coverage:ignore-start | ||
String toString() { | ||
return 'Nip51List { $kind}'; | ||
} | ||
// coverage:ignore-end | ||
|
||
String get displayTitle { | ||
if (kind == NostrList.SEARCH_RELAYS) { | ||
return "Search"; | ||
} | ||
if (kind == NostrList.BLOCKED_RELAYS) { | ||
return "Blocked"; | ||
} | ||
if (kind == NostrList.MUTE) { | ||
return "Mute"; | ||
} | ||
return "kind $kind"; | ||
} | ||
|
||
List<String> get allRelays => relays.map((e) => e.value).toList(); | ||
|
||
NostrList({ | ||
required this.pubKey, | ||
required this.kind, | ||
required this.createdAt, | ||
required this.elements, | ||
}); | ||
|
||
void parseTags(List tags, {required bool private}) { | ||
for (var tag in tags) { | ||
if (tag is! List<dynamic>) continue; | ||
final length = tag.length; | ||
if (length <= 1) continue; | ||
final tagName = tag[0]; | ||
final value = tag[1]; | ||
if (POSSIBLE_TAGS.contains(tagName)) { | ||
elements.add( | ||
NostrListElement(tag: tagName, value: value, private: private)); | ||
} | ||
} | ||
} | ||
|
||
void addRelay(String relayUrl, bool private) { | ||
elements | ||
.add(NostrListElement(tag: RELAY, value: relayUrl, private: private)); | ||
} | ||
|
||
void addElement(String tag, String value, bool private) { | ||
elements.add(NostrListElement(tag: tag, value: value, private: private)); | ||
} | ||
|
||
void removeRelay(String relayUrl) { | ||
elements.removeWhere( | ||
(element) => element.tag == RELAY && element.value == relayUrl); | ||
} | ||
|
||
void removeElement(String tag, String value) { | ||
elements | ||
.removeWhere((element) => element.tag == tag && element.value == value); | ||
} | ||
} | ||
|
||
class NostrListElement { | ||
bool private; | ||
String tag; | ||
String value; | ||
|
||
NostrListElement({ | ||
required this.tag, | ||
required this.value, | ||
required this.private, | ||
}); | ||
} | ||
|
||
class NostrSet extends NostrList { | ||
late String name; | ||
String? title; | ||
String? description; | ||
String? image; | ||
|
||
@override | ||
String toString() { | ||
return 'Nip51Set { $name}'; | ||
} | ||
|
||
/// Create a new Nip51Set | ||
/// default kind is Nip51List.FOLLOW_SET | ||
NostrSet({ | ||
required super.pubKey, | ||
required this.name, | ||
required super.createdAt, | ||
required super.elements, | ||
this.title, | ||
super.kind = NostrList.FOLLOW_SET, | ||
}); | ||
|
||
void parseSetTags(List tags) { | ||
for (var tag in tags) { | ||
if (tag is! List<dynamic>) continue; | ||
final length = tag.length; | ||
if (length <= 1) continue; | ||
final tagName = tag[0]; | ||
final value = tag[1]; | ||
if (tagName == "d") { | ||
name = value; | ||
continue; | ||
} | ||
if (tagName == "title") { | ||
title = value; | ||
continue; | ||
} | ||
if (tagName == "description") { | ||
description = value; | ||
continue; | ||
} | ||
if (tagName == "image") { | ||
image = value; | ||
continue; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import '../entities/nostr_list.dart'; | ||
|
||
abstract class NostrListRepository { | ||
Future<NostrSet?> getNostrFollowSet({ | ||
required String pubKey, | ||
required String name, | ||
}); | ||
} |