Browse Source

lightning and likes working, not DRY:needs work

feature/likes-and-lightning
dskvr 2 years ago
parent
commit
d864421625
  1. 68
      src/components/relays/blocks/RelaysResultTable.vue
  2. 44
      src/components/relays/tasks/RefreshTask.vue
  3. 60
      src/components/relays/tasks/RelayOperatorTask.vue
  4. 12
      src/components/relays/tasks/TasksManager.vue
  5. 3
      src/main.js
  6. 51
      src/store/profiles.js
  7. 1
      src/store/relays.js
  8. 10
      src/store/user.js

68
src/components/relays/blocks/RelaysResultTable.vue

@ -27,10 +27,15 @@
</label>
</span>
</th>
<!-- <th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0" v-if="isLoggedIn()">
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0">
<code class="text-xs block">Favorite</code>
</th>
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0" v-if="isLoggedIn()">
<code class="text-xs block">Upvote</code>
</th> -->
</th>
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0" v-if="isLoggedIn()">
<code class="text-xs block">LN</code>
</th>
<th scope="col" class="hidden md:table-cell lg:table-cell xl:table-cell verified">
<!-- <span class="verified-shape-wrapper">
<span class="shape verified"></span>
@ -57,9 +62,6 @@
<code class="text-xs block">Write</code>
<!-- -->
</th>
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0">
<code class="text-xs block">Favorite</code>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
@ -78,13 +80,40 @@
<a :href="`/relay/${relayClean(relay)}`">{{ relay.replace('wss://', '') }}</a>
</td>
<!-- <td class="w-16 fav text-center" v-if="isLoggedIn()">
<td class="w-16 fav text-center">
<a
class=" hover:opacity-100 cursor-pointer opacity-20"
class="hover:opacity-100 cursor-pointer"
:class="store.relays.isFavorite(relay) ? 'opacity-100' : 'opacity-10'"
@click="store.relays.toggleFavorite(relay)">
</a>
</td>
<td class="w-16 fav text-center" v-if="isLoggedIn()">
<a
v-if="store.relays.hasCanonical(relay)"
class="hover:opacity-100 cursor-pointer "
:class="{
'opacity-20': !store.user.isLiked(relay),
'opacity-100': store.user.isLiked(relay)
}"
@click="likeRelay(relay)">
👍
</a>
</td> -->
</td>
<td class="w-16 fav text-center" v-if="isLoggedIn()">
<a
v-if="results[relay]?.info?.pubkey && store.profile.hasProfile(results[relay]?.info?.pubkey) && store.profile.hasLud06(results[relay]?.info?.pubkey)"
class="block hover:opacity-100 cursor-pointer opacity-20"
:href="`lightning:${store.profile.getLud06(results[relay]?.info?.pubkey)}`">
<center> <!--when a deprecated element is the only thing that works, the internet is broken.-->
<svg className="h-6 w-6 block w-auto" preserveAspectRatio="xMidYMin" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
<path d="M11.983 1.907a.75.75 0 00-1.292-.657l-8.5 9.5A.75.75 0 002.75 12h6.572l-1.305 6.093a.75.75 0 001.292.657l8.5-9.5A.75.75 0 0017.25 8h-6.572l1.305-6.093z" />
</svg>
</center>
</a>
</td>
<td class="w-12 verified text-center md:table-cell lg:table-cell xl:table-cell">
<span v-if="this.results[relay]?.identities">
@ -119,14 +148,6 @@
<span class="m-auto block" :class="getCheckIndicator(relay, 'write')">&nbsp;</span>
</td>
<td class="w-16 fav text-center">
<a
class="hover:opacity-100 cursor-pointer"
:class="store.relays.isFavorite(relay) ? 'opacity-100' : 'opacity-10'"
@click="store.relays.toggleFavorite(relay)">
</a>
</td>
</tr>
</tbody>
@ -159,17 +180,18 @@
const localMethods = {
async likeRelay(relay){
const like = !this.store.user.isLiked(relay)
const id = this.store.relays.getCanonical(relay)
const event = {
created_at: Math.floor(Date.now()/1000),
kind: 7,
content: '+',
tags: [
['e', id],
['p', this.store.user.getPublicKey]
],
pubkey: this.store.user.getPublicKey
}
event.content = like ? '+' : '-'
event.id = getEventHash(event)
console.log('like event', event)
@ -178,7 +200,15 @@
let ok = validateEvent(signedEvent)
let veryOk = await verifySignature(signedEvent)
console.log('valid event?', ok, veryOk)
if(!ok || !veryOk)
return
this.$pool.send(['EVENT', signedEvent])
if(like)
this.store.user.like(relay)
else
this.store.user.unlike(relay)
},
}

44
src/components/relays/tasks/RefreshTask.vue

