Merge branch 'develop' into 'captcha_reload_on_click'

# Conflicts:
#   app/soapbox/locales/defaultMessages.json
merge-requests/98/merge
Curtis 2020-07-03 20:11:09 +00:00
commit c28cc228a2
93 zmienionych plików z 1458 dodań i 43 usunięć

Wyświetl plik

@ -1,4 +1,3 @@
NODE_ENV=development
# BACKEND_URL="https://example.com"
# PATRON_URL="https://patron.example.com"
# PROXY_HTTPS_INSECURE=false

Wyświetl plik

@ -124,7 +124,7 @@ For https, be sure to also set `PROXY_HTTPS_INSECURE=true`.
Allows using an HTTPS backend if set to `true`.
This is needed if `BACKEND_URL` or `PATRON_URL` are set to an `https://` value.
This is needed if `BACKEND_URL` is set to an `https://` value.
[More info](https://stackoverflow.com/a/48624590/8811886).
**Default:** `false`

Wyświetl plik

@ -5,7 +5,7 @@ export const PATRON_FUNDING_FETCH_FAIL = 'PATRON_FUNDING_FETCH_FAIL';
export function fetchFunding() {
return (dispatch, getState) => {
api(getState).get('/patron/v1/funding').then(response => {
api(getState).get('/api/patron/v1/instance').then(response => {
dispatch(importFetchedFunding(response.data));
}).catch(error => {
dispatch(fetchFundingFail(error));

Wyświetl plik

@ -11,6 +11,7 @@ import { decode } from 'blurhash';
import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio';
import { Map as ImmutableMap } from 'immutable';
import { getSettings } from 'soapbox/actions/settings';
import Icon from 'soapbox/components/icon';
import StillImage from 'soapbox/components/still_image';
const messages = defineMessages({
@ -192,6 +193,24 @@ class Item extends React.PureComponent {
<span className='media-gallery__gifv__label'>GIF</span>
</div>
);
} else if (attachment.get('type') === 'audio') {
const remoteURL = attachment.get('remote_url');
const originalUrl = attachment.get('url');
const fileExtensionLastIndex = remoteURL.lastIndexOf('.');
const fileExtension = remoteURL.substr(fileExtensionLastIndex + 1).toUpperCase();
thumbnail = (
<a
className={classNames('media-gallery__item-thumbnail')}
href={attachment.get('remote_url') || originalUrl}
onClick={this.handleClick}
target='_blank'
alt={attachment.get('description')}
title={attachment.get('description')}
>
<span className='media-gallery__item__icons'><Icon id='volume-up' /></span>
<span className='media-gallery__file-extension__label'>{fileExtension}</span>
</a>
);
}
return (

Wyświetl plik

@ -39,11 +39,13 @@ const messages = defineMessages({
const mapStateToProps = state => {
const me = state.get('me');
const getAccount = makeGetAccount();
const patronEnabled = state.getIn(['soapbox', 'extensions', 'patron', 'enabled']);
const patronUrl = state.getIn(['soapbox', 'extensions', 'patron', 'baseUrl']);
return {
account: getAccount(state, me),
sidebarOpen: state.get('sidebar').sidebarOpen,
hasPatron: state.getIn(['soapbox', 'extensions', 'patron']),
patronUrl: patronEnabled && patronUrl,
isStaff: isStaff(state.getIn(['accounts', me])),
};
};
@ -75,7 +77,7 @@ class SidebarMenu extends ImmutablePureComponent {
}
render() {
const { sidebarOpen, onClose, intl, account, onClickLogOut, hasPatron, isStaff } = this.props;
const { sidebarOpen, onClose, intl, account, onClickLogOut, patronUrl, isStaff } = this.props;
if (!account) return null;
const acct = account.get('acct');
@ -127,11 +129,11 @@ class SidebarMenu extends ImmutablePureComponent {
<Icon id='envelope' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.messages)}</span>
</NavLink>
{hasPatron ?
<NavLink className='sidebar-menu-item' to='/donate' onClick={onClose}>
{patronUrl ?
<a className='sidebar-menu-item' href={patronUrl} onClick={onClose}>
<Icon id='dollar' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.donate)}</span>
</NavLink>
</a>
: ''}
<NavLink className='sidebar-menu-item' to='/lists' onClick={onClose}>
<Icon id='list' />

Wyświetl plik

@ -12,7 +12,7 @@ import AttachmentList from './attachment_list';
import Card from '../features/status/components/card';
import { injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { MediaGallery, Video } from '../features/ui/util/async-components';
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
import { HotKeys } from 'react-hotkeys';
import classNames from 'classnames';
import Icon from 'soapbox/components/icon';
@ -73,6 +73,7 @@ class Status extends ImmutablePureComponent {
onPin: PropTypes.func,
onOpenMedia: PropTypes.func,
onOpenVideo: PropTypes.func,
onOpenAudio: PropTypes.func,
onBlock: PropTypes.func,
onEmbed: PropTypes.func,
onHeightChange: PropTypes.func,
@ -194,10 +195,18 @@ class Status extends ImmutablePureComponent {
return <div className='media-spoiler-video' style={{ height: '110px' }} />;
}
renderLoadingAudioPlayer() {
return <div className='media-spoiler-audio' style={{ height: '110px' }} />;
}
handleOpenVideo = (media, startTime) => {
this.props.onOpenVideo(media, startTime);
}
handleOpenAudio = (media, startTime) => {
this.props.OnOpenAudio(media, startTime);
}
handleHotkeyReply = e => {
e.preventDefault();
this.props.onReply(this._properStatus(), this.context.router.history);
@ -356,6 +365,24 @@ class Status extends ImmutablePureComponent {
)}
</Bundle>
);
} else if (status.getIn(['media_attachments', 0, 'type']) === 'audio' && status.get('media_attachments').size === 1) {
const audio = status.getIn(['media_attachments', 0]);
media = (
<Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
{Component => (
<Component
src={audio.get('url')}
alt={audio.get('description')}
inline
sensitive={status.get('sensitive')}
cacheWidth={this.props.cacheMediaWidth}
visible={this.state.showMedia}
onOpenAudio={this.handleOpenAudio}
/>
)}
</Bundle>
);
} else {
media = (
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>

Wyświetl plik

@ -146,6 +146,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
dispatch(openModal('VIDEO', { media, time }));
},
onOpenAudio(media, time) {
dispatch(openModal('AUDIO', { media, time }));
},
onBlock(status) {
const account = status.get('account');
dispatch(openModal('CONFIRM', {

Wyświetl plik

@ -146,6 +146,16 @@ class MediaItem extends ImmutablePureComponent {
<span className='media-gallery__gifv__label'>GIF</span>
</div>
);
} else if (attachment.get('type') === 'audio') {
const remoteURL = attachment.get('remote_url');
const fileExtensionLastIndex = remoteURL.lastIndexOf('.');
const fileExtension = remoteURL.substr(fileExtensionLastIndex + 1).toUpperCase();
thumbnail = (
<div className='media-gallery__item-thumbnail'>
<span className='media-gallery__item__icons'><Icon id='volume-up' /></span>
<span className='media-gallery__file-extension__label'>{fileExtension}</span>
</div>
);
}
if (!visible) {

Wyświetl plik

@ -0,0 +1,380 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { throttle } from 'lodash';
import classNames from 'classnames';
import Icon from 'soapbox/components/icon';
import { getSettings } from 'soapbox/actions/settings';
const messages = defineMessages({
play: { id: 'audio.play', defaultMessage: 'Play' },
pause: { id: 'audio.pause', defaultMessage: 'Pause' },
mute: { id: 'audio.mute', defaultMessage: 'Mute' },
unmute: { id: 'audio.unmute', defaultMessage: 'Unmute' },
hide: { id: 'audio.hide', defaultMessage: 'Hide audio' },
expand: { id: 'audio.expand', defaultMessage: 'Expand audio' },
close: { id: 'audio.close', defaultMessage: 'Close audio' },
});
const formatTime = secondsNum => {
let hours = Math.floor(secondsNum / 3600);
let minutes = Math.floor((secondsNum - (hours * 3600)) / 60);
let seconds = secondsNum - (hours * 3600) - (minutes * 60);
if (hours < 10) hours = '0' + hours;
if (minutes < 10 && hours >= 1) minutes = '0' + minutes;
if (seconds < 10) seconds = '0' + seconds;
return (hours === '00' ? '' : `${hours}:`) + `${minutes}:${seconds}`;
};
export const findElementPosition = el => {
let box;
if (el.getBoundingClientRect && el.parentNode) {
box = el.getBoundingClientRect();
}
if (!box) {
return {
left: 0,
top: 0,
};
}
const docEl = document.documentElement;
const body = document.body;
const clientLeft = docEl.clientLeft || body.clientLeft || 0;
const scrollLeft = window.pageXOffset || body.scrollLeft;
const left = (box.left + scrollLeft) - clientLeft;
const clientTop = docEl.clientTop || body.clientTop || 0;
const scrollTop = window.pageYOffset || body.scrollTop;
const top = (box.top + scrollTop) - clientTop;
return {
left: Math.round(left),
top: Math.round(top),
};
};
export const getPointerPosition = (el, event) => {
const position = {};
const box = findElementPosition(el);
const boxW = el.offsetWidth;
const boxH = el.offsetHeight;
const boxY = box.top;
const boxX = box.left;
let pageY = event.pageY;
let pageX = event.pageX;
if (event.changedTouches) {
pageX = event.changedTouches[0].pageX;
pageY = event.changedTouches[0].pageY;
}
position.y = Math.max(0, Math.min(1, (pageY - boxY) / boxH));
position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
return position;
};
const mapStateToProps = state => ({
displayMedia: getSettings(state).get('displayMedia'),
});
export default @connect(mapStateToProps)
@injectIntl
class Audio extends React.PureComponent {
static propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string,
sensitive: PropTypes.bool,
startTime: PropTypes.number,
detailed: PropTypes.bool,
inline: PropTypes.bool,
cacheWidth: PropTypes.func,
visible: PropTypes.bool,
onToggleVisibility: PropTypes.func,
intl: PropTypes.object.isRequired,
link: PropTypes.node,
displayMedia: PropTypes.string,
expandSpoilers: PropTypes.bool,
};
state = {
currentTime: 0,
duration: 0,
volume: 0.5,
paused: true,
dragging: false,
muted: false,
revealed: this.props.visible !== undefined ? this.props.visible : (this.props.displayMedia !== 'hide_all' && !this.props.sensitive || this.props.displayMedia === 'show_all'),
};
// hard coded in components.scss
// any way to get ::before values programatically?
volWidth = 50;
volOffset = 85;
volHandleOffset = v => {
const offset = v * this.volWidth + this.volOffset;
return (offset > 125) ? 125 : offset;
}
setPlayerRef = c => {
this.player = c;
if (c) {
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
this.setState({
containerWidth: c.offsetWidth,
});
}
}
setAudioRef = c => {
this.audio = c;
if (this.audio) {
this.setState({ volume: this.audio.volume, muted: this.audio.muted });
}
}
setSeekRef = c => {
this.seek = c;
}
setVolumeRef = c => {
this.volume = c;
}
handleClickRoot = e => e.stopPropagation();
handlePlay = () => {
this.setState({ paused: false });
}
handlePause = () => {
this.setState({ paused: true });
}
handleTimeUpdate = () => {
this.setState({
currentTime: Math.floor(this.audio.currentTime),
duration: Math.floor(this.audio.duration),
});
}
handleVolumeMouseDown = e => {
document.addEventListener('mousemove', this.handleMouseVolSlide, true);
document.addEventListener('mouseup', this.handleVolumeMouseUp, true);
document.addEventListener('touchmove', this.handleMouseVolSlide, true);
document.addEventListener('touchend', this.handleVolumeMouseUp, true);
this.handleMouseVolSlide(e);
e.preventDefault();
e.stopPropagation();
}
handleVolumeMouseUp = () => {
document.removeEventListener('mousemove', this.handleMouseVolSlide, true);
document.removeEventListener('mouseup', this.handleVolumeMouseUp, true);
document.removeEventListener('touchmove', this.handleMouseVolSlide, true);
document.removeEventListener('touchend', this.handleVolumeMouseUp, true);
}
handleMouseVolSlide = throttle(e => {
const rect = this.volume.getBoundingClientRect();
const x = (e.clientX - rect.left) / this.volWidth; //x position within the element.
if(!isNaN(x)) {
var slideamt = x;
if(x > 1) {
slideamt = 1;
} else if(x < 0) {
slideamt = 0;
}
this.audio.volume = slideamt;
this.setState({ volume: slideamt });
}
}, 60);
handleMouseDown = e => {
document.addEventListener('mousemove', this.handleMouseMove, true);
document.addEventListener('mouseup', this.handleMouseUp, true);
document.addEventListener('touchmove', this.handleMouseMove, true);
document.addEventListener('touchend', this.handleMouseUp, true);
this.setState({ dragging: true });
this.audio.pause();
this.handleMouseMove(e);
e.preventDefault();
e.stopPropagation();
}
handleMouseUp = () => {
document.removeEventListener('mousemove', this.handleMouseMove, true);
document.removeEventListener('mouseup', this.handleMouseUp, true);
document.removeEventListener('touchmove', this.handleMouseMove, true);
document.removeEventListener('touchend', this.handleMouseUp, true);
this.setState({ dragging: false });
this.audio.play();
}
handleMouseMove = throttle(e => {
const { x } = getPointerPosition(this.seek, e);
const currentTime = Math.floor(this.audio.duration * x);
if (!isNaN(currentTime)) {
this.audio.currentTime = currentTime;
this.setState({ currentTime });
}
}, 60);
togglePlay = () => {
if (this.state.paused) {
this.audio.play();
} else {
this.audio.pause();
}
}
toggleMute = () => {
this.audio.muted = !this.audio.muted;
this.setState({ muted: this.audio.muted });
}
toggleWarning = () => {
this.setState({ revealed: !this.state.revealed });
}
handleLoadedData = () => {
if (this.props.startTime) {
this.audio.currentTime = this.props.startTime;
this.audio.play();
}
}
handleProgress = () => {
if (this.audio.buffered.length > 0) {
this.setState({ buffer: this.audio.buffered.end(0) / this.audio.duration * 100 });
}
}
handleVolumeChange = () => {
this.setState({ volume: this.audio.volume, muted: this.audio.muted });
}
getPreload = () => {
const { startTime, detailed } = this.props;
const { dragging } = this.state;
if (startTime || dragging) {
return 'auto';
} else if (detailed) {
return 'metadata';
} else {
return 'none';
}
}
render() {
const { src, inline, intl, alt, detailed, sensitive, link } = this.props;
const { currentTime, duration, volume, buffer, dragging, paused, muted, revealed } = this.state;
const progress = (currentTime / duration) * 100;
const volumeWidth = (muted) ? 0 : volume * this.volWidth;
const volumeHandleLoc = (muted) ? this.volHandleOffset(0) : this.volHandleOffset(volume);
const playerStyle = {};
let warning;
if (sensitive) {
warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />;
} else {
warning = <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />;
}
return (
<div
role='menuitem'
className={classNames('audio-player', { detailed: detailed, inline: inline, warning_visible: !revealed })}
style={playerStyle}
ref={this.setPlayerRef}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onClick={this.handleClickRoot}
tabIndex={0}
>
<audio
ref={this.setAudioRef}
src={src}
// preload={this.getPreload()}
role='button'
tabIndex='0'
aria-label={alt}
title={alt}
volume={volume}
onClick={this.togglePlay}
onPlay={this.handlePlay}
onPause={this.handlePause}
onTimeUpdate={this.handleTimeUpdate}
onLoadedData={this.handleLoadedData}
onProgress={this.handleProgress}
onVolumeChange={this.handleVolumeChange}
/>
<div className={classNames('audio-player__spoiler-warning', { 'spoiler-button--hidden': revealed })}>
<span className='audio-player__spoiler-warning__label'><Icon id='warning' fixedWidth /> {warning}</span>
<button aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleWarning}><Icon id='times' fixedWidth /></button>
</div>
<div className={classNames('audio-player__controls')}>
<div className='audio-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
<div className='audio-player__seek__buffer' style={{ width: `${buffer}%` }} />
<div className='audio-player__seek__progress' style={{ width: `${progress}%` }} />
<span
className={classNames('audio-player__seek__handle', { active: dragging })}
tabIndex='0'
style={{ left: `${progress}%` }}
/>
</div>
<div className='audio-player__buttons-bar'>
<div className='audio-player__buttons left'>
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
<div className='audio-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
<div className='audio-player__volume__current' style={{ width: `${volumeWidth}px` }} />
<span
className={classNames('audio-player__volume__handle')}
tabIndex='0'
style={{ left: `${volumeHandleLoc}px` }}
/>
</div>
<span>
<span className='audio-player__time-current'>{formatTime(currentTime)}</span>
<span className='audio-player__time-sep'>/</span>
<span className='audio-player__time-total'>{formatTime(duration)}</span>
</span>
{link && <span className='audio-player__link'>{link}</span>}
</div>
</div>
</div>
</div>
);
}
}

Wyświetl plik

@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4, MOV)' },
upload: { id: 'upload_button.label', defaultMessage: 'Add media attachment' },
});
const makeMapStateToProps = () => {

Wyświetl plik

@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import Toggle from 'react-toggle';
import noop from 'lodash/noop';
import StatusContent from '../../../components/status_content';
import { MediaGallery, Video } from '../../ui/util/async-components';
import { MediaGallery, Video, Audio } from '../../ui/util/async-components';
import Bundle from '../../ui/components/bundle';
export default class StatusCheckBox extends React.PureComponent {
@ -48,6 +48,22 @@ export default class StatusCheckBox extends React.PureComponent {
)}
</Bundle>
);
} else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
const audio = status.getIn(['media_attachments', 0]);
media = (
<Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
{Component => (
<Component
src={audio.get('url')}
alt={audio.get('description')}
inline
sensitive={status.get('sensitive')}
onOpenAudio={noop}
/>
)}
</Bundle>
);
} else {
media = (
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >

Wyświetl plik

@ -10,6 +10,7 @@ import { FormattedDate, FormattedNumber } from 'react-intl';
import Card from './card';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Video from '../../video';
import Audio from '../../audio';
import scheduleIdleTask from '../../ui/util/schedule_idle_task';
import classNames from 'classnames';
import Icon from 'soapbox/components/icon';
@ -120,6 +121,19 @@ export default class DetailedStatus extends ImmutablePureComponent {
onToggleVisibility={this.props.onToggleMediaVisibility}
/>
);
} else if (status.getIn(['media_attachments', 0, 'type']) === 'audio' && status.get('media_attachments').size === 1) {
const audio = status.getIn(['media_attachments', 0]);
media = (
<Audio
src={audio.get('url')}
alt={audio.get('description')}
inline
sensitive={status.get('sensitive')}
visible={this.props.showMedia}
onToggleVisibility={this.props.onToggleMediaVisibility}
/>
);
} else {
media = (
<MediaGallery

Wyświetl plik

@ -5,6 +5,16 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ProgressBar from '../../../components/progress_bar';
import { fetchFunding } from 'soapbox/actions/patron';
const moneyFormat = amount => (
new Intl
.NumberFormat('en-US', {
style: 'currency',
currency: 'usd',
notation: 'compact',
})
.format(amount/100)
);
class FundingPanel extends ImmutablePureComponent {
componentDidMount() {
@ -12,21 +22,22 @@ class FundingPanel extends ImmutablePureComponent {
}
render() {
const { funding } = this.props;
const { funding, patronUrl } = this.props;
if (!funding) {
return null;
}
const amount = funding.getIn(['funding', 'amount']);
const goal = funding.getIn(['goals', '0', 'amount']);
const goal_text = funding.getIn(['goals', '0', 'text']);
const goal_reached = funding.get('amount') >= goal;
const goal_reached = amount >= goal;
let ratio_text;
if (goal_reached) {
ratio_text = <><strong>${Math.floor(goal/100)}</strong> per month<span className='funding-panel__reached'>&mdash; reached!</span></>;
ratio_text = <><strong>{moneyFormat(goal)}</strong> per month<span className='funding-panel__reached'>&mdash; reached!</span></>;
} else {
ratio_text = <><strong>${Math.floor(funding.get('amount')/100)} out of ${Math.floor(goal/100)}</strong> per month</>;
ratio_text = <><strong>{moneyFormat(amount)} out of {moneyFormat(goal)}</strong> per month</>;
}
return (
@ -41,11 +52,11 @@ class FundingPanel extends ImmutablePureComponent {
<div className='funding-panel__ratio'>
{ratio_text}
</div>
<ProgressBar progress={funding.get('amount')/goal} />
<ProgressBar progress={amount/goal} />
<div className='funding-panel__description'>
{goal_text}
</div>
<a className='button' href='/donate'>Donate</a>
{patronUrl && <a className='button' href={patronUrl}>Donate</a>}
</div>
</div>
);
@ -56,6 +67,7 @@ class FundingPanel extends ImmutablePureComponent {
const mapStateToProps = state => {
return {
funding: state.getIn(['patron', 'funding']),
patronUrl: state.getIn(['soapbox', 'extensions', 'patron', 'baseUrl']),
};
};

Wyświetl plik

@ -3,6 +3,7 @@ import ReactSwipeableViews from 'react-swipeable-views';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Video from 'soapbox/features/video';
import Audio from 'soapbox/features/audio';
import ExtendedVideoPlayer from 'soapbox/components/extended_video_player';
import classNames from 'classnames';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
@ -138,9 +139,18 @@ class MediaModal extends ImmutablePureComponent {
});
}
const isMultiMedia = media.map((image) => {
if (image.get('type') !== 'image') {
return true;
}
return false;
}).toArray();
const content = media.map((image) => {
const width = image.getIn(['meta', 'original', 'width']) || null;
const height = image.getIn(['meta', 'original', 'height']) || null;
const link = (status && <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>);
if (image.get('type') === 'image') {
return (
@ -167,6 +177,20 @@ class MediaModal extends ImmutablePureComponent {
startTime={time || 0}
onCloseVideo={onClose}
detailed
link={link}
alt={image.get('description')}
key={image.get('url')}
/>
);
} else if (image.get('type') === 'audio') {
const { time } = this.props;
return (
<Audio
src={image.get('url')}
startTime={time || 0}
detailed
link={link}
alt={image.get('description')}
key={image.get('url')}
/>
@ -178,6 +202,7 @@ class MediaModal extends ImmutablePureComponent {
muted
controls={false}
width={width}
link={link}
height={height}
key={image.get('preview_url')}
alt={image.get('description')}
@ -230,7 +255,7 @@ class MediaModal extends ImmutablePureComponent {
{leftNav}
{rightNav}
{status && (
{(status && !isMultiMedia[index]) && (
<div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}>
<a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
</div>

Wyświetl plik

@ -142,6 +142,10 @@ export function Video() {
return import(/* webpackChunkName: "features/video" */'../../video');
}
export function Audio() {
return import(/* webpackChunkName: "features/audio" */'../../audio');
}
export function EmbedModal() {
return import(/* webpackChunkName: "modals/embed_modal" */'../components/embed_modal');
}

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "لقد طرأ هناك خطأ غير متوقّع.",
"alert.unexpected.title": "المعذرة!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "يمكنك/ي ضغط {combo} لتخطّي هذه في المرّة القادمة",
"bundle_column_error.body": "لقد وقع هناك خطأ أثناء عملية تحميل هذا العنصر.",
"bundle_column_error.retry": "إعادة المحاولة",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Asocedió un fallu inesperáu.",
"alert.unexpected.title": "¡Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Pues primir {combo} pa saltar esto la próxima vegada",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Опитай отново",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "অপ্রত্যাশিত একটি সমস্যা হয়েছে।",
"alert.unexpected.title": "ওহো!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "পরেরবার আপনি {combo} চাপ দিলে এটার শেষে চলে যেতে পারবেন",
"bundle_column_error.body": "এই অংশটি দেখতে যেয়ে কোনো সমস্যা হয়েছে।",
"bundle_column_error.retry": "আবার চেষ্টা করুন",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.",
"alert.unexpected.title": "C'hem !",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Klask endro",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "S'ha produït un error inesperat.",
"alert.unexpected.title": "Vaja!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop",
"bundle_column_error.body": "S'ha produït un error en carregar aquest component.",
"bundle_column_error.retry": "Torna-ho a provar",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.",
"alert.unexpected.title": "Uups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta",
"bundle_column_error.body": "C'hè statu un prublemu caricandu st'elementu.",
"bundle_column_error.retry": "Pruvà torna",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "Žádná média k zobrazení.",
"alert.unexpected.message": "Objevila se neočekávaná chyba.",
"alert.unexpected.title": "Jejda!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Příště můžete pro přeskočení stisknout {combo}",
"bundle_column_error.body": "Při načítání tohoto komponentu se něco pokazilo.",
"bundle_column_error.retry": "Zkuste to znovu",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
"alert.unexpected.title": "Wps!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Mae modd gwasgu {combo} er mwyn sgipio hyn tro nesa",
"bundle_column_error.body": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
"bundle_column_error.retry": "Ceisiwch eto",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Der opstod en uventet fejl.",
"alert.unexpected.title": "Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang",
"bundle_column_error.body": "Noget gik galt under indlæsningen af dette komponent.",
"bundle_column_error.retry": "Prøv igen",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "Keine Medien vorhanden.",
"alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.",
"alert.unexpected.title": "Hoppla!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Drücke {combo}, um dieses Fenster zu überspringen",
"bundle_column_error.body": "Etwas ist beim Laden schiefgelaufen.",
"bundle_column_error.retry": "Erneut versuchen",

Wyświetl plik

@ -867,11 +867,43 @@
{
"descriptors": [
{
"defaultMessage": "Click the image to get a new captcha",
"id": "registration.captcha.hint"
"defaultMessage": "Play",
"id": "audio.play"
},
{
"defaultMessage": "Pause",
"id": "audio.pause"
},
{
"defaultMessage": "Mute",
"id": "audio.mute"
},
{
"defaultMessage": "Unmute",
"id": "audio.unmute"
},
{
"defaultMessage": "Hide audio",
"id": "audio.hide"
},
{
"defaultMessage": "Expand audio",
"id": "audio.expand"
},
{
"defaultMessage": "Close audio",
"id": "audio.close"
},
{
"defaultMessage": "Sensitive content",
"id": "status.sensitive_warning"
},
{
"defaultMessage": "Media hidden",
"id": "status.media_hidden"
}
],
"path": "app/soapbox/features/auth_login/components/captcha.json"
"path": "app/soapbox/features/audio/index.json"
},
{
"descriptors": [
@ -1226,7 +1258,7 @@
{
"descriptors": [
{
"defaultMessage": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
"defaultMessage": "Add media attachment",
"id": "upload_button.label"
}
],

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.",
"alert.unexpected.title": "Εεπ!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις αυτό την επόμενη φορά",
"bundle_column_error.body": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.",
"bundle_column_error.retry": "Δοκίμασε ξανά",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",
@ -451,7 +458,7 @@
"unauthorized_modal.text": "You need to be logged in to do that.",
"unauthorized_modal.title": "Sign up for {site_title}",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_button.label": "Add media attachment",
"upload_error.limit": "File upload limit exceeded.",
"upload_error.poll": "File upload not allowed with polls.",
"upload_form.description": "Describe for the visually impaired",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Neatendita eraro okazis.",
"alert.unexpected.title": "Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
"bundle_column_error.body": "Io misfunkciis en la ŝargado de ĉi tiu elemento.",
"bundle_column_error.retry": "Bonvolu reprovi",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ocurrió un error inesperado.",
"alert.unexpected.title": "¡Epa!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Podés hacer clic en {combo} para saltar esto la próxima vez",
"bundle_column_error.body": "Algo salió mal al cargar este componente.",
"bundle_column_error.retry": "Intentá de nuevo",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Hubo un error inesperado.",
"alert.unexpected.title": "¡Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez",
"bundle_column_error.body": "Algo salió mal al cargar este componente.",
"bundle_column_error.retry": "Inténtalo de nuevo",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Tekkis ootamatu viga.",
"alert.unexpected.title": "Oih!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Saad vajutada {combo}, et see järgmine kord vahele jätta",
"bundle_column_error.body": "Mindagi läks valesti selle komponendi laadimisel.",
"bundle_column_error.retry": "Proovi uuesti",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ustekabeko errore bat gertatu da.",
"alert.unexpected.title": "Ene!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko",
"bundle_column_error.body": "Zerbait okerra gertatu da osagai hau kargatzean.",
"bundle_column_error.retry": "Saiatu berriro",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "خطای پیش‌بینی‌نشده‌ای رخ داد.",
"alert.unexpected.title": "ای وای!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید",
"bundle_column_error.body": "هنگام بازکردن این بخش خطایی رخ داد.",
"bundle_column_error.retry": "تلاش دوباره",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Tapahtui odottamaton virhe.",
"alert.unexpected.title": "Hups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}",
"bundle_column_error.body": "Jokin meni vikaan komponenttia ladattaessa.",
"bundle_column_error.retry": "Yritä uudestaan",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Une erreur inattendue sest produite.",
"alert.unexpected.title": "Oups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci, la prochaine fois",
"bundle_column_error.body": "Une erreur sest produite lors du chargement de ce composant.",
"bundle_column_error.retry": "Réessayer",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Aconteceu un fallo non agardado.",
"alert.unexpected.title": "Vaia!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Pulse {combo} para saltar esto a próxima vez",
"bundle_column_error.body": "Houbo un fallo mentras se cargaba este compoñente.",
"bundle_column_error.retry": "Inténteo de novo",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "אירעה שגיאה בלתי צפויה.",
"alert.unexpected.title": "אופס!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
"bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.",
"bundle_column_error.retry": "לנסות שוב",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Možeš pritisnuti {combo} kako bi ovo preskočio sljedeći put",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Váratlan hiba történt.",
"alert.unexpected.title": "Hoppá!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Hogy átugord ezt következő alkalommal, használd {combo}",
"bundle_column_error.body": "Hiba történt a komponens betöltése közben.",
"bundle_column_error.retry": "Próbáld újra",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Վա՜յ",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Կարող ես սեղմել {combo}՝ սա հաջորդ անգամ բաց թողնելու համար",
"bundle_column_error.body": "Այս բաղադրիչը բեռնելու ընթացքում ինչ֊որ բան խափանվեց։",
"bundle_column_error.retry": "Կրկին փորձել",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Terjadi kesalahan yang tidak terduga.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Anda dapat menekan {combo} untuk melewati ini",
"bundle_column_error.body": "Kesalahan terjadi saat memuat komponen ini.",
"bundle_column_error.retry": "Coba lagi",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Tu povas presar sur {combo} por omisar co en la venonta foyo",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Si è verificato un errore inatteso.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio la prossima volta",
"bundle_column_error.body": "E' avvenuto un errore durante il caricamento di questo componente.",
"bundle_column_error.retry": "Riprova",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "不明なエラーが発生しました。",
"alert.unexpected.title": "エラー!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "次からは{combo}を押せばスキップできます",
"bundle_column_error.body": "コンポーネントの読み込み中に問題が発生しました。",
"bundle_column_error.retry": "再試行",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "წარმოიშვა მოულოდნელი შეცდომა.",
"alert.unexpected.title": "უპს!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "შეგიძლიათ დააჭიროთ {combo}-ს რათა შემდეგ ჯერზე გამოტოვოთ ეს",
"bundle_column_error.body": "ამ კომპონენტის ჩატვირთვისას რაღაც აირია.",
"bundle_column_error.retry": "სცადეთ კიდევ ერთხელ",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Бір нәрсе дұрыс болмады.",
"alert.unexpected.title": "Өй!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Келесіде өткізіп жіберу үшін басыңыз {combo}",
"bundle_column_error.body": "Бұл компонентті жүктеген кезде бір қате пайда болды.",
"bundle_column_error.retry": "Қайтадан көріңіз",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.",
"alert.unexpected.title": "앗!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "{combo}를 누르면 다음부터 이 과정을 건너뛸 수 있습니다",
"bundle_column_error.body": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.",
"bundle_column_error.retry": "다시 시도",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Negaidīta kļūda.",
"alert.unexpected.title": "Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Nospied {combo} lai izlaistu šo nākamreiz",
"bundle_column_error.body": "Kaut kas nogāja greizi ielādējot šo komponenti.",
"bundle_column_error.retry": "Mēģini vēlreiz",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Неочекувана грешка.",
"alert.unexpected.title": "Упс!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Кликни {combo} за да го прескокниш ова нареден пат",
"bundle_column_error.body": "Се случи проблем при вчитувањето.",
"bundle_column_error.retry": "Обидете се повторно",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Er deed zich een onverwachte fout voor",
"alert.unexpected.title": "Oeps!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Je kunt {combo} klikken om dit de volgende keer over te slaan",
"bundle_column_error.body": "Tijdens het laden van dit onderdeel is er iets fout gegaan.",
"bundle_column_error.retry": "Opnieuw proberen",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Eit uforventa problem har hendt.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Du kan trykke {combo} for å hoppe over dette neste gong",
"bundle_column_error.body": "Noko gikk gale mens komponent ble nedlasta.",
"bundle_column_error.retry": "Prøv igjen",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "You kan trykke {combo} for å hoppe over dette neste gang",
"bundle_column_error.body": "Noe gikk galt mens denne komponenten lastet.",
"bundle_column_error.retry": "Prøv igjen",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Una error ses producha.",
"alert.unexpected.title": "Ops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Podètz botar {combo} per passar aquò lo còp que ven",
"bundle_column_error.body": "Quicòm a fach mèuca pendent lo cargament daqueste compausant.",
"bundle_column_error.retry": "Tornar ensajar",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Wystąpił nieoczekiwany błąd.",
"alert.unexpected.title": "O nie!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Naciśnij {combo}, aby pominąć to następnym razem",
"bundle_column_error.body": "Coś poszło nie tak podczas ładowania tego składnika.",
"bundle_column_error.retry": "Spróbuj ponownie",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Um erro inesperado ocorreu.",
"alert.unexpected.title": "Eita!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Você pode pressionar {combo} para ignorar este diálogo na próxima vez",
"bundle_column_error.body": "Algo de errado aconteceu enquanto este componente era carregado.",
"bundle_column_error.retry": "Tente novamente",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ocorreu um erro inesperado.",
"alert.unexpected.title": "Bolas!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Pode clicar {combo} para não voltar a ver",
"bundle_column_error.body": "Algo de errado aconteceu enquanto este componente era carregado.",
"bundle_column_error.retry": "Tente de novo",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "A apărut o eroare neașteptată.",
"alert.unexpected.title": "Hopa!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Poți apăsa {combo} pentru a omite asta data viitoare",
"bundle_column_error.body": "Ceva nu a funcționat la încărcarea acestui component.",
"bundle_column_error.retry": "Încearcă din nou",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Что-то пошло не так.",
"alert.unexpected.title": "Ой!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Нажмите {combo}, чтобы пропустить это в следующий раз",
"bundle_column_error.body": "Что-то пошло не так при загрузке этого компонента.",
"bundle_column_error.retry": "Попробовать снова",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Vyskytla sa nečakaná chyba.",
"alert.unexpected.title": "Ups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie",
"bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.",
"bundle_column_error.retry": "Skús to znova",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Zgodila se je nepričakovana napaka.",
"alert.unexpected.title": "Uups!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Če želite preskočiti to, lahko pritisnete {combo}",
"bundle_column_error.body": "Med nalaganjem te komponente je prišlo do napake.",
"bundle_column_error.retry": "Poskusi ponovno",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ndodhi një gabim të papritur.",
"alert.unexpected.title": "Hëm!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Mund të shtypni {combo}, që të anashkalohet kjo herës tjetër",
"bundle_column_error.body": "Diç shkoi ters teksa ngarkohej ky përbërës.",
"bundle_column_error.retry": "Riprovoni",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put",
"bundle_column_error.body": "Nešto je pošlo po zlu prilikom učitavanja ove komponente.",
"bundle_column_error.retry": "Pokušajte ponovo",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Појавила се неочекивана грешка.",
"alert.unexpected.title": "Упс!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
"bundle_column_error.body": "Нешто је пошло по злу приликом учитавања ове компоненте.",
"bundle_column_error.retry": "Покушајте поново",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Ett oväntat fel uppstod.",
"alert.unexpected.title": "Hoppsan!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Du kan trycka {combo} för att slippa denna nästa gång",
"bundle_column_error.body": "Något gick fel när du laddade denna komponent.",
"bundle_column_error.retry": "Försök igen",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "எதிர் பாராத பிழை ஏற்பட்டு விட்டது.",
"alert.unexpected.title": "அச்சச்சோ!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "நீங்கள் அழுத்தவும் {combo} அடுத்த முறை தவிர்க்கவும்",
"bundle_column_error.body": "இந்த கூறுகளை ஏற்றும்போது ஏதோ தவறு ஏற்பட்டது.",
"bundle_column_error.retry": "மீண்டும் முயற்சி செய்",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "అనుకోని తప్పు జరిగినది.",
"alert.unexpected.title": "అయ్యో!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "మీరు తదుపరిసారి దీనిని దాటవేయడానికి {combo} నొక్కవచ్చు",
"bundle_column_error.body": "ఈ భాగం లోడ్ అవుతున్నప్పుడు ఏదో తప్పు జరిగింది.",
"bundle_column_error.retry": "మళ్ళీ ప్రయత్నించండి",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด",
"alert.unexpected.title": "อุปส์!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "คุณสามารถกด {combo} เพื่อข้ามสิ่งนี้ในครั้งถัดไป",
"bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้",
"bundle_column_error.retry": "ลองอีกครั้ง",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Beklenmedik bir hata oluştu.",
"alert.unexpected.title": "Hay aksi!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Bir daha ki sefere {combo} tuşuna basabilirsiniz",
"bundle_column_error.body": "Bu bileşen yüklenirken bir şeyler ters gitti.",
"bundle_column_error.retry": "Tekrar deneyin",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "Трапилась неочікувана помилка.",
"alert.unexpected.title": "Ой!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу",
"bundle_column_error.body": "Щось пішло не так під час завантаження компоненту.",
"bundle_column_error.retry": "Спробуйте ще раз",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "发生了意外错误。",
"alert.unexpected.title": "哎呀!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "下次按住 {combo} 即可跳过此提示",
"bundle_column_error.body": "载入这个组件时发生了错误。",
"bundle_column_error.retry": "重试",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "發生不可預期的錯誤。",
"alert.unexpected.title": "噢!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "如你想在下次路過這顯示,請按{combo}",
"bundle_column_error.body": "加載本組件出錯。",
"bundle_column_error.retry": "重試",

Wyświetl plik

@ -43,6 +43,13 @@
"account_gallery.none": "No media to show.",
"alert.unexpected.message": "發生了非預期的錯誤。",
"alert.unexpected.title": "哎呀!",
"audio.close": "Close audio",
"audio.expand": "Expand audio",
"audio.hide": "Hide audio",
"audio.mute": "Mute",
"audio.pause": "Pause",
"audio.play": "Play",
"audio.unmute": "Unmute",
"boost_modal.combo": "下次您可以按 {combo} 跳過",
"bundle_column_error.body": "載入此元件時發生錯誤。",
"bundle_column_error.retry": "重試",

Wyświetl plik

@ -16,7 +16,7 @@ const mapStateToProps = state => {
const me = state.get('me');
return {
account: state.getIn(['accounts', me]),
hasPatron: state.getIn(['soapbox', 'extensions', 'patron']),
hasPatron: state.getIn(['soapbox', 'extensions', 'patron', 'enabled']),
features: getFeatures(state.get('instance')),
};
};

Wyświetl plik

@ -14,6 +14,8 @@ describe('media_attachments reducer', () => {
'.mp4',
'.m4v',
'.mov',
'.mp3',
'.ogg',
'image/jpeg',
'image/png',
'image/gif',
@ -21,6 +23,9 @@ describe('media_attachments reducer', () => {
'video/webm',
'video/mp4',
'video/quicktime',
'audio/mp3',
'audio/mpeg',
'audio/ogg',
]),
}));
});

Wyświetl plik

@ -16,6 +16,8 @@ const initialState = ImmutableMap({
'.mp4',
'.m4v',
'.mov',
'.mp3',
'.ogg',
'image/jpeg',
'image/png',
'image/gif',
@ -23,6 +25,9 @@ const initialState = ImmutableMap({
'video/webm',
'video/mp4',
'video/quicktime',
'audio/mp3',
'audio/mpeg',
'audio/ogg',
]),
});

Wyświetl plik

@ -399,6 +399,10 @@ a .account__avatar {
bottom: 0;
right: 0;
z-index: 1;
&.still-image {
position: absolute;
}
}
}

Wyświetl plik

@ -69,3 +69,4 @@
@import 'components/media-spoiler';
@import 'components/error-boundary';
@import 'components/video-player';
@import 'components/audio-player';

Wyświetl plik

@ -0,0 +1,397 @@
.audio-error-cover {
align-items: center;
background: var(--background-color);
color: var(--primary-text-color);
cursor: pointer;
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
margin-top: 8px;
position: relative;
text-align: center;
z-index: 100;
}
.status__audio-player {
background: var(--background-color);
box-sizing: border-box;
cursor: default; /* May not be needed */
margin-top: 8px;
overflow: hidden;
position: relative;
}
.status__audio-player-audio {
height: 100%;
object-fit: cover;
position: relative;
top: 50%;
transform: translateY(-50%);
width: 100%;
z-index: 1;
}
.status__audio-player-expand,
.status__audio-player-mute {
color: var(--primary-text-color);
opacity: 0.8;
position: absolute;
right: 4px;
text-shadow: 0 1px 1px $base-shadow-color, 1px 0 1px $base-shadow-color;
}
.status__audio-player-expand {
bottom: 4px;
z-index: 100;
}
.status__audio-player-mute {
top: 4px;
z-index: 5;
}
.detailed,
.fullscreen {
.audio-player__volume__current,
.audio-player__volume::before {
bottom: 27px;
}
.audio-player__volume__handle {
bottom: 23px;
}
}
.audio-player {
overflow: hidden;
position: relative;
background: $base-shadow-color;
max-width: 100%;
border-radius: 4px;
height: 57px;
&.warning_visible {
height: 92px;
}
&:focus {
outline: 0;
}
audio {
max-width: 100vw;
max-height: 80vh;
min-height: 120px;
object-fit: contain;
z-index: 1;
}
&.fullscreen {
width: 100% !important;
height: 100% !important;
margin: 0;
audio {
max-width: 100% !important;
max-height: 100% !important;
width: 100% !important;
height: 100% !important;
}
}
&.inline {
audio {
object-fit: contain;
position: relative;
}
}
&__controls {
position: absolute;
z-index: 2;
bottom: 0;
left: 0;
right: 0;
box-sizing: border-box;
background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent);
padding: 0 15px;
opacity: 1;
transition: opacity .1s ease;
}
&.inactive {
min-height: 57px;
audio,
.audio-player__controls {
visibility: hidden;
}
}
&__spoiler {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 4;
border: 0;
background: var(--background-color);
color: var(--primary-text-color--faint);
transition: none;
pointer-events: auto;
&:hover,
&:active,
&:focus {
color: var(--primary-text-color);
}
&__title {
display: block;
font-size: 14px;
}
&__subtitle {
display: block;
font-size: 11px;
font-weight: 500;
}
}
&__buttons-bar {
display: flex;
justify-content: space-between;
padding-bottom: 10px;
}
&__spoiler-warning {
font-size: 16px;
white-space: nowrap;
overlow: hidden;
text-overflow: ellipsis;
background: hsl( var(--brand-color_h), var(--brand-color_s), 20% );
padding: 5px;
&__label {
color: white;
}
button {
background: transparent;
font-size: 16px;
border: 0;
color: rgba(#ffffff, 0.75);
position: absolute;
right: 0;
padding-right: 5px;
i {
margin-right: 0;
}
&:active,
&:hover,
&:focus {
color: #ffffff;
}
}
}
&__buttons {
font-size: 16px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&.left {
button {
padding-left: 0;
}
}
button {
background: transparent;
padding: 2px 10px;
font-size: 16px;
border: 0;
color: rgba(#ffffff, 0.75);
&:active,
&:hover,
&:focus {
color: #ffffff;
}
}
}
&__time-sep,
&__time-total,
&__time-current {
font-size: 14px;
font-weight: 500;
}
&__time-current {
color: #ffffff;
margin-left: 60px;
}
&__time-sep {
display: inline-block;
margin: 0 6px;
}
&__time-sep,
&__time-total {
color: #ffffff;
}
&__volume {
cursor: pointer;
height: 24px;
display: inline;
&::before {
content: "";
width: 50px;
background: rgba(#ffffff, 0.35);
border-radius: 4px;
display: block;
position: absolute;
height: 4px;
left: 85px;
bottom: 20px;
}
&__current {
display: block;
position: absolute;
height: 4px;
border-radius: 4px;
left: 85px;
bottom: 20px;
background: var(--brand-color);
}
&__handle {
position: absolute;
z-index: 3;
border-radius: 50%;
width: 12px;
height: 12px;
bottom: 16px;
left: 70px;
transition: opacity .1s ease;
background: var(--brand-color);
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
pointer-events: none;
}
}
&__link {
padding: 2px 10px;
a {
text-decoration: none;
font-size: 14px;
font-weight: 500;
color: #ffffff;
&:hover,
&:active,
&:focus {
text-decoration: underline;
}
}
}
&__seek {
cursor: pointer;
height: 24px;
position: relative;
&::before {
content: "";
width: 100%;
background: rgba(#ffffff, 0.35);
border-radius: 4px;
display: block;
position: absolute;
height: 4px;
top: 10px;
}
&__progress,
&__buffer {
display: block;
position: absolute;
height: 4px;
border-radius: 4px;
top: 10px;
background: var(--brand-color);
}
&__buffer {
background: rgba(#ffffff, 0.2);
}
&__handle {
position: absolute;
z-index: 3;
opacity: 1;
border-radius: 50%;
width: 12px;
height: 12px;
top: 6px;
margin-left: -6px;
transition: opacity .1s ease;
background: var(--brand-color);
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
pointer-events: none;
}
&:hover {
.audio-player__seek__handle {
opacity: 1;
}
}
}
&.detailed {
width: 100vmin;
height: 80px;
.audio-player__buttons {
button {
padding-top: 10px;
padding-bottom: 10px;
}
}
}
}
.media-spoiler-audio {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
margin-top: 8px;
position: relative;
border: 0;
display: block;
}
.media-spoiler-audio-play-icon {
border-radius: 100px;
color: var(--primary-text-color--faint);
font-size: 36px;
left: 50%;
padding: 5px;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}

Wyświetl plik

@ -284,7 +284,7 @@
.compose-form__upload-thumbnail {
border-radius: 4px;
background-position: center;
background-size: cover;
background-size: contain;
background-repeat: no-repeat;
height: 140px;
width: 100%;

Wyświetl plik

@ -38,7 +38,8 @@
}
}
.video-player {
.video-player,
.audio-player {
margin-top: 8px;
}
}

Wyświetl plik

@ -16,6 +16,14 @@
position: relative;
border-radius: 4px;
overflow: hidden;
&__icons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 100px;
}
}
.media-gallery__item-thumbnail {
@ -31,6 +39,10 @@
.still-image {
height: 100%;
width: 100%;
img {
object-fit: contain;
}
}
.still-image--play-on-hover::before {
@ -108,7 +120,8 @@
position: absolute;
}
.media-gallery__gifv__label {
.media-gallery__gifv__label,
.media-gallery__file-extension__label {
display: block;
position: absolute;
color: var(--primary-text-color);

Wyświetl plik

@ -38,7 +38,8 @@
overflow-y: hidden;
}
.video-modal {
.video-modal,
.audio-modal {
max-width: 100vw;
max-height: 100vh;
position: relative;
@ -49,12 +50,16 @@
height: 100%;
position: relative;
.audio-player.detailed,
.extended-video-player {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.extended-video-player {
width: 100%;
height: 100%;
video {
max-width: $media-modal-media-max-width;

Wyświetl plik

@ -78,7 +78,8 @@
opacity: 1;
animation: fade 150ms linear;
.video-player {
.video-player,
.audio-player {
margin-top: 8px;
}
@ -176,7 +177,8 @@
white-space: normal;
}
.video-player {
.video-player,
.audio-player {
margin-top: 8px;
max-width: 250px;
}
@ -453,7 +455,8 @@ a.status-card {
margin: 0;
}
.status-card-video {
.status-card-video,
.status-card-audio {
iframe {
width: 100%;
height: 100%;

Wyświetl plik

@ -11,6 +11,10 @@
width: 100%;
background: var(--brand-color--faint);
.still-image {
height: 100%;
}
img {
display: block;
height: 100%;

Wyświetl plik

@ -1,6 +1,8 @@
# Customizing Soapbox
If you haven't already, [install Soapbox](https://soapbox.pub/).
If you haven't already, [install Soapbox](https://soapbox.pub/). But before you install soapbox, you should consider how Soapbox is installed, by default.
Soapbox, by default, is installed to replace the default Pleroma front end. By extension, the Pleroma Masto front end continues to be available at the `/web` sub-URL, which you can reference, if you'd like, in the `promoPanel` section of `soapbox.json`
There are two main places Soapbox gets its configuration:
@ -97,3 +99,9 @@ Simply rename `about.example` to `about`, or create your own.
The `soapbox.json` file navlinks section's default URL values are pointing to the above file location, when the `about.example` folder is renamed to `about`
These four template files have placeholders in them, e.g. "Your_Instance", that should be edited to match your Soapbox instance configuration, and will be meaningless to your users until you edit them.
## Alternate Soapbox URL Root Location
If you want to install Soapbox at an alternate URL, allowing you to potentially run more than 2 front ends on a Pleroma server, you can consider deploying the Nginx config created by @a1batross, available [here](https://git.mentality.rip/a1batross/soapbox-nginx-config/src/branch/master/soapbox.nginx)
Tech support is limited for this level of customization

Wyświetl plik

@ -12,9 +12,6 @@
"url": "https://blog.example.com"
}]
},
"extensions": {
"patron": false
},
"defaultSettings": {
"autoPlayGif": false,
"themeMode": "light"

Wyświetl plik

@ -9,7 +9,6 @@ const { settings, output } = require('./configuration');
const watchOptions = {};
const backendUrl = process.env.BACKEND_URL || 'http://localhost:4000';
const patronUrl = process.env.PATRON_URL || 'http://localhost:5000';
const secureProxy = !(process.env.PROXY_HTTPS_INSECURE === 'true');
const backendEndpoints = [
@ -22,7 +21,6 @@ const backendEndpoints = [
'/.well-known/webfinger',
'/static',
'/emoji',
'/patron',
];
const makeProxyConfig = () => {
@ -33,10 +31,6 @@ const makeProxyConfig = () => {
secure: secureProxy,
};
});
proxyConfig['/patron'] = {
target: patronUrl,
secure: secureProxy,
};
return proxyConfig;
};