th: live from new york it's friday night
various critical fixes (pls don't report this to NVD)
This commit is contained in:
parent
e9dbe31776
commit
c1910db65f
14 changed files with 973 additions and 951 deletions
873
.yarn/releases/yarn-3.4.1.cjs
vendored
873
.yarn/releases/yarn-3.4.1.cjs
vendored
File diff suppressed because one or more lines are too long
893
.yarn/releases/yarn-4.1.0.cjs
vendored
Executable file
893
.yarn/releases/yarn-4.1.0.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
10
.yarnrc.yml
10
.yarnrc.yml
|
@ -1,9 +1,9 @@
|
|||
enableGlobalCache: true
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.4.1.cjs
|
||||
|
||||
logFilters:
|
||||
- code: YN0013
|
||||
level: ${YARN_NOISE_LOG_CODE_LEVEL:-info}
|
||||
level: "${YARN_NOISE_LOG_CODE_LEVEL:-info}"
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.1.0.cjs
|
||||
|
|
|
@ -189,7 +189,7 @@ RUN \
|
|||
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
||||
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||
# Install Node packages
|
||||
yarn workspaces focus --production @mastodon/mastodon;
|
||||
yarn workspaces focus --production @mastodon/mastodon
|
||||
|
||||
# Create temporary assets build layer from build layer
|
||||
FROM build as precompiler
|
||||
|
|
|
@ -363,8 +363,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
/>
|
||||
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon={reblogIcon} iconComponent={reblogIconComponent} onClick={this.handleReblogClick} counter={withCounters ? status.get('reblogs_count') : undefined} />
|
||||
{/* FIXME: this is hilariously broken :( */}
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={true /* !publicStatus && !reblogPrivate */} /* active={status.get('reblogged')} */ title={quoteTitle} icon={quoteIcon} iconComponent={quoteIconComponent} onClick={this.handleQuoteClick} />
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} /* active={status.get('reblogged')} */ title={quoteTitle} icon={quoteIcon} iconComponent={quoteIconComponent} onClick={this.handleQuoteClick} />
|
||||
|
||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
||||
<IconButton className='status__action-bar-button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
||||
|
|
|
@ -372,17 +372,17 @@ class StatusContent extends PureComponent {
|
|||
let quoteStatusDisplayName = { __html: quoteStatusAccount.get('display_name_html') };
|
||||
|
||||
quote = (
|
||||
<div class="status__quote">
|
||||
<div className='status__quote'>
|
||||
<blockquote>
|
||||
<bdi>
|
||||
<span class="quote-display-name">
|
||||
<span className='quote-display-name'>
|
||||
<Icon
|
||||
fixedWidth
|
||||
icon='quote-right'
|
||||
id='quote-right'
|
||||
aria-hidden='true'
|
||||
key='icon-quote-right' />
|
||||
<strong class="display-name__html">
|
||||
<strong className='display-name__html'>
|
||||
<a onClick={this.handleAccountClick} href={quoteStatus.getIn(['account', 'url'])} dangerouslySetInnerHTML={quoteStatusDisplayName} />
|
||||
</strong>
|
||||
</span>
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
// Package imports.
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
// Components.
|
||||
import AccountContainer from 'flavours/glitch/containers/account_container';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
||||
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'flavours/glitch/utils/react_router';
|
||||
|
||||
import { Avatar } from '../../../components/avatar';
|
||||
import { DisplayName } from '../../../components/display_name';
|
||||
import { Icon } from '../../../components/icon';
|
||||
import { IconButton } from '../../../components/icon_button';
|
||||
|
||||
// Messages.
|
||||
const messages = defineMessages({
|
||||
|
@ -19,19 +24,23 @@ const messages = defineMessages({
|
|||
},
|
||||
});
|
||||
|
||||
|
||||
class QuoteIndicator extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onCancel: PropTypes.func,
|
||||
intl: PropTypes.object.isRequired,
|
||||
...WithOptionalRouterPropTypes,
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
const { onCancel } = this.props;
|
||||
if (onCancel) {
|
||||
onCancel();
|
||||
this.props.onCancel();
|
||||
};
|
||||
|
||||
handleAccountClick = (e) => {
|
||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
this.props.history?.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,40 +52,28 @@ class QuoteIndicator extends ImmutablePureComponent {
|
|||
return null;
|
||||
}
|
||||
|
||||
const account = status.get('account');
|
||||
const content = status.get('content');
|
||||
const attachments = status.get('media_attachments');
|
||||
const content = { __html: status.get('contentHtml') };
|
||||
|
||||
// The result.
|
||||
return (
|
||||
<article className='quote-indicator'>
|
||||
<header className='quote-indicator__header'>
|
||||
<IconButton
|
||||
className='quote-indicator__cancel'
|
||||
icon='times'
|
||||
onClick={this.handleClick}
|
||||
title={intl.formatMessage(messages.cancel)}
|
||||
inverted
|
||||
/>
|
||||
<Icon
|
||||
className='quote-indicator__cancel icon-button inverted'
|
||||
icon='quote-right'
|
||||
id='quote-right' />
|
||||
{account && (
|
||||
<AccountContainer
|
||||
id={account}
|
||||
small
|
||||
/>
|
||||
)}
|
||||
<div className='quote-indicator__cancel'>
|
||||
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted />
|
||||
</div>
|
||||
|
||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='quote-indicator__display-name' target='_blank' rel='noopener noreferrer'>
|
||||
<div className='quote-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||
<DisplayName account={status.get('account')} inline />
|
||||
</a>
|
||||
</header>
|
||||
<div
|
||||
className='quote-indicator__content icon-button translate'
|
||||
dangerouslySetInnerHTML={{ __html: content || '' }}
|
||||
/>
|
||||
{attachments.size > 0 && (
|
||||
|
||||
<div className='quote-indicator__content translate' dangerouslySetInnerHTML={content} />
|
||||
|
||||
{status.get('media_attachments').size > 0 && (
|
||||
<AttachmentList
|
||||
compact
|
||||
media={attachments}
|
||||
media={status.get('media_attachments')}
|
||||
/>
|
||||
)}
|
||||
</article>
|
||||
|
@ -85,4 +82,4 @@ class QuoteIndicator extends ImmutablePureComponent {
|
|||
|
||||
}
|
||||
|
||||
export default injectIntl(QuoteIndicator)
|
||||
export default withOptionalRouter(injectIntl(QuoteIndicator));
|
||||
|
|
|
@ -54,9 +54,6 @@ class ReplyIndicator extends ImmutablePureComponent {
|
|||
<div className='reply-indicator__cancel'>
|
||||
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted />
|
||||
</div>
|
||||
<div className='quote-indicator__cancel'>
|
||||
<Icon className='icon-button inverted' id='reply' />
|
||||
</div>
|
||||
|
||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name' target='_blank' rel='noopener noreferrer'>
|
||||
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { cancelQuoteCompose } from 'flavours/glitch/actions/compose';
|
||||
import { makeGetStatus } from '../../../selectors';
|
||||
import QuoteIndicator from '../components/quote_indicator';
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getStatus = makeGetStatus();
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const statusId = state.getIn(['compose', 'quote_id']);
|
||||
const statusId = state.getIn(['compose', 'quote_id'], null);
|
||||
const editing = false;
|
||||
|
||||
return {
|
||||
status: state.getIn(['statuses', statusId]),
|
||||
status: getStatus(state, { id: statusId }),
|
||||
editing,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m228-240 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T458-480L320-240h-92Zm360 0 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T818-480L680-240h-92Z"/></svg>
|
After Width: | Height: | Size: 322 B |
1
app/javascript/material-icons/400-24px/format_quote.svg
Normal file
1
app/javascript/material-icons/400-24px/format_quote.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m228-240 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T458-480L320-240h-92Zm360 0 92-160q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 23-5.5 42.5T818-480L680-240h-92ZM320-500q25 0 42.5-17.5T380-560q0-25-17.5-42.5T320-620q-25 0-42.5 17.5T260-560q0 25 17.5 42.5T320-500Zm360 0q25 0 42.5-17.5T740-560q0-25-17.5-42.5T680-620q-25 0-42.5 17.5T620-560q0 25 17.5 42.5T680-500Zm0-60Zm-360 0Z"/></svg>
|
After Width: | Height: | Size: 538 B |
|
@ -180,11 +180,11 @@ class Status < ApplicationRecord
|
|||
quote: [
|
||||
:application,
|
||||
:tags,
|
||||
:preview_cards,
|
||||
:media_attachments,
|
||||
:conversation,
|
||||
:status_stat,
|
||||
:preloadable_poll,
|
||||
preview_cards_status: [:preview_card],
|
||||
account: [:account_stat, :user],
|
||||
active_mentions: { account: :account_stat },
|
||||
],
|
||||
|
|
|
@ -1,35 +1,38 @@
|
|||
.status.quote-status{ dataurl: ActivityPub::TagManager.instance.url_for(status) }
|
||||
= link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener' do
|
||||
= link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener noreferrer' do
|
||||
.status__avatar
|
||||
%div
|
||||
= image_tag status.account.avatar_static_url, width: 18, height: 18, alt: '', class: 'u-photo account__avatar'
|
||||
- if prefers_autoplay?
|
||||
= image_tag status.account.avatar_original_url, alt: '', class: 'u-photo account__avatar'
|
||||
- else
|
||||
= image_tag status.account.avatar_static_url, alt: '', class: 'u-photo account__avatar'
|
||||
%span.display-name
|
||||
%bdi
|
||||
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true)
|
||||
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: prefers_autoplay?)
|
||||
|
||||
%span.display-name__account
|
||||
= acct(status.account)
|
||||
= fa_icon('lock') if status.account.locked?
|
||||
|
||||
.status__content.emojify<
|
||||
- if status.spoiler_text?
|
||||
%p{ style: ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
|
||||
%span.p-summary> #{Formatter.instance.format_spoiler(status)}
|
||||
%button.status__content__spoiler-link= t('statuses.show_more')
|
||||
.e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}" }
|
||||
= Formatter.instance.format_in_quote(status, custom_emojify: true)
|
||||
.status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
|
||||
|
||||
- if !status.media_attachments.empty?
|
||||
- if status.media_attachments.first.video?
|
||||
- video = status.media_attachments.first
|
||||
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), blurhash: video.blurhash, sensitive: (!current_account&.user&.show_all_media? && status.sensitive?) || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description, quote: true do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- elsif status.media_attachments.first.audio?
|
||||
- audio = status.media_attachments.first
|
||||
= react_component :audio, src: audio.file.url(:original), height: 60, alt: audio.description, duration: audio.file.meta.dig(:original, :duration) do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- if status.spoiler_text?
|
||||
%p<
|
||||
%span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)}
|
||||
%button.status__content__spoiler-link= t('statuses.show_more')
|
||||
.e-content{ lang: status.language }<
|
||||
= prerender_custom_emojis(status_content_format(status), status.emojis)
|
||||
|
||||
- if status.preloadable_poll
|
||||
= render_poll_component(status)
|
||||
|
||||
- if !status.ordered_media_attachments.empty?
|
||||
- if status.ordered_media_attachments.first.video?
|
||||
= render_video_component(status, width: 610, height: 343)
|
||||
- elsif status.ordered_media_attachments.first.audio?
|
||||
= render_audio_component(status, width: 610, height: 343)
|
||||
- else
|
||||
= react_component :media_gallery, height: 343, sensitive: (!current_account&.user&.show_all_media? && status.sensitive?) || current_account&.user&.hide_all_media?, autoPlayGif: current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }, quote: true do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
= render_media_gallery_component(status, height: 343)
|
||||
- elsif status.preview_card
|
||||
= react_component :card, maxDescription: 10, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json, quote: true
|
||||
= render_card_component(status)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@mastodon/mastodon",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"packageManager": "yarn@4.0.2",
|
||||
"packageManager": "yarn@4.1.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue