Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show picture events #1543

Merged
merged 3 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions web/src/lib/EventHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,7 @@ export function getZapperPubkey(event: Event): string | undefined {
export function isNostrHex(hex: string): boolean {
return /[0-9a-f]{64}/.test(hex);
}

export function getTitle(tags: string[][]): string | undefined {
return filterTags('title', tags).at(0);
}
4 changes: 2 additions & 2 deletions web/src/lib/List.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createRxOneshotReq, latest } from 'rx-nostr';
import { lastValueFrom } from 'rxjs';
import type { Event } from 'nostr-typedef';
import { rxNostr } from './timelines/MainTimeline';
import { filterTags, findIdentifier } from './EventHelper';
import { filterTags, findIdentifier, getTitle } from './EventHelper';
import { parsePrivateTags } from './Encryption';
import { pubkey } from './stores/Author';
import { Signer } from './Signer';
Expand All @@ -26,7 +26,7 @@ export async function fetchListEvent(
}

export function getListTitle(tags: string[][]): string {
return filterTags('title', tags).at(0) ?? findIdentifier(tags) ?? '-';
return getTitle(tags) ?? findIdentifier(tags) ?? '-';
}

export async function getListPubkeys(event: Event): Promise<string[]> {
Expand Down
155 changes: 155 additions & 0 deletions web/src/lib/components/actions/ActionMenu.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<script lang="ts">
import type { EventItem, Item } from '$lib/Items';
import { nip19 } from 'nostr-tools';
import MenuButton from '../MenuButton.svelte';
import { metadataStore } from '$lib/cache/Events';
import { getCodePoints } from '$lib/String';
import IconMessageCircle from '@tabler/icons-svelte/icons/message-circle';
import IconBolt from '@tabler/icons-svelte/icons/bolt';
import RepostButton from '../RepostButton.svelte';
import ReactionButton from '../ReactionButton.svelte';
import EmojiPicker from '../EmojiPicker.svelte';
import ZapDialog from '../ZapDialog.svelte';
import { sendReaction } from '$lib/author/Reaction';
import type { Event } from 'nostr-typedef';
import { notesKinds } from '$lib/Constants';
import { openNoteDialog, replyTo } from '$lib/stores/NoteDialog';
import { rom } from '$lib/stores/Author';

export let item: EventItem;

let zapped = false;
let jsonDisplay = false;
let zapDialogComponent: ZapDialog;

const iconSize = 20;

$: metadata = $metadataStore.get(item.event.pubkey);

function reply(item: Item) {
$replyTo = item as EventItem;
$openNoteDialog = true;
}

async function emojiReaction(note: Event, emoji: any) {
console.log('[reaction with emoji]', note, emoji);

if ($rom) {
console.error('Readonly');
return;
}

const content =
emoji.native ??
(emoji.shortcodes ? emoji.shortcodes : `:${emoji.id.replaceAll('+', '_')}:`);
const emojiUrl =
emoji.native === undefined && emoji.src !== undefined ? emoji.src : undefined;
sendReaction(note, content, emojiUrl);
}

function onZapped() {
zapped = true;
}
</script>

<div class="action-menu">
<button class:hidden={!notesKinds.includes(item.event.kind)} on:click={() => reply(item)}>
<IconMessageCircle size={iconSize} />
</button>
<RepostButton event={item.event} {iconSize} />
<ReactionButton event={item.event} {iconSize} />
<span>
<EmojiPicker on:pick={({ detail }) => emojiReaction(item.event, detail)} />
</span>
<button
class="zap"
class:hidden={!metadata?.canZap}
disabled={zapped}
on:click={() => zapDialogComponent.openZapDialog()}
>
<IconBolt size={iconSize} />
</button>
<ZapDialog
pubkey={item.event.pubkey}
event={item.event}
bind:this={zapDialogComponent}
on:zapped={onZapped}
/>
<MenuButton event={item.event} {iconSize} bind:showDetails={jsonDisplay} />
</div>
{#if jsonDisplay}
<div class="develop">
<h5>Event ID</h5>
<div>{nip19.noteEncode(item.event.id)}</div>
<br />
<div>{nip19.neventEncode({ id: item.event.id })}</div>
<h5>Event JSON</h5>
<code>{JSON.stringify(item.event, null, 2)}</code>
<h5>User ID</h5>
<div>{nip19.npubEncode(item.event.pubkey)}</div>
<h5>User JSON</h5>
<code>{JSON.stringify(metadata?.content, null, 2)}</code>
<h5>Code Points</h5>
<h6>display name</h6>
<p>
{getCodePoints(metadata?.content?.display_name ?? '')
.map((codePoint) => `0x${codePoint.toString(16)}`)
.join(' ')}
</p>
<h6>@name</h6>
<p>
{getCodePoints(metadata?.content?.name ?? '')
.map((codePoint) => `0x${codePoint.toString(16)}`)
.join(' ')}
</p>
<h6>content</h6>
<p>
{getCodePoints(item.event.content)
.map((codePoint) => `0x${codePoint.toString(16)}`)
.join(' ')}
</p>
<div>
Open in <a
href="https://koteitan.github.io/nostr-post-checker/?hideform&eid={nip19.neventEncode(
{ id: item.event.id }
)}&kind={item.event.kind}"
target="_blank"
rel="noopener noreferrer"
>
nostr-post-checker
</a>
</div>
</div>
{/if}

<style>
.develop {
cursor: default;
background-color: var(--surface);
}

.action-menu {
display: flex;
justify-content: space-between;

margin-top: 8px;
}

.action-menu button {
border: none;
background-color: inherit;
cursor: pointer;
outline: none;
padding: 0;
height: 20px;
color: var(--accent-gray);
}

.action-menu button.hidden {
visibility: hidden;
}

.zap:disabled {
color: #f59f00;
}
</style>
11 changes: 11 additions & 0 deletions web/src/lib/components/content/Imeta.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import Img from './Img.svelte';

export let tag: string[];

$: url = tag.at(1)?.split(' ').at(1) ?? '';
</script>

{#if URL.canParse(url)}
<Img url={new URL(url)} />
{/if}
3 changes: 3 additions & 0 deletions web/src/lib/components/items/EventComponent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import BadgeDefinition from './BadgeDefinition.svelte';
import List from './List.svelte';
import LegacyDirectMessage from './LegacyDirectMessage.svelte';
import Picture from './Picture.svelte';

export let item: Item;
export let readonly: boolean;
Expand All @@ -32,6 +33,8 @@
<Reaction {item} {readonly} {createdAtFormat} />
{:else if item.event.kind === Kind.BadgeAward}
<BadgeAward {item} {readonly} {createdAtFormat} />
{:else if Number(item.event.kind) === 20}
<Picture {item} {readonly} {createdAtFormat} />
{:else if item.event.kind === Kind.ChannelCreation || item.event.kind === Kind.ChannelMetadata}
<Channel {item} />
{:else if item.event.kind === Kind.Article}
Expand Down
Loading