diff --git a/bin/svgs.js b/bin/svgs.js index 1d33209..f99d5ed 100644 --- a/bin/svgs.js +++ b/bin/svgs.js @@ -43,5 +43,6 @@ module.exports = [ { id: 'fa-angle-left', src: 'src/thirdparty/font-awesome-svg-png/white/svg/angle-left.svg' }, { id: 'fa-angle-right', src: 'src/thirdparty/font-awesome-svg-png/white/svg/angle-right.svg' }, { id: 'fa-search-minus', src: 'src/thirdparty/font-awesome-svg-png/white/svg/search-minus.svg' }, - { id: 'fa-search-plus', src: 'src/thirdparty/font-awesome-svg-png/white/svg/search-plus.svg' } + { id: 'fa-search-plus', src: 'src/thirdparty/font-awesome-svg-png/white/svg/search-plus.svg' }, + { id: 'fa-share-square-o', src: 'src/thirdparty/font-awesome-svg-png/white/svg/share-square-o.svg' } ] diff --git a/src/routes/_actions/share.js b/src/routes/_actions/share.js new file mode 100644 index 0000000..dddf68d --- /dev/null +++ b/src/routes/_actions/share.js @@ -0,0 +1,14 @@ +import { toast } from '../_components/toast/toast' +import { statusHtmlToPlainText } from '../_utils/statusHtmlToPlainText' + +export async function shareStatus (status) { + try { + await navigator.share({ + title: status.spoiler_text || undefined, + text: statusHtmlToPlainText(status.content, status.mentions), + url: status.url + }) + } catch (e) { + toast.say(`Unable to share: ` + (e.message || '')) + } +} diff --git a/src/routes/_components/dialog/components/StatusOptionsDialog.html b/src/routes/_components/dialog/components/StatusOptionsDialog.html index 4fcf60a..7b389b4 100644 --- a/src/routes/_components/dialog/components/StatusOptionsDialog.html +++ b/src/routes/_components/dialog/components/StatusOptionsDialog.html @@ -21,9 +21,13 @@ import { setStatusPinnedOrUnpinned } from '../../../_actions/pin' import { setConversationMuted } from '../../../_actions/muteConversation' import { copyText } from '../../../_actions/copyText' import { deleteAndRedraft } from '../../../_actions/deleteAndRedraft' +import { shareStatus } from '../../../_actions/share' export default { oncreate, + data: () => ({ + supportsWebShare: process.browser && typeof navigator.share === 'function' + }), computed: { relationship: ({ $currentAccountRelationship }) => $currentAccountRelationship, account: ({ $currentAccountProfile }) => $currentAccountProfile, @@ -75,17 +79,18 @@ export default { mutingConversation: ({ status }) => !!status.muted, muteConversationLabel: ({ mutingConversation }) => mutingConversation ? `Unmute conversation` : `Mute conversation`, muteConversationIcon: ({ mutingConversation }) => mutingConversation ? '#fa-volume-up' : '#fa-volume-off', + isPublicOrUnlisted: ({ visibility }) => visibility === 'public' || visibility === 'unlisted', items: ({ blockLabel, blocking, blockIcon, muteLabel, muteIcon, followLabel, followIcon, following, followRequested, pinLabel, isUser, visibility, mentionsUser, mutingConversation, - muteConversationLabel, muteConversationIcon + muteConversationLabel, muteConversationIcon, supportsWebShare, isPublicOrUnlisted }) => ([ isUser && { key: 'delete', label: 'Delete', icon: '#fa-trash' }, - visibility !== 'private' && visibility !== 'direct' && isUser && { + isPublicOrUnlisted && isUser && { key: 'pin', label: pinLabel, icon: '#fa-thumb-tack' @@ -115,7 +120,12 @@ export default { label: 'Delete and redraft', icon: '#fa-pencil' }, - { + isPublicOrUnlisted && supportsWebShare && { + key: 'share', + label: 'Share toot', + icon: '#fa-share-square-o' + }, + isPublicOrUnlisted && { key: 'copy', label: 'Copy link to toot', icon: '#fa-link' @@ -148,6 +158,8 @@ export default { return this.onMuteConversationClicked() case 'redraft': return this.onRedraft() + case 'share': + return this.onShare() } }, async onDeleteClicked () { @@ -190,6 +202,11 @@ export default { let { status } = this.get() await deleteAndRedraft(status) this.close() + }, + async onShare () { + let { status } = this.get() + await shareStatus(status) + this.close() } } }