Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
NoaHimesaka1873 committed Feb 19, 2024
2 parents 0350808 + bbecf1c commit 30343e8
Show file tree
Hide file tree
Showing 15 changed files with 293 additions and 315 deletions.
1 change: 1 addition & 0 deletions app/javascript/flavours/glitch/api_types/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ export interface ApiAccountJSON {
suspended?: boolean;
limited?: boolean;
memorial?: boolean;
hide_collections: boolean;
}
43 changes: 43 additions & 0 deletions app/javascript/flavours/glitch/components/copy_icon_button.jsx
Original file line number Diff line number Diff line change
@@ -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,
};
30 changes: 3 additions & 27 deletions app/javascript/flavours/glitch/components/media_gallery.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,7 @@ import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
import { IconButton } from './icon_button';

const messages = defineMessages({
hidden: {
defaultMessage: 'Media hidden',
id: 'status.media_hidden',
},
sensitive: {
defaultMessage: 'Sensitive',
id: 'media_gallery.sensitive',
},
toggle: {
defaultMessage: 'Click to view',
id: 'status.sensitive_toggle',
},
toggle_visible: {
defaultMessage: '{number, plural, one {Hide image} other {Hide images}}',
id: 'media_gallery.toggle_visible',
},
warning: {
defaultMessage: 'Sensitive content',
id: 'status.sensitive_warning',
},
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: '{number, plural, one {Hide image} other {Hide images}}' },
});