@ -1,29 +1,31 @@
<template>
<span
v-if="!store.tasks.isActive || store.tasks.getActiveSlug === this.taskSlug"
class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs">
<span v-if="!store.tasks.isProcessing(this.taskSlug)">Checked {{ sinceLast }} ago</span>
<span v-if="store.tasks.isProcessing(this.taskSlug)" class="italic lg:pr-9">
<svg class="animate-spin mr-1 -mt-0.5 h-4 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
{{ this.store.tasks.getProcessed(this.taskSlug).length }}/{{ this.relays.length }} Relays Checked
class="inline-block mt-0.5">
<span
class="text-white lg:text-sm mr-2 ml-2 text-xs">
<span v-if="!store.tasks.isProcessing(this.taskSlug)">Checked {{ sinceLast }} ago</span>
<span v-if="store.tasks.isProcessing(this.taskSlug)" class="italic lg:pr-9">
<svg class="animate-spin mr-1 -mt-0.5 h-4 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
{{ this.store.tasks.getProcessed(this.taskSlug).length }}/{{ this.relays.length }} Relays Checked
</span>
</span>
<span class="text-white text-sm mr-2" v-if="!store.tasks.isProcessing(this.taskSlug)">-</span>
<span class="text-white text-sm mr-2" v-if="store.prefs.refresh && !store.tasks.isProcessing(this.taskSlug)">
Next check in: {{ untilNext }}
</span>
<button
v-if="!store.tasks.isProcessing(this.taskSlug)"
class="mr-8 my-1 py-0 px-3 text-xs rounded border-b-3 border-slate-700 bg-slate-500 font-bold text-white hover:border-slate-500 hover:bg-slate-400"
:disabled='store.tasks.isProcessing(this.taskSlug)'
@click="refreshNow()">
Check{{ relay ? ` ${relay}` : "" }} Now
</button>
</span>
<span class="text-white text-sm mr-2 mt-1.5" v-if="!store.tasks.isProcessing(this.taskSlug)">-</span>
<span class="text-white text-sm mr-2 mt-1.5" v-if="store.prefs.refresh && !store.tasks.isProcessing(this.taskSlug)">
Next check in: {{ untilNext }}
</span>
<button
v-if="!store.tasks.isProcessing(this.taskSlug)"
class="mr-8 my-1 py-0 px-3 text-xs rounded border-b-3 border-slate-700 bg-slate-500 font-bold text-white hover:border-slate-500 hover:bg-slate-400"
:disabled='store.tasks.isProcessing(this.taskSlug)'
@click="refreshNow()">
Check{{ relay ? ` ${relay}` : "" }} Now
</button>
</template>
<style scoped>

60
src/components/relays/tasks/RelayOperatorTask.vue

