Skip to content

Commit

Permalink
Merge pull request #16 from RydalWater/post-mvp-fixes-and-enhancements
Browse files Browse the repository at this point in the history
Contacts updates
  • Loading branch information
RydalWater authored Oct 29, 2024
2 parents ced45c7 + aaf8876 commit 2b0c43c
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 14 deletions.
18 changes: 13 additions & 5 deletions openlibrarian_root/almanac/templates/almanac/user_friends.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@

<form method="post">
{% csrf_token %}
<div style="height: 55vh; overflow-y: auto;">
<div class="accordion" id="socialAccordion">
<div style="height: 55vh; overflow-y: auto;">
<div class="input-group input-group-sm">
<input class="form-control" type="text", name="follow_user", placeholder="Enter a Users Public Key or NIP05 Address" aria-describedby="upload"></input>
<button class="btn btn-outline-secondary" type="submit" id="submit"><i class="fa-solid fa-plus"></i></button>
</div>
<div class="accordion mt-2" id="socialAccordion">
<div class="accordion-item">
<h2 class="accordion-header" id="friends">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFriends" aria-expanded="true" aria-controls="collapseFriends">
Expand All @@ -40,7 +44,7 @@ <h2 class="accordion-header" id="friends">
<div class="col-md-4">
<!-- <button id="removeButton" class="btn btn-sm btn-danger" name="remove", value="{{ values.npub }}"><i class="fa-solid fa-trash"></i></button> -->
<button id="copyButton" class="btn btn-sm btn-secondary" name="copy", value="{{ values.npub }}"><i class="fa-solid fa-copy"></i></button>
<a id="profileButton" class="btn btn-sm btn-primary" name="profile", href="{% url 'library_card:library_card' values.npub %}"><i class="fa-solid fa-id-card"></i></a>
<a class="btn btn-sm btn-primary" name="profile", href="{% url 'library_card:library_card' values.npub %}"><i class="fa-solid fa-id-card"></i></a>
</div>
</li>
</ul>
Expand Down Expand Up @@ -93,7 +97,6 @@ <h2 class="accordion-header" id="foes">
<a id="nsec" href="{% url 'almanac:settings' %}" class="btn btn-sm btn-secondary w-50"><i class="fa-solid fa-arrow-left"></i> Back</a>
{% if session.nsec %}
<button id="submit" class="btn btn-sm btn-primary w-50" type="submit", name="refresh", value="Refresh"><i class="fa-solid fa-arrows-rotate"></i> Refresh</button>
<button class="btn btn-sm btn-primary w-50" type="submit", name="save", value="Save"><i class="fa-solid fa-save"></i> Save</button>
{% endif %}
</div>

Expand All @@ -102,8 +105,13 @@ <h2 class="accordion-header" id="foes">
</div>
</form>

<div id="toastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3"></div>

<input type="hidden" id="notification" value="{{ notification }}">
<div id="toastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1000;"></div>
<div id="copytoastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1000;"></div>

<script src="{% static 'js/add-toast.js' %}"> </script>
<script src="{% static 'js/copy-toast.js' %}"> </script>


{% endblock content %}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
</form>

<input type="hidden" id="notification" value="{{ notification }}">
<div id="toastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3"></div>
<div id="toastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1000;"></div>

<script src="{% static 'js/add-toast.js' %}"></script>

Expand Down
14 changes: 11 additions & 3 deletions openlibrarian_root/almanac/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from utils.Session import async_logged_in, async_get_session_info, async_set_session_info, cache_get, cache_set, cache_key, cache_delete
from utils.Profile import edit_profile_info, edit_relay_list, fetch_profile_info
from utils.Login import check_nsec
from utils.Connections import fetch_social_list
from utils.Connections import fetch_social_list, add_follow
from nostr_sdk import Keys

# Users Settings View
Expand Down Expand Up @@ -173,14 +173,22 @@ async def user_friends(request):
friends = connctions['friends']
muted = connctions['muted']

notification = None

# POST requests
if request.method == 'POST':
if request.POST.get('refresh'):
if request.POST.get('refresh') or request.POST.get('follow_user'):

# Attempt to add new follow
if request.POST.get('follow_user'):
notification = await add_follow(session['relays'], npub=session['npub'], nsec=session['nsec'], follow_id=request.POST.get('follow_user'))

# Fetch lists again
friends = await fetch_social_list(relays=session['relays'], npub=session['npub'], list_type="follow")
muted = await fetch_social_list(relays=session['relays'], npub=session['npub'], list_type="mute")

# Cache the friends list for 30 minutes
await cache_delete(await cache_key(key_str,session))
await cache_set(await cache_key(key_str,session), {'friends': friends, 'muted': muted}, 1800)

return render(request, 'almanac/user_friends.html', {'session': session, 'friends': friends, 'muted': muted})
return render(request, 'almanac/user_friends.html', {'session': session, 'friends': friends, 'muted': muted, 'notification': notification})
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ <h5>Explore my Profile or Build your Own!</h5>
</div>
</div>

<div id="toastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1000;"></div>
<div id="copytoastContainer" class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1000;"></div>

<script src="{% static 'js/copy-toast.js' %}"> </script>

Expand Down
2 changes: 1 addition & 1 deletion openlibrarian_root/static/js/add-toast.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if (notification && notification !== "None") {
const toastContainer = document.getElementById('toastContainer');
const toast = document.createElement('div');
toast.classList.add('toast', 'align-items-center', 'text-white', 'bg-success', 'border-0');
if (notification === "Book already in library.") {
if (notification === "Book already in library." || notification === "Already Following.") {
toast.classList.remove('bg-success');
toast.classList.add('bg-danger');
}
Expand Down
2 changes: 1 addition & 1 deletion openlibrarian_root/static/js/copy-toast.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ copyButtons.forEach(button => {
document.execCommand('copy');
document.body.removeChild(textarea);

const toastContainer = document.getElementById('toastContainer');
const toastContainer = document.getElementById('copytoastContainer');
const toast = document.createElement('div');
toast.classList.add('toast', 'align-items-center', 'text-white', 'bg-success', 'border-0');
toast.setAttribute('role', 'alert');
Expand Down
48 changes: 46 additions & 2 deletions openlibrarian_root/utils/Connections.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from nostr_sdk import Client, Filter, Kind, KindEnum, Metadata, PublicKey, TagKind, SingleLetterTag, Alphabet, Keys, NostrSigner, EventBuilder, Contact
from nostr_sdk import Client, Filter, Kind, KindEnum, Metadata, PublicKey, Keys, NostrSigner, EventBuilder, get_nip05_profile, Tag
from utils.Network import nostr_get, nostr_post
from utils.Login import check_npub, check_nsec

Expand All @@ -25,7 +25,8 @@ async def fetch_social_list(relays: dict, npub: str = None, list_type: str = "fo
follow_list = []
if eventlist:
for tag in eventlist[0].tags():
follow_list.append(PublicKey.from_hex(tag.content()))
if tag.as_vec()[0] == "p":
follow_list.append(PublicKey.from_hex(tag.content()))

# Get following and related profile data
f = Filter().kind(Kind(0)).authors(follow_list)
Expand Down Expand Up @@ -101,5 +102,48 @@ async def clone_follow(relays: dict, npub: str = None, nsec: str = None):
await nostr_post(client=client, relays_dict=relays, eventbuilder=mute_builder, connect=False, disconnect=True)


async def add_follow(relays: dict, npub: str = None, nsec: str = None, follow_id: str = None):
if npub in [None, ""] or check_npub(npub) is False:
raise Exception("Invalid or missing npub")
if nsec in [None, ""] or check_nsec(nsec) is False:
raise Exception("Invalid or missing nsec")
if follow_id in [None, ""]:
raise Exception("Missing follow value")

# Check if follow is a valid pubkey or nip05 and get key
if check_npub(follow_id) is True:
follow_key = PublicKey.parse(follow_id)
else:
try:
profile = await get_nip05_profile(follow_id,None)
follow_key = profile.public_key()
except:
return "Invalid npub or nip05"

# Keys
keys = Keys.parse(nsec)

# Signer
signer = NostrSigner.keys(keys)
client = Client(signer)

# Request profile Metadata
follow_filter = Filter().kind(Kind.from_enum(KindEnum.CONTACT_LIST())).author(keys.public_key()).limit(1)

# Get following list and extract p tags
follow_events = await nostr_get(client=client, filters=[follow_filter], relays_dict=relays, wait=10, connect=True, disconnect=True)

for follow in follow_events:
if Tag.public_key(follow_key) not in follow.tags():
follow.tags().append(Tag.public_key(follow_key))

# Build follow event
follow_builder = EventBuilder(kind=Kind.from_enum(KindEnum.CONTACT_LIST()), tags=follow.tags(), content="")

# Post events
await nostr_post(client=client, relays_dict=relays, eventbuilder=follow_builder, connect=True, disconnect=True)
return "Added Friend."

else:
return "Already Following."

0 comments on commit 2b0c43c

Please sign in to comment.