Merge branch 'glitch-soc' into develop

develop v4.3.0-alpha.3+glitch+cat+1.0.1
Jeremy Kescher 3 months ago
commit 05a5c20681
No known key found for this signature in database
GPG Key ID: 80A419A7A613DFA4

@ -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 (
<IconButton
className={classNames(className, copied ? 'copied' : 'copyable')}
title={title}
onClick={handleClick}
iconComponent={ContentCopyIcon}
/>
);
};
CopyIconButton.propTypes = {
title: PropTypes.string,
value: PropTypes.string,
className: PropTypes.string,
};

@ -7,7 +7,6 @@ import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
export default class FollowRequestNote extends ImmutablePureComponent {
static propTypes = {

@ -9,15 +9,16 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
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';
@ -45,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}' },
@ -176,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(<span className='relationship-tag'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>);
@ -198,6 +199,12 @@ class Header extends ImmutablePureComponent {
bellBtn = <IconButton icon={account.getIn(['relationship', 'notifying']) ? 'bell' : 'bell-o'} iconComponent={account.getIn(['relationship', 'notifying']) ? NotificationsActiveIcon : NotificationsIcon} active={account.getIn(['relationship', 'notifying'])} title={intl.formatMessage(account.getIn(['relationship', 'notifying']) ? messages.disableNotifications : messages.enableNotifications, { name: account.get('username') })} onClick={this.props.onNotifyToggle} />;
}
if ('share' in navigator) {
shareBtn = <IconButton className='optional' iconComponent={ShareIcon} title={intl.formatMessage(messages.share, { name: account.get('username') })} onClick={this.handleShare} />;
} else {
shareBtn = <CopyIconButton className='optional' title={intl.formatMessage(messages.copy)} value={account.get('url')} />;
}
if (me !== account.get('id')) {
if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded
actionBtn = '';
@ -235,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 });
@ -308,7 +310,7 @@ class Header extends ImmutablePureComponent {
}
}
const content = { __html: account.get('note_emojified') };
const content = { __html: account.get('note_emojified') };
const displayNameHtml = { __html: account.get('display_name_html') };
const fields = account.get('fields');
const isLocal = account.get('acct').indexOf('@') === -1;
@ -350,6 +352,7 @@ class Header extends ImmutablePureComponent {
<>
{actionBtn}
{bellBtn}
{shareBtn}
</>
)}
@ -372,28 +375,29 @@ class Header extends ImmutablePureComponent {
</div>
)}
{signedIn && <AccountNoteContainer account={account} />}
{!(suspended || hidden) && (
<div className='account__header__extra'>
<div className='account__header__bio'>
{ fields.size > 0 && (
<div className='account__header__fields'>
{fields.map((pair, i) => (
<dl key={i}>
<dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
<dd className={pair.get('verified_at') && 'verified'} title={pair.get('value_plain')}>
{pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><Icon id='check' icon={CheckIcon} className='verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} className='translate' />
</dd>
</dl>
))}
</div>
)}
{(account.get('id') !== me && signedIn) && <AccountNoteContainer account={account} />}
{account.get('note').length > 0 && account.get('note') !== '<p></p>' && <div className='account__header__content translate' dangerouslySetInnerHTML={content} />}
<div className='account__header__joined'><FormattedMessage id='account.joined' defaultMessage='Joined {date}' values={{ date: intl.formatDate(account.get('created_at'), { year: 'numeric', month: 'short', day: '2-digit' }) }} /></div>
<div className='account__header__fields'>
<dl>
<dt><FormattedMessage id='account.joined_short' defaultMessage='Joined' /></dt>
<dd>{intl.formatDate(account.get('created_at'), { year: 'numeric', month: 'short', day: '2-digit' })}</dd>
</dl>
{fields.map((pair, i) => (
<dl key={i} className={classNames({ verified: pair.get('verified_at') })}>
<dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} className='translate' />
<dd className='translate' title={pair.get('value_plain')}>
{pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><Icon id='check' icon={CheckIcon} className='verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
</dd>
</dl>
))}
</div>
</div>
</div>
)}

@ -3,7 +3,6 @@
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
"account.follows": "Follows",
"account.follows_you": "Follows you",
"account.joined": "Joined {date}",
"account.suspended_disclaimer_full": "This user has been suspended by a moderator.",
"account.view_full_profile": "View full profile",
"advanced_options.icon_title": "Advanced options",

@ -1244,6 +1244,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 {
@ -5330,7 +5341,7 @@ a.status-card.compact:hover {
border-bottom: 1px solid lighten($ui-base-color, 8%);
display: flex;
flex-direction: row;
padding: 10px 0;
padding: 8px 0;
}
.language-dropdown {
@ -7978,6 +7989,7 @@ noscript {
.account__header {
overflow: hidden;
container: account-header / inline-size;
&.inactive {
opacity: 0.5;
@ -7999,6 +8011,7 @@ noscript {
height: 145px;
position: relative;
background: darken($ui-base-color, 4%);
border-bottom: 1px solid lighten($ui-base-color, 8%);
img {
object-fit: cover;
@ -8011,9 +8024,9 @@ noscript {
&__bar {
position: relative;
background: lighten($ui-base-color, 4%);
padding: 5px;
border-bottom: 1px solid lighten($ui-base-color, 12%);
padding: 0 20px;
padding-bottom: 16px; // glitch-soc addition for the different tabs design
border-bottom: 1px solid lighten($ui-base-color, 8%);
.avatar {
display: block;
@ -8022,7 +8035,7 @@ noscript {
.account__avatar {
background: darken($ui-base-color, 8%);
border: 2px solid lighten($ui-base-color, 4%);
border: 2px solid $ui-base-color;
}
}
}
@ -8041,8 +8054,8 @@ noscript {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 7px 10px;
margin-top: -55px;
padding-top: 10px;
gap: 8px;
overflow: hidden;
margin-inline-start: -2px; // aligns the pfp with content below
@ -8073,11 +8086,22 @@ noscript {
width: 24px;
height: 24px;
}
&.copied {
border-color: $valid-value-color;
}
}
@container account-header (max-width: 372px) {
.optional {
display: none;
}
}
}
&__name {
padding: 5px 10px;
margin-top: 16px;
margin-bottom: 16px;
.emojione {
width: 22px;
@ -8085,17 +8109,17 @@ noscript {
}
h1 {
font-size: 16px;
line-height: 24px;
font-size: 17px;
line-height: 22px;
color: $primary-text-color;
font-weight: 500;
font-weight: 700;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
small {
display: block;
font-size: 14px;
font-size: 15px;
color: $darker-text-color;
font-weight: 400;
overflow: hidden;
@ -8121,63 +8145,97 @@ noscript {
}
&__bio {
overflow: hidden;
margin: 0 -5px;
.account__header__content {
padding: 20px 15px;
padding-bottom: 5px;
color: $primary-text-color;
}
.account__header__joined {
font-size: 14px;
padding: 5px 15px;
color: $darker-text-color;
.account__header__fields {
margin: 0;
margin-top: 16px;
border-radius: 4px;
background: darken($ui-base-color, 4%);
border: 0;
.columns-area--mobile & {
padding-inline-start: 20px;
padding-inline-end: 20px;
dl {
display: block;
padding: 8px 16px; // glitch-soc: padding purposefuly reduced
border-bottom-color: lighten($ui-base-color, 4%);
}
}
.account__header__fields {
margin: 0;
border-top: 1px solid lighten($ui-base-color, 12%);
dd,
dt {
font-size: 13px;
line-height: 18px;
padding: 0;
text-align: initial;
}
a {
color: lighten($ui-highlight-color, 8%);
dt {
width: auto;
background: transparent;
text-transform: uppercase;
color: $dark-text-color;
}
dl:first-child .verified {
border-radius: 0 4px 0 0;
dd {
color: $darker-text-color;
}
a {
color: lighten($ui-highlight-color, 8%);
}
.icon {
width: 18px;
height: 18px;
vertical-align: middle;
}
dd {
display: flex;
align-items: center;
gap: 4px;
}
.verified {
border: 1px solid rgba($valid-value-color, 0.5);
margin-top: -1px;
&:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
margin-top: 0;
}
&:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
dt,
dd {
color: $valid-value-color;
}
dd {
display: flex;
align-items: center;
gap: 4px;
span {
display: flex;
}
}
.verified a {
color: $valid-value-color;
a {
color: $valid-value-color;
}
}
}
}
&__extra {
margin-top: 4px;
margin-top: 16px;
&__links {
font-size: 14px;
color: $darker-text-color;
padding: 10px 0;
margin: 0 -10px;
padding-top: 16px;
padding-bottom: 10px;
a {
display: inline-block;
@ -8195,14 +8253,10 @@ noscript {
}
&__account-note {
margin: 0 -5px;
padding: 10px 15px;
display: flex;
flex-direction: column;
color: $primary-text-color;
font-size: 14px;
font-weight: 400;
border-top: 1px solid lighten($ui-base-color, 12%);
border-bottom: 1px solid lighten($ui-base-color, 12%);
margin-bottom: 10px;
label {
display: block;
@ -8213,23 +8267,12 @@ noscript {
margin-bottom: 5px;
}
&__content {
white-space: pre-wrap;
padding: 10px 0;
}
strong {
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
}
textarea {
display: block;
box-sizing: border-box;
width: calc(100% + 20px);
color: $secondary-text-color;
background: $ui-base-color;
background: transparent;
padding: 10px;
margin: 0 -10px;
font-family: inherit;
@ -8243,6 +8286,10 @@ noscript {
color: $dark-text-color;
opacity: 1;
}
&:focus {
background: $ui-base-color;
}
}
}
}

@ -25,7 +25,7 @@ module Mastodon
end
def catstodon_revision
'1.0.0'
'1.0.1'
end
def build_metadata

Loading…
Cancel
Save