mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-03-29 11:01:41 +01:00
noogle: refactor code, add summarization
This commit is contained in:
parent
4bb6721b2d
commit
90e3395691
@ -22,94 +22,18 @@ import {data} from "autoprefixer";
|
||||
import {requestProvider} from "webln";
|
||||
import Newnote from "@/components/Newnote.vue";
|
||||
import amberSignerService from "./android-signer/AndroidSigner";
|
||||
import { ref } from "vue";
|
||||
import ModalComponent from "../components/Newnote.vue";
|
||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||
import {timestamp} from "@vueuse/core";
|
||||
import {post_note, schedule, copyinvoice, copyurl, sleep, nextInput} from "../components/helper/Helper.vue"
|
||||
|
||||
|
||||
|
||||
let dvms =[]
|
||||
let searching = false
|
||||
|
||||
|
||||
|
||||
let listener = false
|
||||
|
||||
let hasmultipleinputs = false
|
||||
|
||||
function showDetails(user) {
|
||||
this.$bvModal.show("modal-details");
|
||||
this.modalData = user;
|
||||
}
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
|
||||
async function post_note(note){
|
||||
let client = store.state.client
|
||||
let tags = []
|
||||
|
||||
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
||||
const draft = {
|
||||
content: note,
|
||||
kind: 1,
|
||||
pubkey: store.state.pubkey.toHex(),
|
||||
tags: tags,
|
||||
createdAt: Date.now()
|
||||
};
|
||||
const eventJson = await amberSignerService.signEvent(draft);
|
||||
await client.sendEvent(Event.fromJson(JSON.stringify(eventJson)));
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.publishTextNote(note, tags);
|
||||
}
|
||||
}
|
||||
|
||||
async function schedule(note) {
|
||||
|
||||
|
||||
let schedule = Timestamp.fromSecs(datetopost.value/1000)
|
||||
let humandatetime = schedule.toHumanDatetime()
|
||||
let time = humandatetime.split("T")[1].split("Z")[0].trim()
|
||||
let date = humandatetime.split("T")[0].split("-")[2].trim() + "." + humandatetime.split("T")[0].split("-")[1].trim() + "." + humandatetime.split("T")[0].split("-")[0].trim().slice(2)
|
||||
|
||||
console.log("Date: " + date + " Time: "+ time )
|
||||
|
||||
let client = store.state.client
|
||||
let signer = store.state.signer
|
||||
|
||||
let noteevent = EventBuilder.textNote(note, []).customCreatedAt(schedule).toUnsignedEvent(store.state.pubkey)
|
||||
let signedEvent = await signer.signEvent(noteevent)
|
||||
|
||||
let stringifiedevent = signedEvent.asJson()
|
||||
|
||||
let tags_str = []
|
||||
let tag = Tag.parse(["i", stringifiedevent, "text"])
|
||||
tags_str.push(tag.asVec())
|
||||
let tags_as_str = JSON.stringify(tags_str)
|
||||
|
||||
|
||||
let content = await signer.nip04Encrypt(PublicKey.parse("85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"), tags_as_str)
|
||||
|
||||
let tags_t = []
|
||||
tags_t.push(Tag.parse(["p", "85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"]))
|
||||
tags_t.push(Tag.parse(["encrypted"]))
|
||||
tags_t.push(Tag.parse(["client", "noogle"]))
|
||||
|
||||
|
||||
let evt = new EventBuilder(5905, content, tags_t)
|
||||
console.log(evt)
|
||||
let res = await client.sendEventBuilder(evt);
|
||||
console.log(res)
|
||||
miniToastr.showMessage("Note scheduled for " + ("Date: " + date + " Time: "+ time ))
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function generate_image(message) {
|
||||
|
||||
try {
|
||||
if (message === undefined){
|
||||
message = "A purple Ostrich"
|
||||
@ -138,8 +62,6 @@ async function generate_image(message) {
|
||||
console.log(urlinput.value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
let res;
|
||||
let requestid;
|
||||
|
||||
@ -155,7 +77,6 @@ async function generate_image(message) {
|
||||
res = await amberSignerService.signEvent(draft)
|
||||
await client.sendEvent(Event.fromJson(JSON.stringify(res)))
|
||||
requestid = res.id;
|
||||
res = res.id;
|
||||
}
|
||||
else {
|
||||
|
||||
@ -170,10 +91,6 @@ async function generate_image(message) {
|
||||
}
|
||||
|
||||
store.commit('set_current_request_id_image', requestid)
|
||||
//console.log("IMAGE EVENT SENT: " + res.toHex())
|
||||
|
||||
//miniToastr.showMessage("Sent Request to DVMs", "Awaiting results", VueNotifications.types.warn)
|
||||
searching = true
|
||||
if (!store.state.imagehasEventListener){
|
||||
listen()
|
||||
store.commit('set_imagehasEventListener', true)
|
||||
@ -188,8 +105,6 @@ async function generate_image(message) {
|
||||
}
|
||||
|
||||
async function listen() {
|
||||
listener = true
|
||||
|
||||
let client = store.state.client
|
||||
let pubkey = store.state.pubkey
|
||||
|
||||
@ -224,7 +139,6 @@ async function listen() {
|
||||
try {
|
||||
console.log("7000: ", event.content);
|
||||
console.log("DVM: " + event.author.toHex())
|
||||
searching = false
|
||||
//miniToastr.showMessage("DVM: " + dvmname, event.content, VueNotifications.types.info)
|
||||
|
||||
let status = "unknown"
|
||||
@ -301,7 +215,7 @@ async function listen() {
|
||||
}
|
||||
})
|
||||
},
|
||||
// Handle relay message
|
||||
|
||||
handleMsg: async (relayUrl, message) => {
|
||||
//console.log("Received message from", relayUrl, message.asJson());
|
||||
}
|
||||
@ -313,25 +227,6 @@ async function listen() {
|
||||
|
||||
const urlinput = ref("");
|
||||
|
||||
function nextInput(e) {
|
||||
const next = e.currentTarget.nextElementSibling;
|
||||
if (next) {
|
||||
next.focus();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function copyinvoice(invoice){
|
||||
await navigator.clipboard.writeText(invoice)
|
||||
window.open("lightning:" + invoice,"_blank")
|
||||
miniToastr.showMessage("", "Copied Invoice to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
async function copyurl(url){
|
||||
await navigator.clipboard.writeText(url)
|
||||
miniToastr.showMessage("", "Copied link to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
|
||||
async function zap(invoice) {
|
||||
@ -358,44 +253,11 @@ function nextInput(e) {
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
|
||||
//console.log(response)
|
||||
//for (const dvm of dvms){
|
||||
// console.log(dvm.bolt11 + " " + invoice)
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async function createBolt11Lud16(lud16, amount) {
|
||||
let url;
|
||||
if (lud16.includes('@')) { // LNaddress
|
||||
const parts = lud16.split('@');
|
||||
url = `https://${parts[1]}/.well-known/lnurlp/${parts[0]}`;
|
||||
} else { // No lud16 set or format invalid
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(url);
|
||||
const response = await fetch(url);
|
||||
const ob = await response.json();
|
||||
const callback = ob.callback;
|
||||
const amountInSats = parseInt(amount) * 1000;
|
||||
const callbackResponse = await fetch(`${callback}?amount=${amountInSats}`);
|
||||
const obCallback = await callbackResponse.json();
|
||||
return obCallback.pr;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(`LUD16: ${e}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
defineProps({
|
||||
msg: {
|
||||
@ -404,10 +266,7 @@ defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
import { ref } from "vue";
|
||||
import ModalComponent from "../components/Newnote.vue";
|
||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||
import {timestamp} from "@vueuse/core";
|
||||
|
||||
|
||||
const isModalOpened = ref(false);
|
||||
const modalcontent = ref("");
|
||||
@ -425,17 +284,10 @@ const closeModal = () => {
|
||||
};
|
||||
|
||||
const submitHandler = async () => {
|
||||
|
||||
// await post_note(modalcontent)
|
||||
await schedule(modalcontent, Timestamp.now())
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<!-- font-thin bg-gradient-to-r from-white to-nostr bg-clip-text text-transparent -->
|
||||
|
||||
<template>
|
||||
|
||||
<div class="greetings">
|
||||
@ -454,12 +306,10 @@ const submitHandler = async () => {
|
||||
<summary class="collapse-title font-thin bg">Advanced Options</summary>
|
||||
<div class="collapse-content font-size-0" className="z-10" id="collapse-settings">
|
||||
<div>
|
||||
<h4 className="inline-flex flex-none font-thin">Url to existing image:</h4>
|
||||
<div className="inline-flex flex-none" style="width: 10px;"></div>
|
||||
<input class="c-Input" style="width: 300px;" placeholder="https://image.nostr.build/image123.jpg" v-model="urlinput">
|
||||
</div>
|
||||
|
||||
|
||||
<h4 className="inline-flex flex-none font-thin">Url to existing image:</h4>
|
||||
<div className="inline-flex flex-none" style="width: 10px;"></div>
|
||||
<input class="c-Input" style="width: 300px;" placeholder="https://image.nostr.build/image123.jpg" v-model="urlinput">
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
@ -471,32 +321,18 @@ const submitHandler = async () => {
|
||||
|
||||
<template #content>
|
||||
<textarea v-model="modalcontent" className="d-Input" style="height: 300px;">{{modalcontent}}</textarea>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
<VueDatePicker :min-date="new Date()" :teleport="false" :dark="true" position="right" className="bg-base-200 inline-flex flex-none" style="width: 220px;" v-model="datetopost"></VueDatePicker>
|
||||
|
||||
<button className="v-Button" @click="schedule(modalcontent)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px" src="../../public/shipyard.ico"/>Schedule Note with Shipyard DVM</button>
|
||||
|
||||
<VueDatePicker :min-date="new Date()" :teleport="false" :dark="true" position="right" className="bg-base-200 inline-flex flex-none" style="width: 220px;" v-model="datetopost"></VueDatePicker>
|
||||
<button className="v-Button" @click="schedule(modalcontent, datetopost)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px" src="../../public/shipyard.ico"/>Schedule Note with Shipyard DVM</button>
|
||||
<br>
|
||||
or
|
||||
<br>
|
||||
<button className="v-Button" style="margin-bottom: 0px" @click="post_note(modalcontent)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px;" src="../../public/favicon.ico"/>Post Note now</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
</ModalComponent>
|
||||
|
||||
@ -543,12 +379,12 @@ const submitHandler = async () => {
|
||||
</figure>
|
||||
<div v-if="dvm.result && store.state.pubkey.toHex() !== Keys.parse('ece3c0aa759c3e895ecb3c13ab3813c0f98430c6d4bd22160b9c2219efc9cf0e').publicKey.toHex()" >
|
||||
<button @click="openModal('Look what I created on noogle.lol\n\n' + dvm.result)" class="w-8 h-8 rounded-full bg-nostr border-white border-1 text-white flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black tooltip" data-top='Share' aria-label="make note" role="button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil" width="20" height="20" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"></path>
|
||||
<path d="M4 20h4l10.5 -10.5a1.5 1.5 0 0 0 -4 -4l-10.5 10.5v4"></path>
|
||||
<line x1="13.5" y1="6.5" x2="17.5" y2="10.5"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil" width="20" height="20" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"></path>
|
||||
<path d="M4 20h4l10.5 -10.5a1.5 1.5 0 0 0 -4 -4l-10.5 10.5v4"></path>
|
||||
<line x1="13.5" y1="6.5" x2="17.5" y2="10.5"></line>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -18,8 +18,8 @@ onClickOutside(target, ()=>emit('modal-close'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="isOpen" class="modal-mask">
|
||||
<div class="modal-wrapper">
|
||||
<div v-if="isOpen" class="modal-mask" >
|
||||
<div class="modal-wrapper" >
|
||||
<div class="modal-container" ref="target">
|
||||
<div class="modal-header">
|
||||
<slot name="header"> default header </slot>
|
||||
@ -30,8 +30,8 @@ onClickOutside(target, ()=>emit('modal-close'))
|
||||
<div class="modal-footer">
|
||||
<slot name="footer">
|
||||
<div>
|
||||
<button @click.stop="emit('modal-close')">Submit</button>
|
||||
<button @click.stop="schedule(Date.now())">Schedule</button>
|
||||
<button @click.stop="emit('modal-close')"></button>
|
||||
<button @click.stop="schedule(Date.now())"></button>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
@ -42,6 +42,8 @@ onClickOutside(target, ()=>emit('modal-close'))
|
||||
|
||||
<style scoped>
|
||||
.modal-mask {
|
||||
|
||||
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
@ -51,12 +53,13 @@ onClickOutside(target, ()=>emit('modal-close'))
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.modal-container {
|
||||
@apply bg-base-100;
|
||||
width: 400px;
|
||||
@apply bg-base-200;
|
||||
width: 600px;
|
||||
margin: 200px auto;
|
||||
padding: 20px 30px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
@ -21,98 +21,15 @@ import deadnip89s from "@/components/data/deadnip89s.json";
|
||||
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, nextInput} from "../components/helper/Helper.vue"
|
||||
import amberSignerService from "./android-signer/AndroidSigner";
|
||||
|
||||
let dvms =[]
|
||||
let searching = false
|
||||
|
||||
|
||||
|
||||
let listener = false
|
||||
|
||||
let hasmultipleinputs = false
|
||||
|
||||
function showDetails(user) {
|
||||
this.$bvModal.show("modal-details");
|
||||
this.modalData = user;
|
||||
}
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
|
||||
async function post_note(note){
|
||||
let client = store.state.client
|
||||
let tags = []
|
||||
|
||||
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
||||
const draft = {
|
||||
content: note,
|
||||
kind: 1,
|
||||
pubkey: store.state.pubkey.toHex(),
|
||||
tags: tags,
|
||||
createdAt: Date.now()
|
||||
};
|
||||
const eventJson = await amberSignerService.signEvent(draft);
|
||||
await client.sendEvent(Event.fromJson(JSON.stringify(eventJson)));
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.publishTextNote(note, tags);
|
||||
}
|
||||
}
|
||||
|
||||
async function schedule(note) {
|
||||
|
||||
|
||||
let schedule = Timestamp.fromSecs(datetopost.value/1000)
|
||||
let humandatetime = schedule.toHumanDatetime()
|
||||
let time = humandatetime.split("T")[1].split("Z")[0].trim()
|
||||
let date = humandatetime.split("T")[0].split("-")[2].trim() + "." + humandatetime.split("T")[0].split("-")[1].trim() + "." + humandatetime.split("T")[0].split("-")[0].trim().slice(2)
|
||||
|
||||
console.log("Date: " + date + " Time: "+ time )
|
||||
|
||||
let client = store.state.client
|
||||
let signer = store.state.signer
|
||||
|
||||
let noteevent = EventBuilder.textNote(note, []).customCreatedAt(schedule).toUnsignedEvent(store.state.pubkey)
|
||||
let signedEvent = await signer.signEvent(noteevent)
|
||||
|
||||
let stringifiedevent = signedEvent.asJson()
|
||||
|
||||
let tags_str = []
|
||||
let tag = Tag.parse(["i", stringifiedevent, "text"])
|
||||
tags_str.push(tag.asVec())
|
||||
let tags_as_str = JSON.stringify(tags_str)
|
||||
|
||||
|
||||
let content = await signer.nip04Encrypt(PublicKey.parse("85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"), tags_as_str)
|
||||
|
||||
let tags_t = []
|
||||
tags_t.push(Tag.parse(["p", "85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"]))
|
||||
tags_t.push(Tag.parse(["encrypted"]))
|
||||
tags_t.push(Tag.parse(["client", "noogle"]))
|
||||
|
||||
|
||||
let evt = new EventBuilder(5905, content, tags_t)
|
||||
console.log(evt)
|
||||
let res = await client.sendEventBuilder(evt);
|
||||
console.log(res)
|
||||
miniToastr.showMessage("Note scheduled for " + ("Date: " + date + " Time: "+ time ))
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function generate_feed() {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
if(store.state.pubkey === undefined || localStorage.getItem('nostr-key-method') === "anon"){
|
||||
miniToastr.showMessage("In order to receive personalized recommendations, sign-in first.", "Not signed in.", VueNotifications.types.warn)
|
||||
return
|
||||
@ -122,20 +39,13 @@ async function generate_feed() {
|
||||
dvm = {}
|
||||
dvms.pop()
|
||||
}
|
||||
|
||||
dvms = []
|
||||
store.commit('set_recommendation_dvms', dvms)
|
||||
let client = store.state.client
|
||||
|
||||
let content = "NIP 90 Content Discovery request"
|
||||
let kind = 5300
|
||||
let tags = [
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
let tags = []
|
||||
let res;
|
||||
let requestid;
|
||||
|
||||
@ -169,10 +79,6 @@ async function generate_feed() {
|
||||
}
|
||||
|
||||
store.commit('set_current_request_id_recommendation', requestid)
|
||||
//console.log("IMAGE EVENT SENT: " + res.toHex())
|
||||
|
||||
//miniToastr.showMessage("Sent Request to DVMs", "Awaiting results", VueNotifications.types.warn)
|
||||
searching = true
|
||||
if (!store.state.recommendationehasEventListener){
|
||||
listen()
|
||||
store.commit('set_recommendationEventListener', true)
|
||||
@ -187,39 +93,7 @@ async function generate_feed() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function getEvents(eventids) {
|
||||
const event_filter = new Filter().ids(eventids)
|
||||
let client = store.state.client
|
||||
return await client.getEventsOf([event_filter], Duration.fromSecs(5))
|
||||
}
|
||||
|
||||
|
||||
async function get_user_infos(pubkeys){
|
||||
let profiles = []
|
||||
let client = store.state.client
|
||||
const profile_filter = new Filter().kind(0).authors(pubkeys)
|
||||
let evts = await client.getEventsOf([profile_filter], Duration.fromSecs(10))
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
//console.log(contentjson)
|
||||
profiles.push({profile: contentjson, author: entry.author.toHex(), createdAt: entry.createdAt});
|
||||
}
|
||||
catch(error){
|
||||
console.log("error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return profiles
|
||||
|
||||
}
|
||||
|
||||
async function listen() {
|
||||
listener = true
|
||||
|
||||
let client = store.state.client
|
||||
let pubkey = store.state.pubkey
|
||||
|
||||
@ -239,8 +113,6 @@ async function listen() {
|
||||
sleep(1000).then(async () => {
|
||||
for (let tag in event.tags) {
|
||||
if (event.tags[tag].asVec()[0] === "e") {
|
||||
console.log("RECOMMENDATION ETAG: " + event.tags[tag].asVec()[1])
|
||||
console.log("RECOMMENDATION LISTEN TO : " + store.state.requestidRecommendation)
|
||||
if (event.tags[tag].asVec()[1] === store.state.requestidRecommendation) {
|
||||
resonsetorequest = true
|
||||
}
|
||||
@ -254,7 +126,6 @@ async function listen() {
|
||||
try {
|
||||
console.log("7000: ", event.content);
|
||||
console.log("DVM: " + event.author.toHex())
|
||||
searching = false
|
||||
//miniToastr.showMessage("DVM: " + dvmname, event.content, VueNotifications.types.info)
|
||||
|
||||
let status = "unknown"
|
||||
@ -364,23 +235,16 @@ async function listen() {
|
||||
indicator: {"time": evt.createdAt.toHumanDatetime()}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//miniToastr.showMessage("DVM: " + dvmname, "Received Results", VueNotifications.types.success)
|
||||
dvms.find(i => i.id === event.author.toHex()).result.length = 0
|
||||
dvms.find(i => i.id === event.author.toHex()).result.push.apply(dvms.find(i => i.id === event.author.toHex()).result, items)
|
||||
dvms.find(i => i.id === event.author.toHex()).status = "finished"
|
||||
dvms.find(i => i.id === event.author.toHex()).result.push.apply(dvms.find(i => i.id === event.author.toHex()).result, items)
|
||||
dvms.find(i => i.id === event.author.toHex()).status = "finished"
|
||||
}
|
||||
}
|
||||
store.commit('set_recommendation_dvms', dvms)
|
||||
|
||||
//store.commit('set_imagedvm_results', dvms)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -396,83 +260,32 @@ async function listen() {
|
||||
|
||||
const urlinput = ref("");
|
||||
|
||||
function nextInput(e) {
|
||||
const next = e.currentTarget.nextElementSibling;
|
||||
if (next) {
|
||||
next.focus();
|
||||
|
||||
async function zap(invoice) {
|
||||
let webln;
|
||||
|
||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
||||
//this.dvminvoice = invoice
|
||||
try {
|
||||
webln = await requestProvider();
|
||||
} catch (err) {
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
if (webln) {
|
||||
try{
|
||||
let response = await webln.sendPayment(invoice)
|
||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||
store.commit('set_recommendation_results', dvms)
|
||||
}
|
||||
catch(err){
|
||||
console.log(err)
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function copyinvoice(invoice){
|
||||
await navigator.clipboard.writeText(invoice)
|
||||
window.open("lightning:" + invoice,"_blank")
|
||||
miniToastr.showMessage("", "Copied Invoice to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
async function copyurl(url){
|
||||
await navigator.clipboard.writeText(url)
|
||||
miniToastr.showMessage("", "Copied link to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
|
||||
async function zap(invoice) {
|
||||
let webln;
|
||||
|
||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
||||
//this.dvminvoice = invoice
|
||||
|
||||
|
||||
try {
|
||||
webln = await requestProvider();
|
||||
} catch (err) {
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
if (webln) {
|
||||
try{
|
||||
let response = await webln.sendPayment(invoice)
|
||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||
store.commit('set_recommendation_results', dvms)
|
||||
}
|
||||
catch(err){
|
||||
console.log(err)
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async function createBolt11Lud16(lud16, amount) {
|
||||
let url;
|
||||
if (lud16.includes('@')) { // LNaddress
|
||||
const parts = lud16.split('@');
|
||||
url = `https://${parts[1]}/.well-known/lnurlp/${parts[0]}`;
|
||||
} else { // No lud16 set or format invalid
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(url);
|
||||
const response = await fetch(url);
|
||||
const ob = await response.json();
|
||||
const callback = ob.callback;
|
||||
const amountInSats = parseInt(amount) * 1000;
|
||||
const callbackResponse = await fetch(`${callback}?amount=${amountInSats}`);
|
||||
const obCallback = await callbackResponse.json();
|
||||
return obCallback.pr;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(`LUD16: ${e}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
defineProps({
|
||||
msg: {
|
||||
type: String,
|
||||
@ -494,17 +307,24 @@ const datetopost = ref(Date.now());
|
||||
const openModal = result => {
|
||||
datetopost.value = Date.now();
|
||||
isModalOpened.value = true;
|
||||
|
||||
|
||||
|
||||
//let resevents = ""
|
||||
//for (let evt of result){
|
||||
// resevents = resevents + "nostr:" + (evt.id.toBech32()) + "\n"
|
||||
//}
|
||||
modalcontent.value = result
|
||||
};
|
||||
const closeModal = () => {
|
||||
isModalOpened.value = false;
|
||||
console.log(datetopost.value)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const submitHandler = async () => {
|
||||
|
||||
// await post_note(modalcontent)
|
||||
await schedule(modalcontent, Timestamp.now())
|
||||
}
|
||||
|
||||
|
||||
@ -528,23 +348,31 @@ const submitHandler = async () => {
|
||||
</h3>
|
||||
</div>
|
||||
<br>
|
||||
<ModalComponent :isOpen="isModalOpened" @modal-close="closeModal" @submit="submitHandler" name="first-modal">
|
||||
<template #header>Share your creation on Nostr <br> <br></template>
|
||||
<div>
|
||||
<ModalComponent :isOpen="isModalOpened" @modal-close="closeModal" @submit="submitHandler" name="first-modal">
|
||||
<template #header>Summarize Results <br></template>
|
||||
<template #content>
|
||||
<textarea v-model="modalcontent" className="d-Input" style="height: 300px;">{{modalcontent}}</textarea>
|
||||
|
||||
<SummarizationGeneration :events="modalcontent"></SummarizationGeneration>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div>
|
||||
<!-- <div>
|
||||
<VueDatePicker :min-date="new Date()" :teleport="false" :dark="true" position="right" className="bg-base-200 inline-flex flex-none" style="width: 220px;" v-model="datetopost"></VueDatePicker>
|
||||
<button className="v-Button" @click="schedule(modalcontent)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px" src="../../public/shipyard.ico"/>Schedule Note with Shipyard DVM</button>
|
||||
<button className="v-Button" @click="schedule(modalcontent, datetopost)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px" src="../../public/shipyard.ico"/>Schedule Note with Shipyard DVM</button>
|
||||
<br>
|
||||
or
|
||||
<br>
|
||||
<button className="v-Button" style="margin-bottom: 0px" @click="post_note(modalcontent)" @click.stop="closeModal"><img width="25px" style="margin-right: 5px;" src="../../public/favicon.ico"/>Post Note now</button>
|
||||
</div>
|
||||
</div> -->
|
||||
</template>
|
||||
</ModalComponent>
|
||||
</div>
|
||||
|
||||
<div class=" relative space-y-3">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
@ -609,24 +437,19 @@ const submitHandler = async () => {
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <div v-if="dvm.result.length > 0 && store.state.pubkey.toHex() !== Keys.parse('ece3c0aa759c3e895ecb3c13ab3813c0f98430c6d4bd22160b9c2219efc9cf0e').publicKey.toHex()" >
|
||||
<button @click="openModal('Look what I created on noogle.lol\n\n' + dvm.result)" class="w-8 h-8 rounded-full bg-nostr border-white border-1 text-white flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black tooltip" data-top='Share' aria-label="make note" role="button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil" width="20" height="20" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"></path>
|
||||
<path d="M4 20h4l10.5 -10.5a1.5 1.5 0 0 0 -4 -4l-10.5 10.5v4"></path>
|
||||
<line x1="13.5" y1="6.5" x2="17.5" y2="10.5"></line>
|
||||
</svg>
|
||||
<div data-tip="Make Summarization" v-if="dvm.result.length > 0 && store.state.pubkey.toHex() !== Keys.parse('ece3c0aa759c3e895ecb3c13ab3813c0f98430c6d4bd22160b9c2219efc9cf0e').publicKey.toHex()" >
|
||||
<button @click="openModal(dvm.result)" class="w-8 h-8 rounded-full bg-nostr border-white border-1 text-white flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black tooltip" data-top='Share' aria-label="make note" role="button">
|
||||
<svg class="w-4 h-4 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M9 19V.352A3.451 3.451 0 0 0 7.5 0a3.5 3.5 0 0 0-3.261 2.238A3.5 3.5 0 0 0 2.04 6.015a3.518 3.518 0 0 0-.766 1.128c-.042.1-.064.209-.1.313a3.34 3.34 0 0 0-.106.344 3.463 3.463 0 0 0 .02 1.468A4.016 4.016 0 0 0 .3 10.5l-.015.036a3.861 3.861 0 0 0-.216.779A3.968 3.968 0 0 0 0 12a4.032 4.032 0 0 0 .107.889 4 4 0 0 0 .2.659c.006.014.015.027.021.041a3.85 3.85 0 0 0 .417.727c.105.146.219.284.342.415.072.076.148.146.225.216.1.091.205.179.315.26.11.081.2.14.308.2.02.013.039.028.059.04v.053a3.506 3.506 0 0 0 3.03 3.469 3.426 3.426 0 0 0 4.154.577A.972.972 0 0 1 9 19Zm10.934-7.68a3.956 3.956 0 0 0-.215-.779l-.017-.038a4.016 4.016 0 0 0-.79-1.235 3.417 3.417 0 0 0 .017-1.468 3.387 3.387 0 0 0-.1-.333c-.034-.108-.057-.22-.1-.324a3.517 3.517 0 0 0-.766-1.128 3.5 3.5 0 0 0-2.202-3.777A3.5 3.5 0 0 0 12.5 0a3.451 3.451 0 0 0-1.5.352V19a.972.972 0 0 1-.184.546 3.426 3.426 0 0 0 4.154-.577A3.506 3.506 0 0 0 18 15.5v-.049c.02-.012.039-.027.059-.04.106-.064.208-.13.308-.2s.214-.169.315-.26c.077-.07.153-.14.225-.216a4.007 4.007 0 0 0 .459-.588c.115-.176.215-.361.3-.554.006-.014.015-.027.021-.041.087-.213.156-.434.205-.659.013-.057.024-.115.035-.173.046-.237.07-.478.073-.72a3.948 3.948 0 0 0-.066-.68Z"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 v-if="dvms.length > 0" class="text-base-200-content text-center tracking-wide text-2xl font-thin ">
|
||||
There will be more algos coming soon..</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -28,12 +28,12 @@ import deadnip89s from "@/components/data/deadnip89s.json";
|
||||
import amberSignerService from "./android-signer/AndroidSigner";
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
import '@vuepic/vue-datepicker/dist/main.css'
|
||||
import {post_note, schedule, copyurl, copyinvoice, sleep, getEvents, get_user_infos, nextInput} from "../components/helper/Helper.vue"
|
||||
|
||||
|
||||
let items = []
|
||||
let profiles = []
|
||||
let dvms =[]
|
||||
let listener = false
|
||||
let searching = false
|
||||
|
||||
const message = ref("");
|
||||
const fromuser = ref("");
|
||||
@ -58,28 +58,6 @@ onMounted(async () => {
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(urlParams.has('search')); // true
|
||||
// console.log(urlParams.get('search')); // "MyParam"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async function send_search_request(msg) {
|
||||
try {
|
||||
if (msg === undefined){
|
||||
@ -172,15 +150,12 @@ async function send_search_request(msg) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("STORE: " +store.state.requestidSearch)
|
||||
store.commit('set_current_request_id_search', requestid)
|
||||
store.commit('set_current_request_profile_id_search', requestid_profile)
|
||||
console.log("STORE AFTER: " + store.state.requestidSearch)
|
||||
store.commit('set_current_request_profile_id_search', requestid_profile)
|
||||
|
||||
//miniToastr.showMessage("Sent Request to DVMs", "Awaiting results", VueNotifications.types.warn)
|
||||
if (!store.state.hasEventListener){
|
||||
listen()
|
||||
store.commit('set_hasEventListener', true)
|
||||
store.commit('set_hasEventListener', true)
|
||||
}
|
||||
else{
|
||||
console.log("Already has event listener")
|
||||
@ -191,38 +166,7 @@ async function send_search_request(msg) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function getEvents(eventids) {
|
||||
const event_filter = new Filter().ids(eventids)
|
||||
let client = store.state.client
|
||||
return await client.getEventsOf([event_filter], Duration.fromSecs(5))
|
||||
}
|
||||
|
||||
|
||||
async function get_user_infos(pubkeys){
|
||||
let profiles = []
|
||||
let client = store.state.client
|
||||
const profile_filter = new Filter().kind(0).authors(pubkeys)
|
||||
let evts = await client.getEventsOf([profile_filter], Duration.fromSecs(10))
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
//console.log(contentjson)
|
||||
profiles.push({profile: contentjson, author: entry.author.toHex(), createdAt: entry.createdAt});
|
||||
}
|
||||
catch(error){
|
||||
console.log("error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return profiles
|
||||
|
||||
}
|
||||
|
||||
async function listen() {
|
||||
listener = true
|
||||
let client = store.state.client
|
||||
let pubkey = store.state.pubkey
|
||||
let originale = [store.state.requestidSearch]
|
||||
@ -236,7 +180,6 @@ async function listen() {
|
||||
if (store.state.hasEventListener === false){
|
||||
return true
|
||||
}
|
||||
//const dvmname = getNamefromId(event.author.toHex())
|
||||
console.log("Received new event from", relayUrl);
|
||||
let resonsetorequest = false
|
||||
|
||||
@ -244,8 +187,6 @@ async function listen() {
|
||||
|
||||
for (let tag in event.tags) {
|
||||
if (event.tags[tag].asVec()[0] === "e") {
|
||||
//console.log("SEARCH ETAG: " + event.tags[tag].asVec()[1])
|
||||
// console.log("SEARCH LISTEN TO : " + store.state.requestidSearch)
|
||||
if (event.tags[tag].asVec()[1] === store.state.requestidSearch || event.tags[tag].asVec()[1] === store.state.requestidSearchProfile) {
|
||||
resonsetorequest = true
|
||||
}
|
||||
@ -259,8 +200,6 @@ async function listen() {
|
||||
try {
|
||||
console.log("7000: ", event.content);
|
||||
console.log("DVM: " + event.author.toHex())
|
||||
searching = false
|
||||
//miniToastr.showMessage("DVM: " + dvmname, event.content, VueNotifications.types.info)
|
||||
|
||||
let status = "unknown"
|
||||
let jsonentry = {
|
||||
@ -325,8 +264,6 @@ async function listen() {
|
||||
else if (event.kind === 6302) {
|
||||
let entries = []
|
||||
console.log("6302:", event.content);
|
||||
|
||||
//miniToastr.showMessage("DVM: " + dvmname, "Received Results", VueNotifications.types.success)
|
||||
try{
|
||||
let event_etags = JSON.parse(event.content)
|
||||
if (event_etags.length > 0) {
|
||||
@ -369,13 +306,10 @@ async function listen() {
|
||||
indicator: {"time": evt.createdAt.toHumanDatetime()}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const index = dvms.indexOf((dvms.find(i => i.id === event.author.toHex())));
|
||||
if (index > -1) {
|
||||
dvms.splice(index, 1);
|
||||
@ -387,7 +321,7 @@ async function listen() {
|
||||
}
|
||||
catch{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -395,7 +329,6 @@ async function listen() {
|
||||
let entries = []
|
||||
console.log("6303:", event.content);
|
||||
|
||||
//miniToastr.showMessage("DVM: " + dvmname, "Received Results", VueNotifications.types.success)
|
||||
let event_ptags = JSON.parse(event.content)
|
||||
let authors = []
|
||||
if (event_ptags.length > 0) {
|
||||
@ -408,11 +341,6 @@ async function listen() {
|
||||
|
||||
for (const profile of infos) {
|
||||
console.log(profile["author"])
|
||||
//let p = profiles.find(record => record.author === profile.author)
|
||||
|
||||
//‚let bech32id = PublicKey.parse(profile["profile"][]).toBech32() profile.author.toBech32()
|
||||
// let picture = profile === undefined ? "../assets/nostr-purple.svg" : profile["profile"]["picture"]
|
||||
// let name = profile === undefined ? bech32id : profile["profile"]["name"]
|
||||
if (profiles.findIndex(e => e.id === profile["author"]) === -1 && profile["profile"]["name"] !== "" ) {
|
||||
profiles.push({
|
||||
id: profile["author"],
|
||||
@ -422,8 +350,6 @@ async function listen() {
|
||||
avatar: profile["profile"]["picture"]
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,13 +384,6 @@ function getNamefromId(id){
|
||||
else return elements[0].name
|
||||
}
|
||||
|
||||
function nextInput(e) {
|
||||
const next = e.currentTarget.nextElementSibling;
|
||||
if (next) {
|
||||
next.focus();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function checkuser(msg){
|
||||
usernames = []
|
||||
@ -472,30 +391,19 @@ async function checkuser(msg){
|
||||
for (let profile of profiles){
|
||||
usernames.push(profile)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
async function get_user_from_search(name){
|
||||
name = "\"name\":" + name
|
||||
|
||||
if (store.state.dbclient.database === undefined){
|
||||
console.log("not logged in, not getting profile suggestions")
|
||||
return []
|
||||
}
|
||||
let dbclient = store.state.dbclient
|
||||
let dbclient = store.state.dbclient
|
||||
let profiles = []
|
||||
let filter1 = new Filter().kind(0).search(name)
|
||||
let evts = await dbclient.database.query([filter1])
|
||||
|
||||
|
||||
|
||||
//const profile_filter = new Filter().kind(0).search(name)
|
||||
//let evts = await client.getEventsOf([profile_filter], 3)
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
@ -505,11 +413,8 @@ async function get_user_from_search(name){
|
||||
catch(error){
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return profiles
|
||||
|
||||
}
|
||||
|
||||
defineProps({
|
||||
@ -519,12 +424,8 @@ defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
|
||||
<div class="greetings">
|
||||
@ -534,12 +435,8 @@ defineProps({
|
||||
<h2 class="text-base-200-content text-center tracking-wide text-2xl">
|
||||
Search the Nostr with Data Vending Machines</h2>
|
||||
<h3>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<input class="c-Input" type="search" name="s" autofocus placeholder="Search..." v-model="message" @keyup.enter="send_search_request(message)" @keydown.enter="nextInput">
|
||||
|
||||
|
||||
|
||||
<button class="v-Button" @click="send_search_request(message)">Search the Nostr</button>
|
||||
</h3>
|
||||
|
||||
@ -554,7 +451,6 @@ defineProps({
|
||||
|
||||
<datalist id="users">
|
||||
<option v-for="profile in usernames" :value="profile.author">
|
||||
|
||||
{{profile.profile.name + ' (' + profile.profile.nip05 + ')'}}
|
||||
|
||||
</option>
|
||||
@ -563,8 +459,7 @@ defineProps({
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="inline-flex flex-none" style="width: 20px;"></div>
|
||||
<div className="inline-flex flex-none" style="width: 20px;"></div>
|
||||
|
||||
<div>
|
||||
<h4 className="inline-flex flex-none font-thin">from:</h4>
|
||||
|
452
ui/noogle/src/components/SummarizationGeneration.vue
Normal file
452
ui/noogle/src/components/SummarizationGeneration.vue
Normal file
@ -0,0 +1,452 @@
|
||||
<script setup>
|
||||
|
||||
|
||||
import {
|
||||
Client,
|
||||
Filter,
|
||||
Timestamp,
|
||||
Event,
|
||||
Metadata,
|
||||
PublicKey,
|
||||
EventBuilder,
|
||||
Tag,
|
||||
EventId,
|
||||
Nip19Event, Alphabet, Keys, nip04_decrypt, SecretKey, Duration
|
||||
} from "@rust-nostr/nostr-sdk";
|
||||
import store from '../store';
|
||||
import miniToastr from "mini-toastr";
|
||||
import VueNotifications from "vue-notifications";
|
||||
import {computed, watch} from "vue";
|
||||
import deadnip89s from "@/components/data/deadnip89s.json";
|
||||
import {data} from "autoprefixer";
|
||||
import {requestProvider} from "webln";
|
||||
import Newnote from "@/components/Newnote.vue";
|
||||
import {post_note, schedule, copyurl, copyinvoice, sleep, nextInput} from "../components/helper/Helper.vue"
|
||||
import amberSignerService from "./android-signer/AndroidSigner";
|
||||
import { ref } from "vue";
|
||||
import ModalComponent from "../components/Newnote.vue";
|
||||
import VueDatePicker from "@vuepic/vue-datepicker";
|
||||
import {timestamp} from "@vueuse/core";
|
||||
import NoteTable from "@/components/NoteTable.vue";
|
||||
|
||||
let dvms =[]
|
||||
async function summarizefeed(eventids) {
|
||||
|
||||
try {
|
||||
if(store.state.pubkey === undefined || localStorage.getItem('nostr-key-method') === "anon"){
|
||||
miniToastr.showMessage("In order to receive personalized recommendations, sign-in first.", "Not signed in.", VueNotifications.types.warn)
|
||||
return
|
||||
}
|
||||
|
||||
dvms = []
|
||||
|
||||
store.commit('set_summarization_dvms', dvms)
|
||||
let client = store.state.client
|
||||
let content = "NIP 90 Content Discovery request"
|
||||
let kind = 5001
|
||||
|
||||
let tags = []
|
||||
for (const tag of eventids){
|
||||
try{
|
||||
tags.push(["i", tag.id.toHex(), "event"])
|
||||
}
|
||||
catch{}
|
||||
}
|
||||
|
||||
|
||||
let res;
|
||||
let requestid;
|
||||
|
||||
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
||||
let draft = {
|
||||
content: content,
|
||||
kind: kind,
|
||||
pubkey: store.state.pubkey.toHex(),
|
||||
tags: tags,
|
||||
createdAt: Date.now()
|
||||
};
|
||||
|
||||
res = await amberSignerService.signEvent(draft)
|
||||
await client.sendEvent(Event.fromJson(JSON.stringify(res)))
|
||||
requestid = res.id;
|
||||
}
|
||||
else {
|
||||
|
||||
let tags_t = []
|
||||
for (let tag of tags){
|
||||
tags_t.push(Tag.parse(tag))
|
||||
}
|
||||
let evt = new EventBuilder(kind, content, tags_t)
|
||||
res = await client.sendEventBuilder(evt);
|
||||
requestid = res.toHex();
|
||||
console.log(res)
|
||||
|
||||
|
||||
}
|
||||
|
||||
store.commit('set_current_request_id_summarization', requestid)
|
||||
if (!store.state.summarizationhasEventListener){
|
||||
listen()
|
||||
store.commit('set_summariarizationEventListener', true)
|
||||
}
|
||||
else{
|
||||
console.log("Already has event listener")
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function listen() {
|
||||
let client = store.state.client
|
||||
let pubkey = store.state.pubkey
|
||||
|
||||
const filter = new Filter().kinds([7000, 6001]).pubkey(pubkey).since(Timestamp.now());
|
||||
await client.subscribe([filter]);
|
||||
|
||||
const handle = {
|
||||
// Handle event
|
||||
handleEvent: async (relayUrl, event) => {
|
||||
if (store.state.summarizationhasEventListener === false){
|
||||
return true
|
||||
}
|
||||
//const dvmname = getNamefromId(event.author.toHex())
|
||||
console.log("Received new event from", relayUrl);
|
||||
console.log(event.asJson())
|
||||
let resonsetorequest = false
|
||||
sleep(1000).then(async () => {
|
||||
for (let tag in event.tags) {
|
||||
if (event.tags[tag].asVec()[0] === "e") {
|
||||
|
||||
if (event.tags[tag].asVec()[1] === store.state.requestidSummarization) {
|
||||
resonsetorequest = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (resonsetorequest === true) {
|
||||
if (event.kind === 7000) {
|
||||
|
||||
|
||||
try {
|
||||
console.log("7000: ", event.content);
|
||||
console.log("DVM: " + event.author.toHex())
|
||||
|
||||
let status = "unknown"
|
||||
let jsonentry = {
|
||||
id: event.author.toHex(),
|
||||
kind: "",
|
||||
status: status,
|
||||
result: [],
|
||||
name: event.author.toBech32(),
|
||||
about: "",
|
||||
image: "",
|
||||
amount: 0,
|
||||
bolt11: ""
|
||||
}
|
||||
|
||||
for (const tag in event.tags) {
|
||||
if (event.tags[tag].asVec()[0] === "status") {
|
||||
status = event.tags[tag].asVec()[1]
|
||||
}
|
||||
|
||||
if (event.tags[tag].asVec()[0] === "amount") {
|
||||
jsonentry.amount = event.tags[tag].asVec()[1]
|
||||
if (event.tags[tag].asVec().length > 2) {
|
||||
jsonentry.bolt11 = event.tags[tag].asVec()[2]
|
||||
}
|
||||
// TODO else request invoice
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//let dvm = store.state.nip89dvms.find(x => JSON.parse(x.event).pubkey === event.author.toHex())
|
||||
for (const el of store.state.nip89dvms) {
|
||||
if (JSON.parse(el.event).pubkey === event.author.toHex().toString()) {
|
||||
jsonentry.name = el.name
|
||||
jsonentry.about = el.about
|
||||
jsonentry.image = el.image
|
||||
|
||||
console.log(jsonentry)
|
||||
|
||||
}
|
||||
}
|
||||
if (dvms.filter(i => i.id === jsonentry.id).length === 0) {
|
||||
|
||||
dvms.push(jsonentry)
|
||||
}
|
||||
/*if (event.content !== ""){
|
||||
status = event.content
|
||||
}*/
|
||||
|
||||
dvms.find(i => i.id === jsonentry.id).status = status
|
||||
store.commit('set_summarization_dvms', dvms)
|
||||
|
||||
} catch (error) {
|
||||
console.log("Error: ", error);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
else if (event.kind === 6001){
|
||||
console.log(event.content)
|
||||
dvms.find(i => i.id === event.author.toHex()).result = event.content
|
||||
dvms.find(i => i.id === event.author.toHex()).status = "finished"
|
||||
store.commit('set_summarization_dvms', dvms)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// Handle relay message
|
||||
handleMsg: async (relayUrl, message) => {
|
||||
//console.log("Received message from", relayUrl, message.asJson());
|
||||
}
|
||||
};
|
||||
|
||||
client.handleNotifications(handle);
|
||||
}
|
||||
|
||||
|
||||
async function zap(invoice) {
|
||||
let webln;
|
||||
|
||||
//this.dvmpaymentaddr = `https://chart.googleapis.com/chart?cht=qr&chl=${invoice}&chs=250x250&chld=M|0`;
|
||||
//this.dvminvoice = invoice
|
||||
|
||||
|
||||
try {
|
||||
webln = await requestProvider();
|
||||
} catch (err) {
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
if (webln) {
|
||||
try{
|
||||
let response = await webln.sendPayment(invoice)
|
||||
dvms.find(i => i.bolt11 === invoice).status = "paid"
|
||||
store.commit('set_summarization_dvms', dvms)
|
||||
}
|
||||
catch(err){
|
||||
console.log(err)
|
||||
await copyinvoice(invoice)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
defineProps({
|
||||
events: {
|
||||
type: Array,
|
||||
required: false
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
const isModalOpened = ref(false);
|
||||
const modalcontent = ref("");
|
||||
const datetopost = ref(Date.now());
|
||||
|
||||
|
||||
const openModal = result => {
|
||||
datetopost.value = Date.now();
|
||||
isModalOpened.value = true;
|
||||
modalcontent.value = resevents
|
||||
};
|
||||
const closeModal = () => {
|
||||
isModalOpened.value = false;
|
||||
};
|
||||
|
||||
|
||||
const ttest = result => {
|
||||
|
||||
summarizefeed(result)
|
||||
}
|
||||
|
||||
const submitHandler = async () => {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<!-- font-thin bg-gradient-to-r from-white to-nostr bg-clip-text text-transparent -->
|
||||
|
||||
<template>
|
||||
|
||||
<div class="greetings">
|
||||
<h1 class="text-7xl font-black tracking-wide">Noogle</h1>
|
||||
<h3 class="text-7xl font-black tracking-wide">Summarization</h3>
|
||||
|
||||
<h3>
|
||||
<br>
|
||||
<button class="v-Button" @click="summarizefeed($props.events)">Summarize Results</button>
|
||||
</h3>
|
||||
|
||||
</div>
|
||||
<br>
|
||||
<div class="overflow-y-auto scrollbar w-full" style="max-height: 60pc">
|
||||
|
||||
|
||||
<div class=" relative space-y-3">
|
||||
<div class="grid grid-cols-1 gap-4 " >
|
||||
|
||||
<div className="card w-70 bg-base-100 shadow-xl" v-for="dvm in store.state.summarizationdvms"
|
||||
:key="dvm.id">
|
||||
|
||||
|
||||
|
||||
|
||||
<div className="card-body">
|
||||
|
||||
<div className="playeauthor-wrapper">
|
||||
<figure className="w-20">
|
||||
<img className="avatar" v-if="dvm.image" :src="dvm.image" alt="DVM Picture" />
|
||||
<img class="avatar" v-else src="@/assets/nostr-purple.svg" />
|
||||
</figure>
|
||||
|
||||
|
||||
<h2 className="card-title">{{ dvm.name }}</h2>
|
||||
</div>
|
||||
<h3 class="fa-cut" >{{ dvm.about }}</h3>
|
||||
|
||||
|
||||
|
||||
<div className="card-actions justify-end mt-auto" >
|
||||
|
||||
<div className="tooltip mt-auto" :data-tip="dvm.status">
|
||||
|
||||
|
||||
<button v-if="dvm.status !== 'finished' && dvm.status !== 'paid' && dvm.status !== 'payment-required' && dvm.status !== 'error'" className="btn">{{dvm.status}}</button>
|
||||
<button v-if="dvm.status === 'finished'" className="btn">Done</button>
|
||||
<button v-if="dvm.status === 'paid'" className="btn">Paid, waiting for DVM..</button>
|
||||
<button v-if="dvm.status === 'error'" className="btn">Error</button>
|
||||
<button v-if="dvm.status === 'payment-required'" className="zap-Button" @click="zap(dvm.bolt11);">{{ dvm.amount/1000 }} Sats</button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <div v-if="dvm.result.length > 0" class="collapse bg-base-200">
|
||||
<input type="checkbox" class="peer" />
|
||||
<div class="collapse-title bg-primary text-primary-content peer-checked:bg-secondary peer-checked:text-secondary-content">
|
||||
Click me to show/hide content
|
||||
</div>
|
||||
<div class="collapse-content bg-primary text-primary-content peer-checked:bg-base-200 peer-checked:text-accent">
|
||||
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<details v-if="dvm.status === 'finished'" class="collapse bg-base">
|
||||
<summary class="collapse-title "><div class="btn">Show/Hide Results</div></summary>
|
||||
<div class="collapse-content font-size-0" className="z-10" id="collapse">
|
||||
|
||||
<p>{{dvm.result}}</p>
|
||||
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.zap-Button{
|
||||
@apply btn hover:bg-amber-400 border-amber-400 text-base;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.v-Button {
|
||||
@apply bg-nostr hover:bg-nostr2 focus:ring-white mb-2 inline-flex flex-none items-center rounded-lg border border-black px-3 py-1.5 text-sm leading-4 text-white transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900;
|
||||
height: 48px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.c-Input {
|
||||
@apply bg-base-200 text-accent dark:bg-black dark:text-white focus:ring-white mb-2 inline-flex flex-none items-center rounded-lg border border-transparent px-3 py-1.5 text-sm leading-4 text-accent-content transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900;
|
||||
|
||||
width: 350px;
|
||||
height: 48px;
|
||||
|
||||
}
|
||||
|
||||
.d-Input {
|
||||
@apply bg-black hover:bg-gray-900 focus:ring-white mb-2 inline-flex flex-none items-center rounded-lg border border-transparent px-3 py-1.5 text-sm leading-4 text-white transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900;
|
||||
width: 300px;
|
||||
|
||||
color: white;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.playeauthor-wrapper {
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
width:100%;
|
||||
height:125px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.0rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.avatar {
|
||||
margin-right: 10px;
|
||||
margin-left: 0px;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
box-shadow: inset 0 4px 4px 0 rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.greetings h1,
|
||||
.greetings h3 {
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
|
||||
.greetings h1,
|
||||
.greetings h3 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
168
ui/noogle/src/components/helper/Helper.vue
Normal file
168
ui/noogle/src/components/helper/Helper.vue
Normal file
@ -0,0 +1,168 @@
|
||||
<script>
|
||||
import {defineComponent} from 'vue'
|
||||
import store from "@/store";
|
||||
import amberSignerService from "@/components/android-signer/AndroidSigner";
|
||||
import {Duration, Event, EventBuilder, Filter, PublicKey, Tag, Timestamp} from "@rust-nostr/nostr-sdk";
|
||||
import miniToastr from "mini-toastr/mini-toastr";
|
||||
import VueNotifications from "vue-notifications";
|
||||
|
||||
export default defineComponent({
|
||||
name: "posting"
|
||||
})
|
||||
|
||||
export async function post_note(note){
|
||||
let client = store.state.client
|
||||
let tags = []
|
||||
|
||||
if (localStorage.getItem('nostr-key-method') === 'android-signer') {
|
||||
const draft = {
|
||||
content: note,
|
||||
kind: 1,
|
||||
pubkey: store.state.pubkey.toHex(),
|
||||
tags: tags,
|
||||
createdAt: Date.now()
|
||||
};
|
||||
const eventJson = await amberSignerService.signEvent(draft);
|
||||
await client.sendEvent(Event.fromJson(JSON.stringify(eventJson)));
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.publishTextNote(note, tags);
|
||||
}
|
||||
}
|
||||
|
||||
export async function schedule(note, datetopost) {
|
||||
|
||||
|
||||
let schedule = Timestamp.fromSecs(datetopost/1000)
|
||||
let humandatetime = schedule.toHumanDatetime()
|
||||
let time = humandatetime.split("T")[1].split("Z")[0].trim()
|
||||
let date = humandatetime.split("T")[0].split("-")[2].trim() + "." + humandatetime.split("T")[0].split("-")[1].trim() + "." + humandatetime.split("T")[0].split("-")[0].trim().slice(2)
|
||||
|
||||
console.log("Date: " + date + " Time: "+ time )
|
||||
|
||||
let client = store.state.client
|
||||
let signer = store.state.signer
|
||||
|
||||
let noteevent = EventBuilder.textNote(note, []).customCreatedAt(schedule).toUnsignedEvent(store.state.pubkey)
|
||||
let signedEvent = await signer.signEvent(noteevent)
|
||||
|
||||
let stringifiedevent = signedEvent.asJson()
|
||||
|
||||
let tags_str = []
|
||||
let tag = Tag.parse(["i", stringifiedevent, "text"])
|
||||
tags_str.push(tag.asVec())
|
||||
let tags_as_str = JSON.stringify(tags_str)
|
||||
|
||||
|
||||
let content = await signer.nip04Encrypt(PublicKey.parse("85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"), tags_as_str)
|
||||
|
||||
let tags_t = []
|
||||
tags_t.push(Tag.parse(["p", "85c20d3760ef4e1976071a569fb363f4ff086ca907669fb95167cdc5305934d1"]))
|
||||
tags_t.push(Tag.parse(["encrypted"]))
|
||||
tags_t.push(Tag.parse(["client", "noogle"]))
|
||||
|
||||
|
||||
let evt = new EventBuilder(5905, content, tags_t)
|
||||
console.log(evt)
|
||||
let res = await client.sendEventBuilder(evt);
|
||||
console.log(res)
|
||||
miniToastr.showMessage("Note scheduled for " + ("Date: " + date + " Time: "+ time ))
|
||||
|
||||
|
||||
}
|
||||
|
||||
export async function getEvents(eventids) {
|
||||
const event_filter = new Filter().ids(eventids)
|
||||
let client = store.state.client
|
||||
return await client.getEventsOf([event_filter], Duration.fromSecs(5))
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function nextInput(e) {
|
||||
const next = e.currentTarget.nextElementSibling;
|
||||
if (next) {
|
||||
next.focus();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export async function get_user_infos(pubkeys){
|
||||
let profiles = []
|
||||
let client = store.state.client
|
||||
const profile_filter = new Filter().kind(0).authors(pubkeys)
|
||||
let evts = await client.getEventsOf([profile_filter], Duration.fromSecs(10))
|
||||
|
||||
for (const entry of evts){
|
||||
try{
|
||||
let contentjson = JSON.parse(entry.content)
|
||||
//console.log(contentjson)
|
||||
profiles.push({profile: contentjson, author: entry.author.toHex(), createdAt: entry.createdAt});
|
||||
}
|
||||
catch(error){
|
||||
console.log("error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return profiles
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const sleep = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
|
||||
export async function copyinvoice(invoice){
|
||||
await navigator.clipboard.writeText(invoice)
|
||||
window.open("lightning:" + invoice,"_blank")
|
||||
miniToastr.showMessage("", "Copied Invoice to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
export async function copyurl(url){
|
||||
await navigator.clipboard.writeText(url)
|
||||
miniToastr.showMessage("", "Copied link to clipboard", VueNotifications.types.info)
|
||||
}
|
||||
|
||||
|
||||
export async function createBolt11Lud16(lud16, amount) {
|
||||
let url;
|
||||
if (lud16.includes('@')) { // LNaddress
|
||||
const parts = lud16.split('@');
|
||||
url = `https://${parts[1]}/.well-known/lnurlp/${parts[0]}`;
|
||||
} else { // No lud16 set or format invalid
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(url);
|
||||
const response = await fetch(url);
|
||||
const ob = await response.json();
|
||||
const callback = ob.callback;
|
||||
const amountInSats = parseInt(amount) * 1000;
|
||||
const callbackResponse = await fetch(`${callback}?amount=${amountInSats}`);
|
||||
const obCallback = await callbackResponse.json();
|
||||
return obCallback.pr;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(`LUD16: ${e}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user