From ce3978246b47e660d416c7e27bb33a369a3307ec Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 16 Nov 2023 11:23:14 +0100 Subject: [PATCH 1/2] [Glitch] Add prominent share/copy button on profiles in web UI Port 87696ea26e832fda3cb7a335db6c5899c5ddbf6d to glitch-soc Signed-off-by: Claire --- .../glitch/components/copy_icon_button.jsx | 43 +++++++++++++++++++ .../features/account/components/header.jsx | 24 ++++++----- .../flavours/glitch/styles/components.scss | 21 +++++++++ 3 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/copy_icon_button.jsx diff --git a/app/javascript/flavours/glitch/components/copy_icon_button.jsx b/app/javascript/flavours/glitch/components/copy_icon_button.jsx new file mode 100644 index 000000000..9c8d5fb8a --- /dev/null +++ b/app/javascript/flavours/glitch/components/copy_icon_button.jsx @@ -0,0 +1,43 @@ +import PropTypes from 'prop-types'; +import { useState, useCallback } from 'react'; + +import { defineMessages } from 'react-intl'; + +import classNames from 'classnames'; + +import { useDispatch } from 'react-redux'; + +import ContentCopyIcon from '@/material-icons/400-24px/content_copy.svg?react'; +import { showAlert } from 'flavours/glitch/actions/alerts'; +import { IconButton } from 'flavours/glitch/components/icon_button'; + +const messages = defineMessages({ + copied: { id: 'copy_icon_button.copied', defaultMessage: 'Copied to clipboard' }, +}); + +export const CopyIconButton = ({ title, value, className }) => { + const [copied, setCopied] = useState(false); + const dispatch = useDispatch(); + + const handleClick = useCallback(() => { + navigator.clipboard.writeText(value); + setCopied(true); + dispatch(showAlert({ message: messages.copied })); + setTimeout(() => setCopied(false), 700); + }, [setCopied, value, dispatch]); + + return ( + + ); +}; + +CopyIconButton.propTypes = { + title: PropTypes.string, + value: PropTypes.string, + className: PropTypes.string, +}; diff --git a/app/javascript/flavours/glitch/features/account/components/header.jsx b/app/javascript/flavours/glitch/features/account/components/header.jsx index ea56c9638..29e3aa32f 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.jsx +++ b/app/javascript/flavours/glitch/features/account/components/header.jsx @@ -14,9 +14,11 @@ import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react'; import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react'; +import ShareIcon from '@/material-icons/400-24px/share.svg?react'; import { Avatar } from 'flavours/glitch/components/avatar'; import { Badge, AutomatedBadge, GroupBadge } from 'flavours/glitch/components/badge'; import { Button } from 'flavours/glitch/components/button'; +import { CopyIconButton } from 'flavours/glitch/components/copy_icon_button'; import { Icon } from 'flavours/glitch/components/icon'; import { IconButton } from 'flavours/glitch/components/icon_button'; import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container'; @@ -44,6 +46,7 @@ const messages = defineMessages({ mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, report: { id: 'account.report', defaultMessage: 'Report @{name}' }, share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, + copy: { id: 'account.copy', defaultMessage: 'Copy link to profile' }, media: { id: 'account.media', defaultMessage: 'Media' }, blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' }, unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' }, @@ -175,11 +178,10 @@ class Header extends ImmutablePureComponent { const isRemote = account.get('acct') !== account.get('username'); const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null; - let info = []; - let actionBtn = ''; - let bellBtn = ''; - let lockedIcon = ''; - let menu = []; + let actionBtn, bellBtn, lockedIcon, shareBtn; + + let info = []; + let menu = []; if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { info.push(); @@ -197,6 +199,12 @@ class Header extends ImmutablePureComponent { bellBtn = ; } + if ('share' in navigator) { + shareBtn = ; + } else { + shareBtn = ; + } + if (me !== account.get('id')) { if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded actionBtn = ''; @@ -234,11 +242,6 @@ class Header extends ImmutablePureComponent { menu.push(null); } - if ('share' in navigator && !account.get('suspended')) { - menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); - menu.push(null); - } - if (account.get('id') === me) { if (profileLink) menu.push({ text: intl.formatMessage(messages.edit_profile), href: profileLink }); if (preferencesLink) menu.push({ text: intl.formatMessage(messages.preferences), href: preferencesLink }); @@ -349,6 +352,7 @@ class Header extends ImmutablePureComponent { <> {actionBtn} {bellBtn} + {shareBtn} )} diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 7df2a3aaf..f51a4c4da 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -1240,6 +1240,17 @@ body > [data-popper-placement] { font-size: 14px; font-weight: 500; } + + &.copyable { + transition: all 300ms linear; + } + + &.copied { + border-color: $valid-value-color; + color: $valid-value-color; + transition: none; + background-color: rgba($valid-value-color, 0.15); + } } .domain__wrapper { @@ -8061,6 +8072,16 @@ noscript { width: 24px; height: 24px; } + + &.copied { + border-color: $valid-value-color; + } + } + + @media screen and (width <= 427px) { + .optional { + display: none; + } } } From 50d9cd66d3f9e66418948111401122b7d1aee5dd Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 16 Nov 2023 12:59:45 +0100 Subject: [PATCH 2/2] [Glitch] Use container queries to hide profile share button Port c94bedf4e6e5987864b42d63aa90920f80d3644e to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index f51a4c4da..d5de4ce4f 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -7976,6 +7976,7 @@ noscript { .account__header { overflow: hidden; + container: account-header / inline-size; &.inactive { opacity: 0.5; @@ -8078,7 +8079,7 @@ noscript { } } - @media screen and (width <= 427px) { + @container account-header (max-width: 372px) { .optional { display: none; }