th: live from new york it's friday night
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
various critical fixes (pls don't report this to NVD)streaming-builds
parent
e9dbe31776
commit
c1910db65f
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
.yarnrc.yml
10
.yarnrc.yml
|
@ -1,9 +1,9 @@
|
||||||
enableGlobalCache: true
|
enableGlobalCache: true
|
||||||
|
|
||||||
nodeLinker: node-modules
|
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-3.4.1.cjs
|
|
||||||
|
|
||||||
logFilters:
|
logFilters:
|
||||||
- code: YN0013
|
- 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=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 \
|
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||||
# Install Node packages
|
# Install Node packages
|
||||||
yarn workspaces focus --production @mastodon/mastodon;
|
yarn workspaces focus --production @mastodon/mastodon
|
||||||
|
|
||||||
# Create temporary assets build layer from build layer
|
# Create temporary assets build layer from build layer
|
||||||
FROM build as precompiler
|
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} />
|
<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={!publicStatus && !reblogPrivate} /* active={status.get('reblogged')} */ title={quoteTitle} icon={quoteIcon} iconComponent={quoteIconComponent} onClick={this.handleQuoteClick} />
|
||||||
<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='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 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} />
|
<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') };
|
let quoteStatusDisplayName = { __html: quoteStatusAccount.get('display_name_html') };
|
||||||
|
|
||||||
quote = (
|
quote = (
|
||||||
<div class="status__quote">
|
<div className='status__quote'>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<bdi>
|
<bdi>
|
||||||
<span class="quote-display-name">
|
<span className='quote-display-name'>
|
||||||
<Icon
|
<Icon
|
||||||
fixedWidth
|
fixedWidth
|
||||||
icon='quote-right'
|
icon='quote-right'
|
||||||
id='quote-right'
|
id='quote-right'
|
||||||
aria-hidden='true'
|
aria-hidden='true'
|
||||||
key='icon-quote-right' />
|
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} />
|
<a onClick={this.handleAccountClick} href={quoteStatus.getIn(['account', 'url'])} dangerouslySetInnerHTML={quoteStatusDisplayName} />
|
||||||
</strong>
|
</strong>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
// Package imports.
|
// Package imports.
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
|
||||||
// Components.
|
|
||||||
import AccountContainer from 'flavours/glitch/containers/account_container';
|
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
|
||||||
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
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.
|
// Messages.
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -19,19 +24,23 @@ const messages = defineMessages({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
class QuoteIndicator extends ImmutablePureComponent {
|
class QuoteIndicator extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
onCancel: PropTypes.func,
|
onCancel: PropTypes.func,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
...WithOptionalRouterPropTypes,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
const { onCancel } = this.props;
|
this.props.onCancel();
|
||||||
if (onCancel) {
|
};
|
||||||
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const account = status.get('account');
|
const content = { __html: status.get('contentHtml') };
|
||||||
const content = status.get('content');
|
|
||||||
const attachments = status.get('media_attachments');
|
|
||||||
|
|
||||||
// The result.
|
// The result.
|
||||||
return (
|
return (
|
||||||
<article className='quote-indicator'>
|
<article className='quote-indicator'>
|
||||||
<header className='quote-indicator__header'>
|
<header className='quote-indicator__header'>
|
||||||
<IconButton
|
<div className='quote-indicator__cancel'>
|
||||||
className='quote-indicator__cancel'
|
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted />
|
||||||
icon='times'
|
</div>
|
||||||
onClick={this.handleClick}
|
|
||||||
title={intl.formatMessage(messages.cancel)}
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='quote-indicator__display-name' target='_blank' rel='noopener noreferrer'>
|
||||||
inverted
|
<div className='quote-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||||
/>
|
<DisplayName account={status.get('account')} inline />
|
||||||
<Icon
|
</a>
|
||||||
className='quote-indicator__cancel icon-button inverted'
|
|
||||||
icon='quote-right'
|
|
||||||
id='quote-right' />
|
|
||||||
{account && (
|
|
||||||
<AccountContainer
|
|
||||||
id={account}
|
|
||||||
small
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</header>
|
</header>
|
||||||
<div
|
|
||||||
className='quote-indicator__content icon-button translate'
|
<div className='quote-indicator__content translate' dangerouslySetInnerHTML={content} />
|
||||||
dangerouslySetInnerHTML={{ __html: content || '' }}
|
|
||||||
/>
|
{status.get('media_attachments').size > 0 && (
|
||||||
{attachments.size > 0 && (
|
|
||||||
<AttachmentList
|
<AttachmentList
|
||||||
compact
|
compact
|
||||||
media={attachments}
|
media={status.get('media_attachments')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</article>
|
</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'>
|
<div className='reply-indicator__cancel'>
|
||||||
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted />
|
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted />
|
||||||
</div>
|
</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'>
|
<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>
|
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { cancelQuoteCompose } from 'flavours/glitch/actions/compose';
|
import { cancelQuoteCompose } from 'flavours/glitch/actions/compose';
|
||||||
|
import { makeGetStatus } from '../../../selectors';
|
||||||
import QuoteIndicator from '../components/quote_indicator';
|
import QuoteIndicator from '../components/quote_indicator';
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
|
const getStatus = makeGetStatus();
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const statusId = state.getIn(['compose', 'quote_id']);
|
const statusId = state.getIn(['compose', 'quote_id'], null);
|
||||||
const editing = false;
|
const editing = false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: state.getIn(['statuses', statusId]),
|
status: getStatus(state, { id: statusId }),
|
||||||
editing,
|
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 |
|
@ -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: [
|
quote: [
|
||||||
:application,
|
:application,
|
||||||
:tags,
|
:tags,
|
||||||
:preview_cards,
|
|
||||||
:media_attachments,
|
:media_attachments,
|
||||||
:conversation,
|
:conversation,
|
||||||
:status_stat,
|
:status_stat,
|
||||||
:preloadable_poll,
|
:preloadable_poll,
|
||||||
|
preview_cards_status: [:preview_card],
|
||||||
account: [:account_stat, :user],
|
account: [:account_stat, :user],
|
||||||
active_mentions: { account: :account_stat },
|
active_mentions: { account: :account_stat },
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,35 +1,38 @@
|
||||||
.status.quote-status{ dataurl: ActivityPub::TagManager.instance.url_for(status) }
|
.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
|
.status__avatar
|
||||||
%div
|
%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
|
%span.display-name
|
||||||
%bdi
|
%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
|
%span.display-name__account
|
||||||
= acct(status.account)
|
= acct(status.account)
|
||||||
= fa_icon('lock') if status.account.locked?
|
= fa_icon('lock') if status.account.locked?
|
||||||
|
|
||||||
.status__content.emojify<
|
.status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
|
||||||
- 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)
|
|
||||||
|
|
||||||
- if !status.media_attachments.empty?
|
- if status.spoiler_text?
|
||||||
- if status.media_attachments.first.video?
|
%p<
|
||||||
- video = status.media_attachments.first
|
%span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)}
|
||||||
= 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
|
%button.status__content__spoiler-link= t('statuses.show_more')
|
||||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
.e-content{ lang: status.language }<
|
||||||
- elsif status.media_attachments.first.audio?
|
= prerender_custom_emojis(status_content_format(status), status.emojis)
|
||||||
- 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
|
- if status.preloadable_poll
|
||||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
= 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
|
- 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_media_gallery_component(status, height: 343)
|
||||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
|
||||||
- elsif status.preview_card
|
- 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",
|
"name": "@mastodon/mastodon",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"packageManager": "yarn@4.0.2",
|
"packageManager": "yarn@4.1.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue