noogle: add reactions, ui fixes

This commit is contained in:
Believethehype 2024-03-11 09:19:47 +01:00
parent 1e35c652e8
commit 57d4452ea8
5 changed files with 231 additions and 59 deletions

14
.idea/dataSources.xml generated
View File

@ -87,5 +87,19 @@
<jdbc-url>jdbc:sqlite:identifier.sqlite</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="identifier.sqlite [2]" uuid="6d783b7b-9c23-46fa-9057-ac42e5e18a1e">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:identifier.sqlite</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="identifier.sqlite [3]" uuid="4d771519-8188-464e-ba40-636a043fda3e">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:identifier.sqlite</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -15,7 +15,7 @@
<div tabIndex={0} role="button" class="button" >
<img class="avatar" :src="this.avatar" alt="" />
</div>
<div tabIndex={0} className="dropdown-content -start-44 z-[1] horizontal card card-compact w-64 p-2 shadow bg-primary text-primary-content">
<div tabIndex={0} className="dropdown-content -start-56 z-[1] horizontal card card-compact w-64 p-2 shadow bg-nostr text-primary-content">
<div className="card-body">
<h3 className="card-title">Sign out of your account</h3>
<!--<p>Sign out</p> -->
@ -23,13 +23,13 @@
</div>
</div>
</div>
<p>{{ this.current_user }}</p>
<!--<p>{{ this.current_user }}</p> -->
</div>
<template v-if="!current_user">
<div className="dropdown">
<div tabIndex={0} role="button" class="v-Button" >Sign in</div>
<div tabIndex={0} className="dropdown-content -start-44 z-[1] horizontal card card-compact w-64 p-2 shadow bg-primary text-primary-content">
<div tabIndex={0} className="dropdown-content -start-56 z-[1] horizontal card card-compact w-64 p-2 shadow bg-nostr text-primary-content">
<div className="card-body">
<h3 className="card-title">Login</h3>
<p>Use a Browser Nip07 Extension like getalby, nos2x or nsec.app, a nsec or ncryptsec or use Amber on Android to sign-in</p>

View File

