From 3c66a500462ed04d116049a631919453cce4bf0b Mon Sep 17 00:00:00 2001 From: styppo Date: Mon, 9 Jan 2023 22:24:24 +0000 Subject: [PATCH] Basic Profile page --- .../CreatePost/CreatePostDialog.vue | 1 + src/components/MainMenu/MainMenu.vue | 6 +- src/components/PageHeader.vue | 2 +- src/components/User/LogoutDialog.vue | 24 ++++-- src/components/User/UserAvatar.vue | 8 +- src/components/User/UserCard.vue | 36 +++++++++ src/components/User/UserName.vue | 19 ++--- src/nostr/Account.js | 34 ++++++++ src/nostr/FetchQueue.js | 4 +- src/nostr/NostrStore.js | 72 +++++++++++++---- src/nostr/Relay.js | 2 +- src/nostr/store/ContactStore.js | 66 +++++++++++++++ src/pages/Feed.vue | 44 +++++----- src/pages/Profile.vue | 81 ++++++++++++++++++- src/stores/Settings.js | 46 +++-------- 15 files changed, 347 insertions(+), 98 deletions(-) create mode 100644 src/components/User/UserCard.vue create mode 100644 src/nostr/Account.js create mode 100644 src/nostr/store/ContactStore.js diff --git a/src/components/CreatePost/CreatePostDialog.vue b/src/components/CreatePost/CreatePostDialog.vue index 4caffab..43fad02 100644 --- a/src/components/CreatePost/CreatePostDialog.vue +++ b/src/components/CreatePost/CreatePostDialog.vue @@ -83,6 +83,7 @@ export default { .create-post-dialog { position: relative; background-color: $color-bg; + box-shadow: $shadow-white; padding: 3rem 1rem 1rem; min-width: 660px; .icon { diff --git a/src/components/MainMenu/MainMenu.vue b/src/components/MainMenu/MainMenu.vue index 39a079c..28c1ae8 100644 --- a/src/components/MainMenu/MainMenu.vue +++ b/src/components/MainMenu/MainMenu.vue @@ -20,7 +20,7 @@ @@ -71,6 +71,7 @@ import ProfilePopup from 'components/MainMenu/ProfilePopup' import Logo from 'components/Logo.vue' import {useAppStore} from 'stores/App' import {MENU_ITEMS} from 'components/MainMenu/constants.js' +import {hexToBech32} from 'src/utils/utils' export default { name: 'MainMenu', @@ -105,7 +106,8 @@ export default { signIn() { this.$emit('mobile-menu-close') this.app.signIn() - } + }, + hexToBech32 } } diff --git a/src/components/PageHeader.vue b/src/components/PageHeader.vue index 30721a1..27ff02b 100644 --- a/src/components/PageHeader.vue +++ b/src/components/PageHeader.vue @@ -48,7 +48,7 @@ export default defineComponent({ methods: { titleFromRoute() { const route = this.$route.name?.toLowerCase() - return route.charAt(0).toUpperCase() + route.substring(1) + return route?.charAt(0).toUpperCase() + route?.substring(1) } } }) diff --git a/src/components/User/LogoutDialog.vue b/src/components/User/LogoutDialog.vue index 8370db4..00fa862 100644 --- a/src/components/User/LogoutDialog.vue +++ b/src/components/User/LogoutDialog.vue @@ -1,6 +1,8 @@ @@ -44,6 +79,7 @@ import PageHeader from 'components/PageHeader.vue' import UserAvatar from 'components/User/UserAvatar.vue' import UserName from 'components/User/UserName.vue' import ListPost from 'components/Post/ListPost.vue' +import UserCard from 'components/User/UserCard.vue' import {useAppStore} from 'stores/App' import {useNostrStore} from 'src/nostr/NostrStore' import {bech32ToHex} from 'src/utils/utils' @@ -51,6 +87,7 @@ import {bech32ToHex} from 'src/utils/utils' export default defineComponent({ name: 'Profile', components: { + UserCard, PageHeader, UserAvatar, UserName, @@ -71,12 +108,28 @@ export default defineComponent({ pubkey() { return bech32ToHex(this.$route.params.pubkey) }, - posts() { + profile() { + return this.nostr.getProfile(this.pubkey) + }, + notes() { return this.nostr.getNotesByAuthor(this.pubkey) }, + posts() { + return this.notes.filter(note => !note.isReply()) + }, + replies() { + return this.notes.filter(note => note.isReply()) + }, + contacts() { + return this.nostr.getContacts(this.pubkey) + }, + followers() { + return this.nostr.getFollowers(this.pubkey) + }, }, mounted() { this.nostr.fetchNotesByAuthor(this.pubkey) + this.nostr.fetchFollowers(this.pubkey) } }) @@ -85,9 +138,29 @@ export default defineComponent({ .profile { &-header { display: flex; + padding: 1rem; + &-avatar { + height: 128px; + width: 128px; + margin-right: 1rem; + } + &-content { + .followers { + span + span { + margin-left: 1rem; + } + } + } } &-tab-panels { background-color: unset; } } + diff --git a/src/stores/Settings.js b/src/stores/Settings.js index b368650..bcbbead 100644 --- a/src/stores/Settings.js +++ b/src/stores/Settings.js @@ -1,44 +1,22 @@ import {defineStore} from 'pinia' -import {getEventHash, getPublicKey, signEvent} from 'nostr-tools' -import Nip07 from 'src/utils/Nip07' +import {Account} from 'src/nostr/Account' -export class Account { - constructor(opts) { - this.pubkey = opts.pubkey || null - this.privkey = opts.privkey || null - this.useExtension = opts.useExtension || false - - if (this.privkey && !this.pubkey) { - this.pubkey = getPublicKey(this.privkey) - } - - if (!this.pubkey) throw new Error('pubkey is required') - } - - canSign() { - return !!this.privkey || (this.useExtension && Nip07.isAvailable()) - } - - async sign(event) { - event.id = getEventHash(event) - if (this.privkey) { - event.sig = signEvent(event, this.privkey) - } else if (this.useExtension && Nip07.isAvailable()) { - let {sig} = await Nip07.signEvent(event) - event.sig = sig - } else { - // TODO - throw new Error('cannot sign') - } - return event - } -} +const RELAYS = [ + 'wss://nostr-pub.wellorder.net', + 'wss://nostr.onsats.org', + 'wss://nostr-relay.wlvs.space', + 'wss://nostr.bitcoiner.social', + 'wss://relay.damus.io', + 'wss://nostr.zebedee.cloud', + 'wss://relay.nostr.info', + 'wss://nostr-pub.semisol.dev', +] export const useSettingsStore = defineStore('settings', { state: () => ({ accounts: {}, pubkey: null, - relays: [] + relays: RELAYS, }), getters: { activeAccount(state) {