class Item extends PureComponent {
Expand Down Expand Up @@ -299,8 +280,8 @@ class MediaGallery extends PureComponent {
this.props.onOpenMedia(this.props.media, index, this.props.lang);
};

handleRef = (node) => {
this.node = node;
handleRef = c => {
this.node = c;

if (this.node) {
this._setDimensions();
Expand Down Expand Up @@ -379,11 +360,6 @@ class MediaGallery extends PureComponent {
<div className={computedClass} style={style} ref={this.handleRef}>
<div className={classNames('spoiler-button', { 'spoiler-button--minified': visible && !uncached, 'spoiler-button--click-thru': uncached })}>
{spoilerButton}
{visible && sensitive && (
<span className='sensitive-marker'>
<FormattedMessage {...messages.sensitive} />
</span>
)}
</div>

{children}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/flavours/glitch/components/setting_text.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class SettingText extends PureComponent {
<label>
<span style={{ display: 'none' }}>{label}</span>
<input
className='setting-text'
className='glitch-setting-text'
value={settings.getIn(settingPath)}
onChange={this.handleChange}
placeholder={label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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}' },
Expand Down Expand Up @@ -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>);
Expand All @@ -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 = '';
Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -350,6 +352,7 @@ class Header extends ImmutablePureComponent {
<>
{actionBtn}
{bellBtn}
{shareBtn}
</>
)}

Expand All @@ -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>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
if (!contents) {
contents = (
<>
{icon && <Icon className='icon' id={icon} icon={iconComponent} />}
{icon && (
<div className='privacy-dropdown__option__icon'>
<Icon className='icon' id={icon} icon={iconComponent} />
</div>
)}

<div className='privacy-dropdown__option__content'>
<strong>{text}</strong>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ class ToggleOptionImpl extends ImmutablePureComponent {

return (
<>
<Toggle checked={checked} onChange={this.handleChange} />
<div className='privacy-dropdown__option__icon'>
<Toggle checked={checked} onChange={this.handleChange} />
</div>

<div className='privacy-dropdown__option__content'>
<strong>{text}</strong>
Expand Down
5 changes: 4 additions & 1 deletion app/javascript/flavours/glitch/features/followers/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const mapStateToProps = (state, { params: { acct, id } }) => {
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'followers', accountId, 'isLoading'], true),
suspended: state.getIn(['accounts', accountId, 'suspended'], false),
hideCollections: state.getIn(['accounts', accountId, 'hide_collections'], false),
hidden: getAccountHidden(state, accountId),
};
};
Expand Down Expand Up @@ -117,7 +118,7 @@ class Followers extends ImmutablePureComponent {
};

render () {
const { accountId, accountIds, hasMore, isAccount, multiColumn, isLoading, suspended, hidden, remote, remoteUrl } = this.props;
const { accountId, accountIds, hasMore, isAccount, multiColumn, isLoading, suspended, hidden, remote, remoteUrl, hideCollections } = this.props;

if (!isAccount) {
return (
Expand All @@ -141,6 +142,8 @@ class Followers extends ImmutablePureComponent {
emptyMessage = <FormattedMessage id='empty_column.account_suspended' defaultMessage='Account suspended' />;
} else if (hidden) {
emptyMessage = <LimitedAccountHint accountId={accountId} />;
} else if (hideCollections && accountIds.isEmpty()) {
emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />;
} else if (remote && accountIds.isEmpty()) {
emptyMessage = <RemoteHint url={remoteUrl} />;
} else {
Expand Down
5 changes: 4 additions & 1 deletion app/javascript/flavours/glitch/features/following/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const mapStateToProps = (state, { params: { acct, id } }) => {
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
isLoading: state.getIn(['user_lists', 'following', accountId, 'isLoading'], true),
suspended: state.getIn(['accounts', accountId, 'suspended'], false),
hideCollections: state.getIn(['accounts', accountId, 'hide_collections'], false),
hidden: getAccountHidden(state, accountId),
};
};
Expand Down Expand Up @@ -117,7 +118,7 @@ class Following extends ImmutablePureComponent {
};

render () {
const { accountId, accountIds, hasMore, isAccount, multiColumn, isLoading, suspended, hidden, remote, remoteUrl } = this.props;
const { accountId, accountIds, hasMore, isAccount, multiColumn, isLoading, suspended, hidden, remote, remoteUrl, hideCollections } = this.props;

if (!isAccount) {
return (
Expand All @@ -141,6 +142,8 @@ class Following extends ImmutablePureComponent {
emptyMessage = <FormattedMessage id='empty_column.account_suspended' defaultMessage='Account suspended' />;
} else if (hidden) {
emptyMessage = <LimitedAccountHint accountId={accountId} />;
} else if (hideCollections && accountIds.isEmpty()) {
emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />;
} else if (remote && accountIds.isEmpty()) {
emptyMessage = <RemoteHint url={remoteUrl} />;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { Avatar } from 'flavours/glitch/components/avatar';
import { DisplayName } from 'flavours/glitch/components/display_name';
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
import StatusContent from 'flavours/glitch/components/status_content';

import { IconButton } from '../../../components/icon_button';

export default class ActionsModal extends ImmutablePureComponent {
Expand Down Expand Up @@ -58,33 +53,9 @@ export default class ActionsModal extends ImmutablePureComponent {
};

render () {
const status = this.props.status && (
<div className='status light'>
<div className='boost-modal__status-header'>
<div className='boost-modal__status-time'>
<a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
<RelativeTimestamp timestamp={this.props.status.get('created_at')} />
</a>
</div>

<a href={this.props.status.getIn(['account', 'url'])} className='status__display-name' rel='noopener noreferrer'>
<div className='status__avatar'>
<Avatar account={this.props.status.get('account')} size={48} />
</div>

<DisplayName account={this.props.status.get('account')} />
</a>
</div>

<StatusContent status={this.props.status} />
</div>
);

return (
<div className='modal-root__modal actions-modal'>
{status}

<ul className={classNames({ 'with-status': !!status })}>
<ul>
{this.props.actions.map(this.renderAction)}
</ul>
</div>
Expand Down
3 changes: 0 additions & 3 deletions app/javascript/flavours/glitch/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -53,7 +52,6 @@
"keyboard_shortcuts.bookmark": "to bookmark",
"keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
"keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
"media_gallery.sensitive": "Sensitive",
"moved_to_warning": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
"navigation_bar.app_settings": "App settings",
"navigation_bar.featured_users": "Featured users",
Expand Down Expand Up @@ -158,7 +156,6 @@
"status.is_poll": "This toot is a poll",
"status.local_only": "Only visible from your instance",
"status.react": "React",
"status.sensitive_toggle": "Click to view",
"status.uncollapse": "Uncollapse",
"suggestions.dismiss": "Dismiss suggestion"
}
Loading

0 comments on commit 30343e8

Please sign in to comment.