2023-07-24 18:35:05 +00:00
|
|
|
import Dropdown from 'react-bootstrap/Dropdown'
|
2022-12-19 22:27:52 +00:00
|
|
|
import ShareIcon from '../svgs/share-fill.svg'
|
|
|
|
import copy from 'clipboard-copy'
|
2023-12-19 17:48:48 +00:00
|
|
|
import useCrossposter from './use-crossposter'
|
2022-12-19 22:27:52 +00:00
|
|
|
import { useMe } from './me'
|
2023-08-25 23:21:51 +00:00
|
|
|
import { useToast } from './toast'
|
2023-10-15 17:45:21 +00:00
|
|
|
import { SSR } from '../lib/constants'
|
2024-01-18 01:02:59 +00:00
|
|
|
import { commentSubTreeRootId } from '../lib/item'
|
|
|
|
import { useRouter } from 'next/router'
|
2023-10-15 17:45:21 +00:00
|
|
|
|
2023-12-15 18:10:29 +00:00
|
|
|
const referrurl = (ipath, me) => {
|
2024-03-17 14:57:50 +00:00
|
|
|
const referral = me && !me.privates?.noReferralLinks
|
|
|
|
const path = `${ipath}${referral ? `/r/${me.name}` : ''}`
|
2023-10-15 17:45:21 +00:00
|
|
|
if (!SSR) {
|
|
|
|
return `${window.location.protocol}//${window.location.host}${path}`
|
|
|
|
}
|
|
|
|
return `https://stacker.news${path}`
|
|
|
|
}
|
2022-12-19 22:27:52 +00:00
|
|
|
|
2023-12-15 18:10:29 +00:00
|
|
|
export default function Share ({ path, title, className = '' }) {
|
2022-12-19 22:27:52 +00:00
|
|
|
const me = useMe()
|
2023-08-25 23:21:51 +00:00
|
|
|
const toaster = useToast()
|
2023-12-15 18:10:29 +00:00
|
|
|
const url = referrurl(path, me)
|
2023-12-19 17:48:48 +00:00
|
|
|
|
2023-10-15 17:45:21 +00:00
|
|
|
return !SSR && navigator?.share
|
2022-12-19 22:27:52 +00:00
|
|
|
? (
|
2023-07-24 18:35:05 +00:00
|
|
|
<div className='ms-auto pointer d-flex align-items-center'>
|
2022-12-19 22:27:52 +00:00
|
|
|
<ShareIcon
|
2023-05-01 20:58:30 +00:00
|
|
|
width={20} height={20}
|
2023-12-15 18:10:29 +00:00
|
|
|
className={`mx-2 fill-grey theme ${className}`}
|
2023-08-25 23:21:51 +00:00
|
|
|
onClick={async () => {
|
|
|
|
try {
|
|
|
|
await navigator.share({
|
2023-12-15 18:10:29 +00:00
|
|
|
title: title || '',
|
2022-12-19 22:27:52 +00:00
|
|
|
text: '',
|
|
|
|
url
|
2023-08-25 23:21:51 +00:00
|
|
|
})
|
|
|
|
toaster.success('link shared')
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err)
|
2022-12-19 22:27:52 +00:00
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>)
|
|
|
|
: (
|
2023-07-24 18:35:05 +00:00
|
|
|
<Dropdown align='end' className='ms-auto pointer d-flex align-items-center' as='span'>
|
2022-12-19 22:27:52 +00:00
|
|
|
<Dropdown.Toggle variant='success' id='dropdown-basic' as='a'>
|
2023-12-15 18:10:29 +00:00
|
|
|
<ShareIcon width={20} height={20} className={`mx-2 fill-grey theme ${className}`} />
|
2022-12-19 22:27:52 +00:00
|
|
|
</Dropdown.Toggle>
|
|
|
|
<Dropdown.Menu>
|
|
|
|
<Dropdown.Item
|
|
|
|
onClick={async () => {
|
2023-08-25 23:21:51 +00:00
|
|
|
try {
|
|
|
|
await copy(url)
|
|
|
|
toaster.success('link copied')
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err)
|
|
|
|
toaster.danger('failed to copy link')
|
|
|
|
}
|
2022-12-19 22:27:52 +00:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
copy link
|
|
|
|
</Dropdown.Item>
|
|
|
|
</Dropdown.Menu>
|
|
|
|
</Dropdown>)
|
|
|
|
}
|
2023-02-16 22:23:59 +00:00
|
|
|
|
|
|
|
export function CopyLinkDropdownItem ({ item }) {
|
|
|
|
const me = useMe()
|
2023-08-25 23:21:51 +00:00
|
|
|
const toaster = useToast()
|
2024-01-18 01:02:59 +00:00
|
|
|
const router = useRouter()
|
|
|
|
let url = referrurl(`/items/${item.id}`, me)
|
|
|
|
|
|
|
|
// if this is a comment and we're not directly on the comment page
|
|
|
|
// link to the comment in context
|
|
|
|
if (item.parentId && !router.asPath.includes(`/items/${item.id}`)) {
|
|
|
|
const rootId = commentSubTreeRootId(item)
|
|
|
|
url = referrurl(`/items/${rootId}`, me) + `?commentId=${item.id}`
|
|
|
|
}
|
|
|
|
|
2023-02-16 22:23:59 +00:00
|
|
|
return (
|
|
|
|
<Dropdown.Item
|
|
|
|
onClick={async () => {
|
2023-08-25 23:21:51 +00:00
|
|
|
try {
|
|
|
|
if (navigator.share) {
|
|
|
|
await navigator.share({
|
|
|
|
title: item.title || '',
|
|
|
|
text: '',
|
|
|
|
url
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
await copy(url)
|
|
|
|
}
|
|
|
|
toaster.success('link copied')
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err)
|
|
|
|
toaster.danger('failed to copy link')
|
2023-02-16 22:23:59 +00:00
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
copy link
|
|
|
|
</Dropdown.Item>
|
|
|
|
)
|
|
|
|
}
|
2023-12-15 18:10:29 +00:00
|
|
|
|
|
|
|
export function CrosspostDropdownItem ({ item }) {
|
|
|
|
const crossposter = useCrossposter()
|
|
|
|
const toaster = useToast()
|
|
|
|
|
Nostr crossposting all item types (#779)
* crosspost-item
* crosspost old items, update with nEventId
* Updating noteId encoding, cleaning up a little
* Fixing item-info condition, cleaning up
* Linting
* Add createdAt variable back
* Change instances of eventId to noteId
* Adding upsertNoteId mutation
* Cleaning up updateItem, using toasts to communivate success/failure in crosspost-item
* Linting
* Move crosspost to share button, make sure only OP can crosspost
* Lint
* Simplify conditions
* user might have no nostr extension installed
Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>
* change upsertNoteId to updateNoteID for resolver and mutations, change isOp to mine, remove unused noteId params
* Basic setup for crossposting poll / link items
* post rebase fixes and Bounty and job crossposts
* Job crossposting working
* adding back accidentally removed import
* Lint / rebase
* Outsource as much crossposting logic from discussion-form into use-crossposter as possible
* Fix incorrect property for user relays, fix itemId param in updateNoteId
* Fix toast messages / error cases in use-crossposter
* Update item forms to for updated use-crossposter hook
* CrosspostDropdownItem in share updated to accomodate use-crossposter update
* Encode paramaterized replacable event id's in naddress format with nostr-tools, bounty to follw nip-99 spec
* Increase timeout on relay connection / cleaning up
* No longer crossposting job
* Add blastr, fix crosspost button in item-info for polls/discussions, finish removing job crosspostr code
* Fix toaster error, create reusable crossposterror function to surface toaster
* Cleaning up / comments / linting
* Update copy
* Simplify CrosspostdropdownItem, keep replies from being crossposted
* Moved query for missing item fields when crossposting to use-crossposter hook
* Remove unneeded param in CrosspostDropdownItem, lint
* Small fixes post rebase
* Remove unused import
* fix nostr-tools version, fix package-lock.json
* Update components/item-info.js
Co-authored-by: ekzyis <ek@stacker.news>
* Remove unused param, determine poll item type from pollCost field, add mutiny strfry relay to defaults
* Update toaster implementations, use no-cache for item query, restructure crosspostItem to use await with try catch
* crosspost info modal that lives under adv-post-form now has dynamic crossposting info
* Move determineItemType into handleEventCreation, mover item/event handing outside of do ... while loop
* Lint
* Reconcile skip method with onCancel function in toaster
* Handle failedRelays being undefined
* determine item type from router.query.type if available otherwise use item fields
* Initiliaze failerRelays as undefined but handle error explicitly
* Lint
* Fix crosspost default value for link, poll, bounty forms
---------
Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>
Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-02-22 01:18:36 +00:00
|
|
|
const handleCrosspostClick = async () => {
|
|
|
|
try {
|
|
|
|
await crossposter(item.id)
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e)
|
|
|
|
toaster.danger('Crosspost failed')
|
|
|
|
}
|
|
|
|
}
|
2023-12-15 18:10:29 +00:00
|
|
|
|
|
|
|
return (
|
Nostr crossposting all item types (#779)
* crosspost-item
* crosspost old items, update with nEventId
* Updating noteId encoding, cleaning up a little
* Fixing item-info condition, cleaning up
* Linting
* Add createdAt variable back
* Change instances of eventId to noteId
* Adding upsertNoteId mutation
* Cleaning up updateItem, using toasts to communivate success/failure in crosspost-item
* Linting
* Move crosspost to share button, make sure only OP can crosspost
* Lint
* Simplify conditions
* user might have no nostr extension installed
Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>
* change upsertNoteId to updateNoteID for resolver and mutations, change isOp to mine, remove unused noteId params
* Basic setup for crossposting poll / link items
* post rebase fixes and Bounty and job crossposts
* Job crossposting working
* adding back accidentally removed import
* Lint / rebase
* Outsource as much crossposting logic from discussion-form into use-crossposter as possible
* Fix incorrect property for user relays, fix itemId param in updateNoteId
* Fix toast messages / error cases in use-crossposter
* Update item forms to for updated use-crossposter hook
* CrosspostDropdownItem in share updated to accomodate use-crossposter update
* Encode paramaterized replacable event id's in naddress format with nostr-tools, bounty to follw nip-99 spec
* Increase timeout on relay connection / cleaning up
* No longer crossposting job
* Add blastr, fix crosspost button in item-info for polls/discussions, finish removing job crosspostr code
* Fix toaster error, create reusable crossposterror function to surface toaster
* Cleaning up / comments / linting
* Update copy
* Simplify CrosspostdropdownItem, keep replies from being crossposted
* Moved query for missing item fields when crossposting to use-crossposter hook
* Remove unneeded param in CrosspostDropdownItem, lint
* Small fixes post rebase
* Remove unused import
* fix nostr-tools version, fix package-lock.json
* Update components/item-info.js
Co-authored-by: ekzyis <ek@stacker.news>
* Remove unused param, determine poll item type from pollCost field, add mutiny strfry relay to defaults
* Update toaster implementations, use no-cache for item query, restructure crosspostItem to use await with try catch
* crosspost info modal that lives under adv-post-form now has dynamic crossposting info
* Move determineItemType into handleEventCreation, mover item/event handing outside of do ... while loop
* Lint
* Reconcile skip method with onCancel function in toaster
* Handle failedRelays being undefined
* determine item type from router.query.type if available otherwise use item fields
* Initiliaze failerRelays as undefined but handle error explicitly
* Lint
* Fix crosspost default value for link, poll, bounty forms
---------
Co-authored-by: ekzyis <27162016+ekzyis@users.noreply.github.com>
Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2024-02-22 01:18:36 +00:00
|
|
|
<Dropdown.Item onClick={handleCrosspostClick}>
|
2023-12-15 18:10:29 +00:00
|
|
|
crosspost to nostr
|
|
|
|
</Dropdown.Item>
|
|
|
|
)
|
|
|
|
}
|