@ -41,7 +41,12 @@ const localMethods = {
() => {
const relays = this.store.relays.getAggregateCache('public')
console.log('public relays', this.store.relays.getAggregateCache('public').length)
if( !relays.length ){
this.store.tasks.completeJob()
return
}
// console.log('public relays', this.store.relays.getAggregateCache('public').length)
const pool = new RelayPool(relays)
const subid = crypto.randomBytes(40).toString('hex')
@ -51,42 +56,60 @@ const localMethods = {
7: new Set(),
}
const limits = {
0: 1,
1: 20,
7: 100
}
// const limits = {
// 0: 1,
// 1: 20,
// 7: 100
// }
// const kinds = [0,1,7]
const kinds = [0]
const pubkeys = new Set()
Object.keys(this.results).forEach( relayKey => {
const result = this.results[relayKey]
const pubkey = result?.info?.pubkey
if(!pubkey)
return
pubkeys.add(pubkey)
})
const kinds = [0,1,7]
//remove kind 1 for non-single page tasks
pool
.on('open', relay => {
relay.subscribe(subid, { limit:10, kinds:kinds, authors:[this.result.info.pubkey] })
console.log('subscribing', Array.from(pubkeys) )
relay.subscribe(subid, { limit:pubkeys.size, kinds:kinds, authors: Array.from(pubkeys) })
})
.on('event', (relay, sub_id, event) => {
console.log(event)
if(!kinds.includes(event.kind))
return
if(sub_id !== subid)
return
const u = uniques[event.kind],
l = limits[event.kind]
if( u.has(event.id) || u.size > l )
const u = uniques[event.kind]
// l = limits[event.kind]
if( u.has(event.id) )
return
if( !(event instanceof Object) )
return
if( !( this.events[event.kind] instanceof Object ))
this.events[event.kind] = new Object()
this.events[event.kind][event.id] = event
this.store.profile.setProfile(event.pubkey, JSON.parse(event.content))
u.add(event.id)
if(event.kind === 0)
this.store.profile.setProfile(JSON.parse(event.content)).catch()
console.log(`kind: ${event.kind} found`, '... total', u.size, Object.keys(this.events[event.kind]).length)
console.log( 'event!', event.content )
})
this.store.tasks.completeJob()
setTimeout( () => {
pool.unsubscribe()
pool.close()
this.store.tasks.completeJob()
}, 10000 )
// .on('eose', relay => {
// relay.close()
// })
@ -107,7 +130,8 @@ export default defineComponent({
components: {},
data() {
return {
taskSlug: 'relays/operatorprofiles'
taskSlug: 'relays/operatorprofiles',
events: {}
}
},
setup(props){

12
src/components/relays/tasks/TasksManager.vue

@ -1,10 +1,10 @@
<template>
<RefreshTask
v-bind:resultsProp="results" />
<!-- <RelayCanonicalsTask
<RelayCanonicalsTask
:resultsProp="results" />
<RelayOperatorTask
:resultsProp="results" /> -->
:resultsProp="results" />
</template>
<script>
@ -16,15 +16,15 @@ import { setupStore } from '@/store'
import SharedComputed from '@/shared/computed.js'
import RefreshTask from './RefreshTask.vue'
// import RelayCanonicalsTask from './RelayCanonicalsTask.vue'
// import RelayOperatorTask from './RelayOperatorTask.vue'
import RelayCanonicalsTask from './RelayCanonicalsTask.vue'
import RelayOperatorTask from './RelayOperatorTask.vue'
export default defineComponent({
name: "TasksManager",
components: {
RefreshTask,
// RelayCanonicalsTask,
// RelayOperatorTask
RelayCanonicalsTask,
RelayOperatorTask
},
data(){
return {

3
src/main.js

@ -29,7 +29,8 @@ app.config.globalProperties.$tabId = crypto.randomBytes(40).toString('hex')
app.config.globalProperties.$filters = []
// app.config.globalProperties.$pool = new RelayPool(relays, {reconnect: false})
app.config.globalProperties.$pool = new RelayPool(['wss://relay.nostr.ch'])
app.config.globalProperties.$pool = new RelayPool(['wss://nostr.sandwich.farm'])
app.config.globalProperties.$pool.on('ok', () => console.log('ok') )
await router.isReady()

51
src/store/profiles.js

@ -1,23 +1,34 @@
import { defineStore } from 'pinia'
export const useProfileStore = defineStore('profiles', {
state: () => ({
name: new String(),
about: new String(),
picture: new String(),
nip05: new String(),
lud06: new String(),
}),
getters: {},
actions: {
setProfile(profile){
Object.keys(profile).forEach( key => {
if( !(profile[key] instanceof String) )
return
if( !(this[key] instanceof String) )
return
this[key] = profile[key]
})
export const useProfileStore = defineStore(
'profiles',
{
state: () => ({
data: new Object()
}),
getters: {
getProfiles: (state) => state.data,
hasProfile: state => pubkey => typeof state.data[pubkey] !== 'undefined',
hasLud06: state => pubkey => typeof state.data[pubkey] !== 'undefined' && typeof state.data[pubkey].lud06 !== 'undefined',
getProfile: state => pubkey => state.data[pubkey],
getLud06: state => pubkey => state.data[pubkey]?.lud06,
getPicture: state => pubkey => state.data[pubkey]?.picture,
getName: state => pubkey => state.data[pubkey]?.name,
getNip05: state => pubkey => state.data[pubkey]?.nip05,
},
},
})
actions: {
setProfile(pubkey, profile){
console.log('setting ', pubkey, profile)
if( !(this.data[pubkey] instanceof Object) )
this.data[pubkey] = new Object()
Object.keys(profile).forEach( key => {
// if( !(profile[key] instanceof String) )
// return
console.log('setting profile', key, profile[key])
this.data[pubkey][key] = profile[key]
})
},
},
}
)

1
src/store/relays.js

@ -51,6 +51,7 @@ export const useRelaysStore = defineStore('relays', {
getCanonicals: state => state.canonicals,
getCanonical: state => relay => state.canonicals[relay],
hasCanonical: state => relay => typeof state.canonicals[relay] !== 'undefined',
},
actions: {
addRelay(relayUrl){ this.urls.push(relayUrl) },

10
src/store/user.js

@ -5,7 +5,8 @@ export const useUserStore = defineStore('user', {
pubKey: "",
events: [],
profile: {},
testEvent: false
testEvent: false,
likes: {}
}),
getters: {
getPublicKey: (state) => state.pubKey,
@ -14,9 +15,14 @@ export const useUserStore = defineStore('user', {
getPicture: (state) => state.profile.picture,
getNip05: (state) => state.profile.nip05,
isProfile: (state) => Object.keys(state.profile).length ? true : false,
getTestEvent: (state) => state.testEvent
getTestEvent: (state) => state.testEvent,
getLikes: state => state.likes,
isLiked: state => relay => state.likes[relay]
},
actions: {
unlike: function(relay){ this.likes[relay] = false },
like: function(relay){ this.likes[relay] = true },
setPublicKey: function(pubKey){ this.pubKey = pubKey },
setProfile: function(stringifiedEvContent){
this.profile = JSON.parse(stringifiedEvContent)

Loading…
Cancel
Save