@ -4,7 +4,7 @@
:items="data"
:sort-by="sortBy"
:sort-type="sortType">
<template #item-content="{content, author, authorurl, avatar, indicator, links, lud16, id, authorid, zapped, zapAmount}">
<template #item-content="{content, author, authorurl, avatar, indicator, links, lud16, id, authorid, zapped, zapAmount, reacted, reactions}">
<div class="playeauthor-wrapper">
@ -29,10 +29,31 @@
<!--<a class="menusmall" :href="links.highlighter" target="_blank">Highlighter</a> -->
<a class="menusmall":href="links.nostrudel" target="_blank">Nostrudel</a>
<div class="flex" >
<div class="flex" style="margin-left: auto; margin-right: 5px;" v-if="!reacted" @click="react(id, authorid)">
<div style="margin-left: auto; margin-right: 5px; float: left;">
<svg style="margin-top:4px" width="14" height="12" xmlns="http://www.w3.org/2000/svg" class="bi bi-heart" fill-rule="evenodd" fill="currentColor" viewBox="0 0 20 25" clip-rule="evenodd"><path d="M12 21.593c-5.63-5.539-11-10.297-11-14.402 0-3.791 3.068-5.191 5.281-5.191 1.312 0 4.151.501 5.719 4.457 1.59-3.968 4.464-4.447 5.726-4.447 2.54 0 5.274 1.621 5.274 5.181 0 4.069-5.136 8.625-11 14.402m5.726-20.583c-2.203 0-4.446 1.042-5.726 3.238-1.285-2.206-3.522-3.248-5.719-3.248-3.183 0-6.281 2.187-6.281 6.191 0 4.661 5.571 9.429 12 15.809 6.43-6.38 12-11.148 12-15.809 0-4.011-3.095-6.181-6.274-6.181"/></svg> </div>
<div>
<p style="float: left;">{{reactions}}</p>
</div>
</div>
<div class="flex" v-if="reacted" style="margin-left: auto; margin-right: 5px;" @click="react(id, authorid)">
<div style="margin-left: auto; margin-right: 5px; float: left;">
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="12" class="bi bi-heart fill-nostr" viewBox="0 0 20 25"><path d="M12 4.419c-2.826-5.695-11.999-4.064-11.999 3.27 0 7.27 9.903 10.938 11.999 15.311 2.096-4.373 12-8.041 12-15.311 0-7.327-9.17-8.972-12-3.27z"/></svg> </div>
<div>
<p className="text-nostr" style="float: left;">{{reactions}}</p>
</div>
</div>
<div class="flex" v-if="!zapped" @click="zap(lud16, id, authorid)">
<div style="margin-left: auto; margin-right: 5px; float: left;">
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" fill="currentColor" class="bi bi-lightning" viewBox="0 0 16 20">
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/> </svg> </div>
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/>
</svg> </div>
<div>
<p style="float: left;">{{zapAmount/1000}}</p>
</div>
@ -40,13 +61,15 @@
<div class="flex" v-if="zapped" @click="zap(lud16, id, authorid)" >
<div style="margin-left: auto; margin-right: 5px;">
<svg style="margin-top:4px" xmlns="http://www.w3.org/2000/svg" width="14" height="16" class="bi bi-lightning fill-amber-400" viewBox="0 0 16 20">
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641zM6.374 1 4.168 8.5H7.5a.5.5 0 0 1 .478.647L6.78 13.04 11.478 7H8a.5.5 0 0 1-.474-.658L9.306 1z"/></svg></div>
<path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641z"/>
</svg></div>
<div>
<p style="float: left;" className="text-amber-400">{{zapAmount/1000}}</p>
</div>
</div>
</div>
</div>
</template>
@ -66,6 +89,8 @@ import Null = types.Null;
import StringUtil from "@/components/helper/string";
import {copyinvoice, createBolt11Lud16, parseandreplacenpubs, zaprequest} from "@/components/helper/Helper.vue";
import {requestProvider} from "webln";
import {Event, EventBuilder, EventId, PublicKey} from "@rust-nostr/nostr-sdk";
import amberSignerService from "@/components/android-signer/AndroidSigner";
const props = defineProps<{
@ -83,6 +108,43 @@ const headers: Header[] = [
];
async function react(eventid, authorid){
let event_id = EventId.parse(eventid)
let public_key = PublicKey.parse(authorid);
let signer = store.state.signer
let client = store.state.client
let objects = (props.data.find(x=> x.id === eventid))
if (objects !== undefined){
if(!objects.reacted ){
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
let draft = {
content: "🧡",
kind: 7,
pubkey: store.state.pubkey.toHex(),
tags: [],
createdAt: Date.now()
};
let res = await amberSignerService.signEvent(draft)
await client.sendEvent(Event.fromJson(JSON.stringify(res)))
let requestid = res.id;
}
else {
let event = EventBuilder.reaction(event_id, public_key, "🧡")
let res = await client.sendEventBuilder(event);
}
objects.reacted = true
objects.reactions += 1
}
}
}
async function zap(lud16, eventid, authorid){
if(lud16 != Null && lud16 != ""){

View File

@ -22,7 +22,7 @@ import {data} from "autoprefixer";
import {requestProvider} from "webln";
import Newnote from "@/components/Newnote.vue";
import SummarizationGeneration from "@/components/SummarizationGeneration.vue"
import {post_note, schedule, copyurl, copyinvoice, sleep, getEvents, get_user_infos, get_zaps, nextInput, createBolt11Lud16, getEventsOriginalOrder, parseandreplacenpubsName} from "../components/helper/Helper.vue"
import {post_note, schedule, copyurl, copyinvoice, sleep, getEvents, get_user_infos, get_zaps, get_reactions, nextInput, createBolt11Lud16, getEventsOriginalOrder, parseandreplacenpubsName} from "../components/helper/Helper.vue"
import amberSignerService from "./android-signer/AndroidSigner";
import StringUtil from "@/components/helper/string.ts";
@ -144,8 +144,25 @@ async function listen() {
//miniToastr.showMessage("DVM: " + dvmname, event.content, VueNotifications.types.info)
for (const tag in event.tags) {
if (event.tags[tag].asVec()[0] === "status") {
dvms.find(i => i.id === event.author.toHex()).status = event.tags[tag].asVec()[1]
}
if (event.content !== "" && event.tags[tag].asVec()[1] === "processing") {
if(event.tags[tag].asVec().length > 2) {
dvms.find(i => i.id === event.author.toHex()).status = event.tags[tag].asVec()[2]
}
else{
dvms.find(i => i.id === event.author.toHex()).status = event.content
}
}
else{
dvms.find(i => i.id === event.author.toHex()).status = event.tags[tag].asVec()[1]
}
}
if (event.tags[tag].asVec()[0] === "amount") {
dvms.find(i => i.id === event.author.toHex()).amount = event.tags[tag].asVec()[1]
@ -246,6 +263,8 @@ async function listen() {
if (items.find(e => e.id === evt.id.toHex()) === undefined) {
let react = zaps.find(x => x.id === evt.id.toHex())
items.push({
id: evt.id.toHex(),
content: await parseandreplacenpubsName(evt.content),
@ -262,8 +281,10 @@ async function listen() {
index: index,
indicator: {"time": evt.createdAt.toHumanDatetime(), "index": index},
lud16: lud16,
zapped: zaps.find(x => x.id === evt.id.toHex()).zappedbyUser,
zapAmount: zaps.find(x => x.id === evt.id.toHex()).amount
zapped: react.zappedbyUser,
zapAmount: react.amount,
reacted: react.reactedbyUser,
reactions: react.reactions,
})
index = index + 1
@ -342,7 +363,7 @@ async function addAllContentDVMs() {
}
// console.log(last_active)
// If DVM hasnt been active for 3 weeks, don't consider it.
// If DVM hasn't been active for 3 weeks, don't consider it.
console.log(active_dvms)
let final_dvms = []
for (let element of active_dvms) {
@ -455,7 +476,7 @@ async function addDVM(event){
if (event.content !== "" && status !== "payment-required" && status !== "error" && status !== "finished" && status !== "paid"){
status = event.content
}
jsonentry.status = status
console.log(dvms)
if (dvms.filter(i => i.id === jsonentry.id).length === 0) {
dvms.push(jsonentry)

View File

@ -139,17 +139,91 @@ export async function get_user_infos(pubkeys){
}
export async function get_zaps(ids){
let zaps = []
let jsonentry = {}
let zapsandreactions = []
for (let id of ids){
zaps.push({
zapsandreactions.push({
id: id.toHex(),
amount: 0,
zappedbyUser: false,})
reactions: 0,
zappedbyUser: false,
reactedbyUser: false,})
}
let client = store.state.client
const zap_filter = new Filter().kind(9735).events(ids)
const zap_filter = new Filter().kinds([9735, 7]).events(ids)
let evts = await client.getEventsOf([zap_filter], Duration.fromSecs(10))
for (const entry of evts){
try{
//let contentjson = JSON.parse(entry.content)
if (entry.kind === 9735){
for (let tag of entry.tags) {
if (tag.asVec()[0] === "description") {
let request = JSON.parse(tag.asVec()[1])
let etag = ""
let amount = 0
for (let tg of request.tags) {
if (tg[0] === "amount") {
amount = parseInt(tg[1])
}
if (tg[0] === "e") {
etag = tg[1]
console.log(request.pubkey)
if (request.pubkey === localStorage.getItem("nostr-key")) {
zapsandreactions.find(x => x.id === etag).zappedbyUser = true
}
}
}
zapsandreactions.find(x => x.id === etag).amount += amount
}
}
}
else if (entry.kind === 7) {
for (let tag of entry.tags) {
if (tag.asVec()[0] === "e") {
console.log(entry.pubkey)
if (entry.author.toHex() === localStorage.getItem("nostr-key")) {
zapsandreactions.find(x => x.id === tag.asVec()[1]).reactedbyUser = true
}
zapsandreactions.find(x => x.id === tag.asVec()[1]).reactions += 1
}
}
}
//console.log(contentjson)
//zaps.push({profile: contentjson, author: entry.author.toHex(), createdAt: entry.createdAt});
}
catch(error){
console.log("error")
}
}
console.log(zapsandreactions)
return zapsandreactions
}
export async function get_reactions(ids){
let reactions = []
let jsonentry = {}
for (let id of ids){
reactions.push({
id: id.toHex(),
amount: 0,
ReactedbyUser: false,})
}
let client = store.state.client
const zap_filter = new Filter().kind(7).events(ids)
let evts = await client.getEventsOf([zap_filter], Duration.fromSecs(10))
for (const entry of evts){
@ -157,26 +231,13 @@ export async function get_zaps(ids){
//let contentjson = JSON.parse(entry.content)
for (let tag of entry.tags){
if (tag.asVec()[0] === "description"){
let request = JSON.parse(tag.asVec()[1])
let etag = ""
let amount = 0
for (let tg of request.tags){
if (tg[0] === "amount") {
amount = parseInt(tg[1])
}
if (tg[0] === "e") {
etag = tg[1]
console.log(request.pubkey )
if(request.pubkey === localStorage.getItem("nostr-key")){
zaps.find(x=> x.id === etag).zappedbyUser = true
}
}
if (tag.asVec()[0] === "e") {
console.log(entry.pubkey )
if(entry.pubkey === localStorage.getItem("nostr-key")){
reactions.find(x=> x.id === tag.asVec()[1]).ReactedbyUser = true
}
zaps.find(x=> x.id === etag).amount += amount
reactions.find(x=> x.id === tag.asVec()[1]).amount += 1
}
}
@ -189,9 +250,9 @@ export async function get_zaps(ids){
}
console.log(zaps)
console.log(reactions)
return zaps
return reactions
}
@ -203,8 +264,9 @@ export const sleep = (ms) => {
export async function copyinvoice(invoice){
await navigator.clipboard.writeText(invoice)
window.open("lightning:" + invoice,"_blank")
await navigator.clipboard.writeText(invoice)
miniToastr.showMessage("", "Copied Invoice to clipboard", VueNotifications.types.info)
}
@ -333,26 +395,24 @@ export async function zaprequest(lud16, amount, content, zapped_event_id, zapped
const urlBytes = new TextEncoder().encode(url);
const encoded_lnurl = bech32.encode('lnurl', bech32.toWords(urlBytes), 1023);
console.log(encoded_lnurl)
console.log( relay_list.toString())
console.log(zapped_event_id)
console.log(zapped_user_id)
const amount_tag = Tag.parse(['amount', (amount * 1000).toString()]);
const amount_tag = ['amount', (amount * 1000).toString()];
let relays = ['relays']
relays.push.apply(relays, relay_list)
let relays_tag = Tag.parse(relays);
//let relays_tag = Tag.parse(relays);
const lnurl_tag = Tag.parse(['lnurl', encoded_lnurl]);
const lnurl_tag = ['lnurl', encoded_lnurl];
let tags
let p_tag = Tag.parse(['p', zapped_user_id])
let tags = []
let p_tag = ['p', zapped_user_id]
if (zapped_event_id !== null){
let e_tag = Tag.parse(['e', zapped_event_id])
tags = [amount_tag, relays_tag, p_tag, e_tag, lnurl_tag]
let e_tag = ['e', zapped_event_id]
tags = [amount_tag, relays, p_tag, e_tag, lnurl_tag]
}
else{
tags = [amount_tag, relays_tag, p_tag, lnurl_tag]
tags = [amount_tag, relays, p_tag, lnurl_tag]
}
/*if (zaptype === "private") {
const key_str = keys.secret_key().to_hex() + zapped_event.id().to_hex() + zapped_event.created_at().as_secs().toString();
@ -368,16 +428,31 @@ export async function zaprequest(lud16, amount, content, zapped_event_id, zapped
let signer = store.state.signer
let zap_request = ""
let noteevent = new EventBuilder(9734, content, tags).toUnsignedEvent(store.state.pubkey)
let signedEvent = await signer.signEvent(noteevent)
let zap_request = signedEvent.asJson()
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
let draft = {
content: content,
kind: 9734,
pubkey: store.state.pubkey.toHex(),
tags: tags,
createdAt: Date.now()
};
//console.log(encoded_zap_request)
let res = await amberSignerService.signEvent(draft)
zap_request = JSON.stringify(res)
//await sleep(3000)
//`amount=${(amount * 1000).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`;
// const queryString = `amount=${(amount * 1000).toString()}&nostr=${encodeURIComponent(zap_request)}&lnurl=${encoded_lnurl}`;
}
else {
let tags_t = []
for (let tag of tags){
tags_t.push(Tag.parse(tag))
}
let noteevent = new EventBuilder(9734, content, tags_t).toUnsignedEvent(store.state.pubkey)
let signedEvent = await signer.signEvent(noteevent)
zap_request = signedEvent.asJson()
}
try{