Show published note content inline on Home screen

This commit is contained in:
Avi 2026-09-01 13:06:33 -05:00
commit cd5d2d7fd1
7 changed files with 36 additions and 34 deletions

View file

@ -71,7 +71,7 @@ function Shell() {
)} )}
{screen === 'feed' && <FeedScreen onNavigate={setScreen} />} {screen === 'feed' && <FeedScreen onNavigate={setScreen} />}
{screen === 'profiles' && <ProfilesScreen onCreateProfile={() => setCreateOpen(true)} />} {screen === 'profiles' && <ProfilesScreen onCreateProfile={() => setCreateOpen(true)} />}
{screen === 'compose' && <ComposeScreen onNavigate={setScreen} />} {screen === 'compose' && <ComposeScreen />}
{screen === 'relays' && <RelaysScreen />} {screen === 'relays' && <RelaysScreen />}
{screen === 'signer' && <SignerScreen />} {screen === 'signer' && <SignerScreen />}
{screen === 'settings' && <SettingsScreen />} {screen === 'settings' && <SettingsScreen />}

View file

@ -66,6 +66,8 @@ export interface PublishReport {
event_id: string; event_id: string;
succeeded: string[]; succeeded: string[];
failed: RelayFailure[]; failed: RelayFailure[];
/** The note content that was published. */
content?: string;
} }
/** Per-relay outcome of publishing a profile's name as kind 0 metadata. */ /** Per-relay outcome of publishing a profile's name as kind 0 metadata. */
@ -145,6 +147,7 @@ export interface AppState {
event_id: string; event_id: string;
succeeded: string[]; succeeded: string[];
failed: RelayFailure[]; failed: RelayFailure[];
content: string;
} | null; } | null;
} }

View file

