Skip to content
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
23 changes: 23 additions & 0 deletions src/lib/components/AddFeedModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { fetchSingleFeed } from '$lib/services/feedFetcher';
import { searchBlueskyActors, type BlueskySearchResult } from '$lib/services/blueskySearch';
import { api } from '$lib/services/api';
import { profileService } from '$lib/services/profiles';
import Modal from '$lib/components/common/Modal.svelte';

interface Publication {
Expand Down Expand Up @@ -449,6 +450,28 @@
$effect(() => {
if (open) {
loadStandardSubscriptions();
// If opened with a specific DID, skip straight to content detection
const initialDid = sidebarStore.addFeedModalInitialDid;
if (initialDid) {
// Start content detection immediately with DID as placeholder handle
selectAccount({
did: initialDid,
handle: initialDid,
displayName: undefined,
avatar: undefined,
});
// Resolve profile in background to update display name/avatar
profileService.getProfile(initialDid).then((profile) => {
if (profile && selectedAccount?.did === initialDid) {
selectedAccount = {
...selectedAccount,
handle: profile.handle || selectedAccount.handle,
displayName: profile.displayName,
avatar: profile.avatar,
};
}
});
}
}
});

Expand Down
66 changes: 55 additions & 11 deletions src/lib/components/ArticleCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import LinkContextMenu from '$lib/components/feed/LinkContextMenu.svelte';
import { itemLabelsStore } from '$lib/stores/itemLabels.svelte';
import { feedViewStore } from '$lib/stores/feedView.svelte';
import { sidebarStore } from '$lib/stores/sidebar.svelte';
import { useParagraphTracking } from '$lib/hooks/useParagraphTracking.svelte';
import { useLinkInterception } from '$lib/hooks/useLinkInterception.svelte';
import { useHighlights } from '$lib/hooks/useHighlights.svelte';
Expand Down Expand Up @@ -107,6 +108,34 @@
let itemGuid = $derived(article?.guid || share?.itemGuid || document?.recordUri || itemUrl);
let displaySiteUrl = $derived(siteUrl || share?.feedUrl || document?.siteUri || itemUrl);

// Derive a publication name for shares/documents when feedTitle isn't provided
let displayFeedTitle = $derived.by(() => {
if (feedTitle) return feedTitle;
// For shares, extract hostname from feedUrl or itemUrl
if (isShareMode) {
const url = share?.feedUrl || share?.itemUrl;
if (url) {
try {
return new URL(url).hostname.replace(/^www\./, '');
} catch {
return undefined;
}
}
}
// For documents, extract hostname from canonicalUrl
if (isDocumentMode) {
const url = document?.canonicalUrl;
if (url) {
try {
return new URL(url).hostname.replace(/^www\./, '');
} catch {
return undefined;
}
}
}
return undefined;
});

// Content handling - article has priority, then share content, then localArticle, then document
let displayContent = $derived.by(() => {
// For articles and shares, use existing logic
Expand Down Expand Up @@ -458,10 +487,12 @@
<div class="share-attribution">
<img src={logo} alt="" class="attribution-icon" />
shared by
<a
href="/?sharer={share.authorDid}"
<button
class="share-author-link"
onclick={(e) => e.stopPropagation()}>@{authorHandle}</a
onclick={(e) => {
e.stopPropagation();
sidebarStore.openAddFeedModalForDid(share.authorDid);
}}>@{authorHandle}</button
>
{#if displayReshareCount > 0}
<span class="attribution-reshare-count" title="{displayReshareCount} reshares"
Expand All @@ -473,10 +504,12 @@
<div class="share-attribution">
<span class="attribution-icon-wrapper"><Icon name="newspaper" size={12} /></span>
published by
<a
href="/?author={document.authorDid}"
<button
class="share-author-link"
onclick={(e) => e.stopPropagation()}>@{authorHandle}</a
onclick={(e) => {
e.stopPropagation();
sidebarStore.openAddFeedModalForDid(document.authorDid);
}}>@{authorHandle}</button
>
</div>
{/if}
Expand All @@ -497,10 +530,14 @@
{itemTitle}
{/if}
</span>
{#if feedTitle}
<a href="/?feed={feedId}" class="feed-title-link" onclick={(e) => e.stopPropagation()}
>{feedTitle}</a
>
{#if displayFeedTitle}
{#if feedId}
<a href="/?feed={feedId}" class="feed-title-link" onclick={(e) => e.stopPropagation()}
>{displayFeedTitle}</a
>
{:else}
<span class="feed-title-label">{displayFeedTitle}</span>
{/if}
{/if}
<span class="article-date">{formatRelativeDate(itemPublishedAt)}</span>
</button>
Expand Down Expand Up @@ -788,6 +825,12 @@
.share-author-link {
color: var(--color-text-secondary);
text-decoration: none;
background: none;
border: none;
padding: 0;
font: inherit;
font-size: inherit;
cursor: pointer;
}

.share-author-link:hover {
Expand Down Expand Up @@ -853,7 +896,8 @@
color: var(--color-text-secondary);
}

.feed-title-link {
.feed-title-link,
.feed-title-label {
flex-shrink: 0;
max-width: 12rem;
overflow: hidden;
Expand Down
12 changes: 12 additions & 0 deletions src/lib/stores/sidebar.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,20 @@ function createSidebarStore() {
persist();
}

let addFeedModalInitialDid = $state<string | null>(null);

function openAddFeedModal() {
state.addFeedModalOpen = true;
}

function openAddFeedModalForDid(did: string) {
addFeedModalInitialDid = did;
state.addFeedModalOpen = true;
}

function closeAddFeedModal() {
state.addFeedModalOpen = false;
addFeedModalInitialDid = null;
}

function openSaveArticleModal() {
Expand Down Expand Up @@ -117,6 +125,9 @@ function createSidebarStore() {
get addFeedModalOpen() {
return state.addFeedModalOpen;
},
get addFeedModalInitialDid() {
return addFeedModalInitialDid;
},
get saveArticleModalOpen() {
return state.saveArticleModalOpen;
},
Expand All @@ -137,6 +148,7 @@ function createSidebarStore() {
toggleSection,
toggleShowOnlyUnread,
openAddFeedModal,
openAddFeedModalForDid,
closeAddFeedModal,
openSaveArticleModal,
closeSaveArticleModal,
Expand Down