Merge remote-tracking branch 'hub/main' into feature/sse-connect
Some checks failed
deploy / test (push) Failing after 1m0s
deploy / Update templates on Mailgun (push) Failing after 5s

This commit is contained in:
Untone 2024-01-10 15:42:54 +03:00
commit 8c8c8725f4
5 changed files with 46 additions and 16 deletions

View File

@ -14,7 +14,6 @@ import { Icon } from '../../_shared/Icon'
import { Image } from '../../_shared/Image' import { Image } from '../../_shared/Image'
import { InviteCoAuthorsModal } from '../../_shared/InviteCoAuthorsModal' import { InviteCoAuthorsModal } from '../../_shared/InviteCoAuthorsModal'
import { Popover } from '../../_shared/Popover' import { Popover } from '../../_shared/Popover'
import { ShareModal } from '../../_shared/ShareModal'
import { CoverImage } from '../../Article/CoverImage' import { CoverImage } from '../../Article/CoverImage'
import { getShareUrl, SharePopup } from '../../Article/SharePopup' import { getShareUrl, SharePopup } from '../../Article/SharePopup'
import { ShoutRatingControl } from '../../Article/ShoutRatingControl' import { ShoutRatingControl } from '../../Article/ShoutRatingControl'
@ -52,6 +51,7 @@ export type ArticleCardProps = {
withAspectRatio?: boolean withAspectRatio?: boolean
desktopCoverSize?: 'XS' | 'S' | 'M' | 'L' desktopCoverSize?: 'XS' | 'S' | 'M' | 'L'
article: Shout article: Shout
onShare?: (article: Shout) => void
} }
const desktopCoverImageWidths: Record<ArticleCardProps['desktopCoverSize'], number> = { const desktopCoverImageWidths: Record<ArticleCardProps['desktopCoverSize'], number> = {
@ -370,7 +370,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
<FeedArticlePopup <FeedArticlePopup
isOwner={canEdit()} isOwner={canEdit()}
containerCssClass={stylesHeader.control} containerCssClass={stylesHeader.control}
onShareClick={() => showModal('share')} onShareClick={() => props.onShare(props.article)}
onInviteClick={() => showModal('inviteCoAuthors')} onInviteClick={() => showModal('inviteCoAuthors')}
onVisibilityChange={(isVisible) => setIsActionPopupActive(isVisible)} onVisibilityChange={(isVisible) => setIsActionPopupActive(isVisible)}
trigger={ trigger={
@ -389,12 +389,6 @@ export const ArticleCard = (props: ArticleCardProps) => {
</Show> </Show>
</div> </div>
<InviteCoAuthorsModal title={t('Invite experts')} /> <InviteCoAuthorsModal title={t('Invite experts')} />
<ShareModal
title={title}
description={description}
imageUrl={props.article.cover}
shareUrl={getShareUrl({ pathname: `/${props.article.slug}` })}
/>
</section> </section>
) )
} }

View File

@ -1,7 +1,7 @@
.backdrop { .backdrop {
align-items: center; align-items: center;
display: flex; display: flex;
background: rgb(20 20 20 / 7%); background: rgb(20 20 20 / 90%);
justify-content: center; justify-content: center;
height: 100%; height: 100%;
left: 0; left: 0;

View File

@ -10,6 +10,7 @@ import { useReactions } from '../../../context/reactions'
import { useSession } from '../../../context/session' import { useSession } from '../../../context/session'
import { apiClient } from '../../../graphql/client/core' import { apiClient } from '../../../graphql/client/core'
import { router, useRouter } from '../../../stores/router' import { router, useRouter } from '../../../stores/router'
import { showModal } from '../../../stores/ui'
import { useArticlesStore, resetSortedArticles } from '../../../stores/zine/articles' import { useArticlesStore, resetSortedArticles } from '../../../stores/zine/articles'
import { useTopAuthorsStore } from '../../../stores/zine/topAuthors' import { useTopAuthorsStore } from '../../../stores/zine/topAuthors'
import { useTopicsStore } from '../../../stores/zine/topics' import { useTopicsStore } from '../../../stores/zine/topics'
@ -17,7 +18,10 @@ import { getImageUrl } from '../../../utils/getImageUrl'
import { DropDown } from '../../_shared/DropDown' import { DropDown } from '../../_shared/DropDown'
import { Icon } from '../../_shared/Icon' import { Icon } from '../../_shared/Icon'
import { Loading } from '../../_shared/Loading' import { Loading } from '../../_shared/Loading'
import { ShareModal } from '../../_shared/ShareModal'
import { CommentDate } from '../../Article/CommentDate' import { CommentDate } from '../../Article/CommentDate'
import { getShareUrl } from '../../Article/SharePopup'
import { AuthorLink } from '../../Author/AhtorLink'
import { AuthorBadge } from '../../Author/AuthorBadge' import { AuthorBadge } from '../../Author/AuthorBadge'
import { AuthorLink } from '../../Author/AuthorLink' import { AuthorLink } from '../../Author/AuthorLink'
import { ArticleCard } from '../../Feed/ArticleCard' import { ArticleCard } from '../../Feed/ArticleCard'
@ -216,6 +220,12 @@ export const FeedView = (props: Props) => {
) )
const ogTitle = t('Feed') const ogTitle = t('Feed')
const [shareData, setShareData] = createSignal<Shout | undefined>()
const handleShare = (shared) => {
showModal('share')
setShareData(shared)
}
return ( return (
<div class="wide-container feed"> <div class="wide-container feed">
<Meta name="descprition" content={description} /> <Meta name="descprition" content={description} />
@ -292,7 +302,12 @@ export const FeedView = (props: Props) => {
<Show when={sortedArticles().length > 0}> <Show when={sortedArticles().length > 0}>
<For each={sortedArticles().slice(0, 4)}> <For each={sortedArticles().slice(0, 4)}>
{(article) => ( {(article) => (
<ArticleCard article={article} settings={{ isFeedMode: true }} desktopCoverSize="M" /> <ArticleCard
onShare={(shared) => handleShare(shared)}
article={article}
settings={{ isFeedMode: true }}
desktopCoverSize="M"
/>
)} )}
</For> </For>
@ -407,6 +422,14 @@ export const FeedView = (props: Props) => {
</Show> </Show>
</aside> </aside>
</div> </div>
<Show when={shareData()}>
<ShareModal
title={shareData().title}
description={shareData().description}
imageUrl={shareData().cover}
shareUrl={getShareUrl({ pathname: `/${shareData().slug}` })}
/>
</Show>
</div> </div>
) )
} }

View File

@ -16,11 +16,13 @@ type Props = {
imageUrl?: string imageUrl?: string
class?: string class?: string
variant: 'inModal' | 'inPopup' variant: 'inModal' | 'inPopup'
onShareClick?: () => void
} }
export const ShareLinks = (props: Props) => { export const ShareLinks = (props: Props) => {
const { t } = useLocalize() const { t } = useLocalize()
const [isLinkCopied, setIsLinkCopied] = createSignal(false) const [isLinkCopied, setIsLinkCopied] = createSignal(false)
const { const {
actions: { showSnackbar }, actions: { showSnackbar },
} = useSnackbar() } = useSnackbar()
@ -30,11 +32,21 @@ export const ShareLinks = (props: Props) => {
url: props.shareUrl, url: props.shareUrl,
description: props.description, description: props.description,
})) }))
const handleShare = (network) => {
share(network)
if (props.variant === 'inModal') {
props.onShareClick()
}
}
const copyLink = async () => { const copyLink = async () => {
await navigator.clipboard.writeText(props.shareUrl) await navigator.clipboard.writeText(props.shareUrl)
if (props.variant === 'inModal') { if (props.variant === 'inModal') {
setIsLinkCopied(true) setIsLinkCopied(true)
setTimeout(() => setIsLinkCopied(false), 3000) setTimeout(() => {
setIsLinkCopied(false)
props.onShareClick()
}, 3000)
} else { } else {
showSnackbar({ body: t('Link copied') }) showSnackbar({ body: t('Link copied') })
} }
@ -44,25 +56,25 @@ export const ShareLinks = (props: Props) => {
<div class={clsx(styles.ShareLinks, props.class, { [styles.inModal]: props.variant === 'inModal' })}> <div class={clsx(styles.ShareLinks, props.class, { [styles.inModal]: props.variant === 'inModal' })}>
<ul class="nodash"> <ul class="nodash">
<li> <li>
<button role="button" class={styles.shareControl} onClick={() => share(FACEBOOK)}> <button role="button" class={styles.shareControl} onClick={() => handleShare(FACEBOOK)}>
<Icon name="facebook-white" class={styles.icon} /> <Icon name="facebook-white" class={styles.icon} />
Facebook Facebook
</button> </button>
</li> </li>
<li> <li>
<button role="button" class={styles.shareControl} onClick={() => share(TWITTER)}> <button role="button" class={styles.shareControl} onClick={() => handleShare(TWITTER)}>
<Icon name="twitter-white" class={styles.icon} /> <Icon name="twitter-white" class={styles.icon} />
Twitter Twitter
</button> </button>
</li> </li>
<li> <li>
<button role="button" class={styles.shareControl} onClick={() => share(TELEGRAM)}> <button role="button" class={styles.shareControl} onClick={() => handleShare(TELEGRAM)}>
<Icon name="telegram-white" class={styles.icon} /> <Icon name="telegram-white" class={styles.icon} />
Telegram Telegram
</button> </button>
</li> </li>
<li> <li>
<button role="button" class={styles.shareControl} onClick={() => share(VK)}> <button role="button" class={styles.shareControl} onClick={() => handleShare(VK)}>
<Icon name="vk-white" class={styles.icon} /> <Icon name="vk-white" class={styles.icon} />
VK VK
</button> </button>

View File

@ -1,4 +1,5 @@
import { useLocalize } from '../../../context/localize' import { useLocalize } from '../../../context/localize'
import { hideModal } from '../../../stores/ui'
import { Modal } from '../../Nav/Modal' import { Modal } from '../../Nav/Modal'
import { ShareLinks } from '../ShareLinks' import { ShareLinks } from '../ShareLinks'
@ -11,7 +12,6 @@ type Props = {
} }
export const ShareModal = (props: Props) => { export const ShareModal = (props: Props) => {
const { t } = useLocalize() const { t } = useLocalize()
return ( return (
<Modal name="share" variant="medium" allowClose={true}> <Modal name="share" variant="medium" allowClose={true}>
<h2>{t('Share publication')}</h2> <h2>{t('Share publication')}</h2>
@ -21,6 +21,7 @@ export const ShareModal = (props: Props) => {
shareUrl={props.shareUrl} shareUrl={props.shareUrl}
imageUrl={props.imageUrl} imageUrl={props.imageUrl}
description={props.description} description={props.description}
onShareClick={() => hideModal()}
/> />
</Modal> </Modal>
) )