@ -9,7 +9,6 @@ import { Modal } from '../components/Modal';
import { shortenNpub } from '../lib/format'; import { shortenNpub } from '../lib/format';
import { extractImageUrls, extractLinkUrls } from '../lib/media'; import { extractImageUrls, extractLinkUrls } from '../lib/media';
import type { LinkPreview } from '../lib/types'; import type { LinkPreview } from '../lib/types';
import type { Screen } from '../lib/navigation';
import { useApp } from '../state/AppProvider'; import { useApp } from '../state/AppProvider';
const SOFT_LIMIT = 10_000; const SOFT_LIMIT = 10_000;
@ -33,11 +32,7 @@ function buildContent(content: string, attachments: Attachment[]): string {
return parts.join('\n'); return parts.join('\n');
} }
interface ComposeScreenProps { export function ComposeScreen() {
onNavigate?: (screen: Screen) => void;
}
export function ComposeScreen({ onNavigate }: ComposeScreenProps) {
const { const {
state, state,
publishNote, publishNote,
@ -369,12 +364,6 @@ export function ComposeScreen({ onNavigate }: ComposeScreenProps) {
{shortenNpub(lastReport.event_id, true)} {shortenNpub(lastReport.event_id, true)}
</span> </span>
<CopyButton text={lastReport.event_id} label="event ID" /> <CopyButton text={lastReport.event_id} label="event ID" />
{onNavigate && (
<Button variant="ghost" size="sm" onClick={() => onNavigate('feed')}>
<Icon name="list" size={16} />
View in Feed
</Button>
)}
{lastReport.failed.length > 0 && ( {lastReport.failed.length > 0 && (
<details className="alert-details"> <details className="alert-details">
<summary>Relays that didn't accept it</summary> <summary>Relays that didn't accept it</summary>

View file

@ -184,7 +184,6 @@ export function HomeScreen({ onNavigate, onCreateProfile }: HomeScreenProps) {
<PublicationResult <PublicationResult
lastPublish={lastPublish} lastPublish={lastPublish}
onNavigateCompose={() => onNavigate('compose')} onNavigateCompose={() => onNavigate('compose')}
onNavigateFeed={() => onNavigate('feed')}
/> />
</div> </div>
</section> </section>
@ -196,11 +195,9 @@ export function HomeScreen({ onNavigate, onCreateProfile }: HomeScreenProps) {
function PublicationResult({ function PublicationResult({
lastPublish, lastPublish,
onNavigateCompose, onNavigateCompose,
onNavigateFeed,
}: { }: {
lastPublish: ReturnType<typeof useApp>['lastPublish']; lastPublish: ReturnType<typeof useApp>['lastPublish'];
onNavigateCompose: () => void; onNavigateCompose: () => void;
onNavigateFeed: () => void;
}) { }) {
if (!lastPublish) { if (!lastPublish) {
return ( return (
@ -231,19 +228,18 @@ function PublicationResult({
if (report.failed.length === 0) { if (report.failed.length === 0) {
return ( return (
<div className="publish-result success"> <>
<Badge tone="success"> <div className="publish-result success">
<Icon name="check" size={14} /> Published <Badge tone="success">
</Badge> <Icon name="check" size={14} /> Published
<span className="mono" title={report.event_id}> </Badge>
{shortenNpub(report.event_id, true)} <span className="mono" title={report.event_id}>
</span> {shortenNpub(report.event_id, true)}
<CopyButton text={report.event_id} label="event ID" /> </span>
<Button variant="ghost" size="sm" onClick={onNavigateFeed}> <CopyButton text={report.event_id} label="event ID" />
<Icon name="list" size={16} /> </div>
View in Feed {report.content && <p className="publish-preview">{report.content}</p>}
</Button> </>
</div>
); );
} }
@ -257,10 +253,7 @@ function PublicationResult({
</code> </code>
</Alert> </Alert>
<CopyButton text={report.event_id} label="event ID" /> <CopyButton text={report.event_id} label="event ID" />
<Button variant="ghost" size="sm" onClick={onNavigateFeed}> {report.content && <p className="publish-preview">{report.content}</p>}
<Icon name="list" size={16} />
View in Feed
</Button>
<details className="alert-details"> <details className="alert-details">
<summary>Relay results</summary> <summary>Relay results</summary>
<ul className="relay-result-list"> <ul className="relay-result-list">

View file

@ -1587,6 +1587,18 @@ select {
flex-basis: 100%; flex-basis: 100%;
} }
.publish-preview {
margin: 8px 0 0;
padding: 10px 12px;
background: var(--surface-2);
border-radius: var(--radius-sm);
font-size: 14px;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-word;
max-width: 65ch;
}
.relay-result-list { .relay-result-list {
margin: 8px 0 0; margin: 8px 0 0;
padding-left: 18px; padding-left: 18px;

View file

@ -468,8 +468,11 @@ async fn run_with_app(app: &mut App, request: Request) -> Result<serde_json::Val
event_id: report.event_id.clone(), event_id: report.event_id.clone(),
succeeded: report.succeeded.clone(), succeeded: report.succeeded.clone(),
failed: report.failed.clone(), failed: report.failed.clone(),
content: content.trim().to_string(),
}; };
let _ = crate::vault::save_last_publish(&stored); if let Err(e) = crate::vault::save_last_publish(&stored) {
eprintln!("Could not save last publish report: {e}");
}
app.last_publish = Some(stored); app.last_publish = Some(stored);
Ok(json!(report)) Ok(json!(report))
} }

View file

@ -193,6 +193,8 @@ pub struct StoredPublishReport {
pub event_id: String, pub event_id: String,
pub succeeded: Vec<String>, pub succeeded: Vec<String>,
pub failed: Vec<crate::publish::RelayFailure>, pub failed: Vec<crate::publish::RelayFailure>,
#[serde(default)]
pub content: String,
} }
/// Load the last publish report, returning `None` when absent or unreadable. /// Load the last publish report, returning `None` when absent or unreadable.