Progress
This commit is contained in:
parent
c15d4f12dc
commit
8e349c368c
|
@ -246,19 +246,20 @@ export function submitComposeFail(error) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_FAIL,
|
type: COMPOSE_SUBMIT_FAIL,
|
||||||
error: error,
|
error: error,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
export function uploadCompose(files) {
|
export function uploadCompose(files) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
if (!me) return;
|
if (!me) return
|
||||||
|
|
||||||
const uploadLimit = 4;
|
const uploadLimit = 4
|
||||||
const media = getState().getIn(['compose', 'media_attachments']);
|
const media = getState().getIn(['compose', 'media_attachments'])
|
||||||
|
const pending = getState().getIn(['compose', 'pending_media_attachments'])
|
||||||
const progress = new Array(files.length).fill(0);
|
const progress = new Array(files.length).fill(0);
|
||||||
let total = Array.from(files).reduce((a, v) => a + v.size, 0);
|
let total = Array.from(files).reduce((a, v) => a + v.size, 0);
|
||||||
|
|
||||||
if (files.length + media.size > uploadLimit) {
|
if (files.length + media.size + pending > uploadLimit) {
|
||||||
// dispatch(showAlert(undefined, messages.uploadErrorLimit));
|
// dispatch(showAlert(undefined, messages.uploadErrorLimit));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +274,7 @@ export function uploadCompose(files) {
|
||||||
for (const [i, f] of Array.from(files).entries()) {
|
for (const [i, f] of Array.from(files).entries()) {
|
||||||
if (media.size + i > 3) break;
|
if (media.size + i > 3) break;
|
||||||
|
|
||||||
resizeImage(f).then(file => {
|
resizeImage(f).then((file) => {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append('file', file);
|
data.append('file', file);
|
||||||
// Account for disparity in size of original image and resized data
|
// Account for disparity in size of original image and resized data
|
||||||
|
@ -285,7 +286,7 @@ export function uploadCompose(files) {
|
||||||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||||
},
|
},
|
||||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
|
||||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
}).catch(error => dispatch(uploadComposeFail(error, true)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -318,10 +319,11 @@ export function changeUploadComposeSuccess(media) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function changeUploadComposeFail(error) {
|
export function changeUploadComposeFail(error, decrement = false) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_CHANGE_FAIL,
|
type: COMPOSE_UPLOAD_CHANGE_FAIL,
|
||||||
error: error,
|
error: error,
|
||||||
|
decrement: decrement,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -157,15 +157,10 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('activeFilter:', activeFilter)
|
|
||||||
// console.log('excludeTypesFromSettings(getState()):', excludeTypesFromSettings(getState()))
|
|
||||||
console.log('excludeTypesFromFilter(activeFilter):', excludeTypesFromFilter(activeFilter))
|
|
||||||
|
|
||||||
// : todo :
|
|
||||||
// filter verified and following here too
|
|
||||||
const params = {
|
const params = {
|
||||||
max_id: maxId,
|
max_id: maxId,
|
||||||
exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter),
|
exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter),
|
||||||
|
// : todo : ?
|
||||||
// exclude_types: activeFilter === 'all'
|
// exclude_types: activeFilter === 'all'
|
||||||
// ? excludeTypesFromSettings(getState())
|
// ? excludeTypesFromSettings(getState())
|
||||||
// : excludeTypesFromFilter(activeFilter),
|
// : excludeTypesFromFilter(activeFilter),
|
||||||
|
@ -180,8 +175,6 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
|
||||||
|
|
||||||
dispatch(expandNotificationsRequest(isLoadingMore));
|
dispatch(expandNotificationsRequest(isLoadingMore));
|
||||||
|
|
||||||
console.log("params:", params)
|
|
||||||
|
|
||||||
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,14 @@ export const POPOVER_OPEN = 'POPOVER_OPEN'
|
||||||
export const POPOVER_CLOSE = 'POPOVER_CLOSE'
|
export const POPOVER_CLOSE = 'POPOVER_CLOSE'
|
||||||
|
|
||||||
export function openPopover(type, props) {
|
export function openPopover(type, props) {
|
||||||
return {
|
return function (dispatch, getState) {
|
||||||
type: POPOVER_OPEN,
|
const currentlyOpenPopover = getState().getIn(['popover', 'popoverType'])
|
||||||
popoverType: type,
|
|
||||||
popoverProps: props,
|
if (currentlyOpenPopover === type) {
|
||||||
|
dispatch(closePopover(type))
|
||||||
|
} else {
|
||||||
|
dispatch(handleOpenPopover(type, props))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,3 +19,11 @@ export function closePopover(type) {
|
||||||
popoverType: type,
|
popoverType: type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleOpenPopover = (type, props) => {
|
||||||
|
return {
|
||||||
|
type: POPOVER_OPEN,
|
||||||
|
popoverType: type,
|
||||||
|
popoverProps: props,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
const ArrowLeftIcon = ({
|
||||||
|
className = '',
|
||||||
|
size = '16px',
|
||||||
|
title = '',
|
||||||
|
}) => (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
version='1.1'
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
x='0px'
|
||||||
|
y='0px'
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox='0 0 24 24'
|
||||||
|
xmlSpace='preserve'
|
||||||
|
aria-label={title}
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<path d='M20 11H7.414l4.293-4.293c.39-.39.39-1.023 0-1.414s-1.023-.39-1.414 0l-6 6c-.39.39-.39 1.023 0 1.414l6 6c.195.195.45.293.707.293s.512-.098.707-.293c.39-.39.39-1.023 0-1.414L7.414 13H20c.553 0 1-.447 1-1s-.447-1-1-1z' />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ArrowLeftIcon
|
|
@ -0,0 +1,24 @@
|
||||||
|
const ArrowRightIcon = ({
|
||||||
|
className = '',
|
||||||
|
size = '16px',
|
||||||
|
title = '',
|
||||||
|
}) => (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
version='1.1'
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
x='0px'
|
||||||
|
y='0px'
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox='0 0 24 24'
|
||||||
|
xmlSpace='preserve'
|
||||||
|
aria-label={title}
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<path d='M19.707 11.293l-6-6c-.39-.39-1.023-.39-1.414 0s-.39 1.023 0 1.414L16.586 11H4c-.553 0-1 .447-1 1s.447 1 1 1h12.586l-4.293 4.293c-.39.39-.39 1.023 0 1.414.195.195.45.293.707.293s.512-.098.707-.293l6-6c.39-.39.39-1.023 0-1.414z' />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ArrowRightIcon
|
|
@ -107,7 +107,7 @@ class Avatar extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
alt={alt}
|
alt={alt}
|
||||||
ref={this.setRef}
|
imageRef={this.setRef}
|
||||||
className={classes.join(' ')}
|
className={classes.join(' ')}
|
||||||
{...options}
|
{...options}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -195,10 +195,13 @@ class Composer extends PureComponent {
|
||||||
return (
|
return (
|
||||||
<div className={_s.default}>
|
<div className={_s.default}>
|
||||||
|
|
||||||
<RichTextEditorBar
|
{ /** : todo : */
|
||||||
editorState={editorState}
|
!small &&
|
||||||
onChange={this.onChange}
|
<RichTextEditorBar
|
||||||
/>
|
editorState={editorState}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
onClick={this.focus}
|
onClick={this.focus}
|
||||||
|
|
|
@ -1,4 +1,17 @@
|
||||||
import Layout from '../layouts/layout'
|
import { FormattedMessage } from 'react-intl'
|
||||||
|
import {
|
||||||
|
source_url,
|
||||||
|
version,
|
||||||
|
} from '../initial_state'
|
||||||
|
import {
|
||||||
|
APP_NAME,
|
||||||
|
DEFAULT_REL,
|
||||||
|
} from '../constants'
|
||||||
|
import Button from './button'
|
||||||
|
import DotTextSeperator from './dot_text_seperator'
|
||||||
|
import Divider from './divider'
|
||||||
|
import Icon from './icon'
|
||||||
|
import Text from './text'
|
||||||
|
|
||||||
export default class ErrorBoundary extends PureComponent {
|
export default class ErrorBoundary extends PureComponent {
|
||||||
|
|
||||||
|
@ -10,6 +23,7 @@ export default class ErrorBoundary extends PureComponent {
|
||||||
hasError: false,
|
hasError: false,
|
||||||
stackTrace: undefined,
|
stackTrace: undefined,
|
||||||
componentStack: undefined,
|
componentStack: undefined,
|
||||||
|
copied: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidCatch(error, info) {
|
componentDidCatch(error, info) {
|
||||||
|
@ -17,20 +31,129 @@ export default class ErrorBoundary extends PureComponent {
|
||||||
hasError: true,
|
hasError: true,
|
||||||
stackTrace: error.stack,
|
stackTrace: error.stack,
|
||||||
componentStack: info && info.componentStack,
|
componentStack: info && info.componentStack,
|
||||||
|
copied: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCopyStackTrace = () => {
|
||||||
|
const { stackTrace } = this.state;
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
|
||||||
|
textarea.textContent = stackTrace;
|
||||||
|
textarea.style.position = 'fixed';
|
||||||
|
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
|
||||||
|
try {
|
||||||
|
textarea.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
|
||||||
|
this.setState({ copied: true });
|
||||||
|
setTimeout(() => this.setState({ copied: false }), 700);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { hasError } = this.state
|
const { hasError, copied } = this.state
|
||||||
|
|
||||||
if (!hasError) return this.props.children
|
if (!hasError) return this.props.children
|
||||||
|
|
||||||
// : todo : custom error page
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='error-boundary'>
|
<div className={[_s.default, _s.heightMin100VH, _s.width100PC, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
|
||||||
<div className='error-boundary__container'>
|
<div className={[_s.default, _s.height53PX, _s.bgBrand, _s.alignItemsCenter, _s.z3, _s.top0, _s.right0, _s.left0, _s.posFixed].join(' ')} >
|
||||||
<a className='error-boundary__link' href='/home'>Return Home</a>
|
<div className={[_s.default, _s.flexRow, _s.width1255PX].join(' ')}>
|
||||||
|
|
||||||
|
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||||
|
|
||||||
|
<h1 className={[_s.default, _s.mr15].join(' ')}>
|
||||||
|
<Button href='/' isText aria-label='Gab' className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}>
|
||||||
|
<Icon id='gab-logo' className={_s.fillWhite} />
|
||||||
|
</Button>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={[_s.default, _s.maxWidth640PX, _s.px15, _s.py10].join(' ')}>
|
||||||
|
|
||||||
|
<Icon id='warning' size='28px' className={[_s.default, _s.fillSecondary, _s.mb15].join(' ')} />
|
||||||
|
|
||||||
|
<Text size='medium' className={_s.pt15}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='error.unexpected_crash.explanation'
|
||||||
|
defaultMessage='Due to a bug in our code or a browser compatibility issue, this page or feature could not be displayed correctly.'
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size='medium' className={_s.mt10}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='error.unexpected_crash.next_steps'
|
||||||
|
defaultMessage='Try refreshing the page or trying the action again. If that does not help, you may still be able to use Gab Social through a different browser or native app.'
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<div className={[_s.default, _s.py10, _s.my10].join(' ')}>
|
||||||
|
<Text>
|
||||||
|
{APP_NAME} ({version})
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<div className={[_s.default, _s.flexRow, _s.mt10, _s.alignItemsCenter].join(' ')}>
|
||||||
|
<Button
|
||||||
|
isText
|
||||||
|
href={source_url}
|
||||||
|
rel={DEFAULT_REL}
|
||||||
|
target='_blank'
|
||||||
|
backgroundColor='tertiary'
|
||||||
|
color='primary'
|
||||||
|
radiusSmall
|
||||||
|
className={[_s.py2, _s.px10].join(' ')}
|
||||||
|
>
|
||||||
|
<Text color='inherit'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='errors.unexpected_crash.report_issue'
|
||||||
|
defaultMessage='Report issue'
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<DotTextSeperator />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
isText
|
||||||
|
backgroundColor='tertiary'
|
||||||
|
color='primary'
|
||||||
|
onClick={this.handleCopyStackTrace}
|
||||||
|
radiusSmall
|
||||||
|
className={[_s.ml5, _s.py2, _s.px10].join(' ')}
|
||||||
|
>
|
||||||
|
<Text color='inherit'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='errors.unexpected_crash.copy_stacktrace'
|
||||||
|
defaultMessage='Copy stacktrace to clipboard'
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||||
|
<Button href='/home'>
|
||||||
|
<Text align='center' color='inherit'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='return_home'
|
||||||
|
defaultMessage='Return Home'
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,6 @@ import Text from './text'
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
||||||
leave: { id: 'groups.leave', defaultMessage: 'Leave group' },
|
leave: { id: 'groups.leave', defaultMessage: 'Leave group' },
|
||||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
|
||||||
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
||||||
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
||||||
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' }
|
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' }
|
||||||
|
@ -30,10 +29,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onShare() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
onOpenGroupOptions() {
|
onOpenGroupOptions() {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -53,7 +48,6 @@ class GroupHeader extends ImmutablePureComponent {
|
||||||
group: ImmutablePropTypes.map,
|
group: ImmutablePropTypes.map,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
onToggleMembership: PropTypes.func.isRequired,
|
onToggleMembership: PropTypes.func.isRequired,
|
||||||
onShare: PropTypes.func.isRequired,
|
|
||||||
onOpenGroupOptions: PropTypes.func.isRequired,
|
onOpenGroupOptions: PropTypes.func.isRequired,
|
||||||
relationships: ImmutablePropTypes.map,
|
relationships: ImmutablePropTypes.map,
|
||||||
}
|
}
|
||||||
|
@ -67,7 +61,6 @@ class GroupHeader extends ImmutablePureComponent {
|
||||||
const {
|
const {
|
||||||
group,
|
group,
|
||||||
intl,
|
intl,
|
||||||
onShare,
|
|
||||||
onOpenGroupOptions,
|
onOpenGroupOptions,
|
||||||
relationships,
|
relationships,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
@ -130,17 +123,7 @@ class GroupHeader extends ImmutablePureComponent {
|
||||||
</Text>
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
<Button
|
|
||||||
color='primary'
|
|
||||||
backgroundColor='tertiary'
|
|
||||||
radiusSmall
|
|
||||||
className={_s.mr5}
|
|
||||||
onClick={onShare}
|
|
||||||
>
|
|
||||||
<Text color='inherit' size='small'>
|
|
||||||
{intl.formatMessage(messages.share)}
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
radiusSmall
|
radiusSmall
|
||||||
color='primary'
|
color='primary'
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import AddIcon from '../assets/add_icon'
|
import AddIcon from '../assets/add_icon'
|
||||||
import AngleRightIcon from '../assets/angle_right_icon'
|
import AngleRightIcon from '../assets/angle_right_icon'
|
||||||
import AppsIcon from '../assets/apps_icon'
|
import AppsIcon from '../assets/apps_icon'
|
||||||
|
import ArrowLeftIcon from '../assets/arrow_left_icon'
|
||||||
|
import ArrowRightIcon from '../assets/arrow_right_icon'
|
||||||
import AudioIcon from '../assets/audio_icon'
|
import AudioIcon from '../assets/audio_icon'
|
||||||
import AudioMuteIcon from '../assets/audio_mute_icon'
|
import AudioMuteIcon from '../assets/audio_mute_icon'
|
||||||
import BackIcon from '../assets/back_icon'
|
import BackIcon from '../assets/back_icon'
|
||||||
|
@ -73,6 +75,8 @@ const ICONS = {
|
||||||
'add': AddIcon,
|
'add': AddIcon,
|
||||||
'angle-right': AngleRightIcon,
|
'angle-right': AngleRightIcon,
|
||||||
'apps': AppsIcon,
|
'apps': AppsIcon,
|
||||||
|
'arrow-left': ArrowLeftIcon,
|
||||||
|
'arrow-right': ArrowRightIcon,
|
||||||
'audio': AudioIcon,
|
'audio': AudioIcon,
|
||||||
'audio-mute': AudioMuteIcon,
|
'audio-mute': AudioMuteIcon,
|
||||||
'back': BackIcon,
|
'back': BackIcon,
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default class Image extends PureComponent {
|
||||||
fit: PropTypes.oneOf(['contain', 'cover', 'tile', 'none']),
|
fit: PropTypes.oneOf(['contain', 'cover', 'tile', 'none']),
|
||||||
nullable: PropTypes.bool,
|
nullable: PropTypes.bool,
|
||||||
lazy: PropTypes.bool,
|
lazy: PropTypes.bool,
|
||||||
ref: PropTypes.func,
|
imageRef: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -43,6 +43,7 @@ export default class Image extends PureComponent {
|
||||||
className,
|
className,
|
||||||
nullable,
|
nullable,
|
||||||
lazy,
|
lazy,
|
||||||
|
imageRef,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = this.props
|
} = this.props
|
||||||
const { error } = this.state
|
const { error } = this.state
|
||||||
|
@ -69,6 +70,7 @@ export default class Image extends PureComponent {
|
||||||
alt={alt}
|
alt={alt}
|
||||||
className={classes}
|
className={classes}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
|
ref={imageRef}
|
||||||
src={src}
|
src={src}
|
||||||
onError={this.handleOnError}
|
onError={this.handleOnError}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
source_url,
|
source_url,
|
||||||
me,
|
me,
|
||||||
} from '../initial_state'
|
} from '../initial_state'
|
||||||
|
import { DEFAULT_REL } from '../constants'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ class LinkFooter extends PureComponent {
|
||||||
defaultMessage='Gab Social is open source software. You can contribute or report issues on our self-hosted GitLab at {gitlab}.'
|
defaultMessage='Gab Social is open source software. You can contribute or report issues on our self-hosted GitLab at {gitlab}.'
|
||||||
values={{
|
values={{
|
||||||
gitlab: (
|
gitlab: (
|
||||||
<a href={source_url} className={_s.inherit} rel='noopener noreferrer' target='_blank'>
|
<a href={source_url} className={_s.inherit} rel={DEFAULT_REL} target='_blank'>
|
||||||
{repository}
|
{repository}
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SensitiveMediaItem from './sensitive_media_item'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
|
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Hide media' },
|
||||||
warning: { id: 'status.sensitive_warning', defaultMessage: 'Sensitive content' },
|
warning: { id: 'status.sensitive_warning', defaultMessage: 'Sensitive content' },
|
||||||
hidden: { id: 'status.media_hidden', defaultMessage: 'Media hidden' },
|
hidden: { id: 'status.media_hidden', defaultMessage: 'Media hidden' },
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,15 +4,13 @@ import ConfirmationModal from './confirmation_modal'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
blockDomain: { id: 'block_domain', defaultMessage: 'Block {domain}' },
|
blockDomain: { id: 'block_domain', defaultMessage: 'Block {domain}' },
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
|
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
||||||
blockDomainMessage: { id: 'confirmations.domain_block.message', defaultMessage: 'Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' },
|
blockDomainMessage: { id: 'confirmations.domain_block.message', defaultMessage: 'Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' },
|
||||||
cancel: { id: 'confirmation_modal.cancel', defaultMessage: 'Cancel' },
|
cancel: { id: 'confirmation_modal.cancel', defaultMessage: 'Cancel' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onConfirm(domain) {
|
onConfirm: (domain) => dispatch(blockDomain(domain)),
|
||||||
dispatch(blockDomain(domain))
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
|
@ -22,9 +20,9 @@ class BlockDomainModal extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
domain: PropTypes.string.isRequired,
|
domain: PropTypes.string.isRequired,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
onConfirm: PropTypes.func.isRequired,
|
onConfirm: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
|
@ -34,8 +32,6 @@ class BlockDomainModal extends PureComponent {
|
||||||
render() {
|
render() {
|
||||||
const { onClose, domain, intl } = this.props
|
const { onClose, domain, intl } = this.props
|
||||||
|
|
||||||
console.log("this.props: ", this.props)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
title={intl.formatMessage(messages.blockDomain, { domain })}
|
title={intl.formatMessage(messages.blockDomain, { domain })}
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import Button from '../button';
|
import Button from '../button'
|
||||||
import StatusContent from '../status_content';
|
import StatusContainer from '../../containers/status_container'
|
||||||
import Avatar from '../avatar';
|
import Text from '../text'
|
||||||
import RelativeTimestamp from '../relative_timestamp';
|
import ModalLayout from './modal_layout'
|
||||||
import DisplayName from '../display_name';
|
|
||||||
import Icon from '../icon';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
cancel_repost: { id: 'status.cancel_repost_private', defaultMessage: 'Un-repost' },
|
removeRepost: { id: 'status.cancel_repost_private', defaultMessage: 'Remove Repost' },
|
||||||
repost: { id: 'status.repost', defaultMessage: 'Repost' },
|
repost: { id: 'status.repost', defaultMessage: 'Repost' },
|
||||||
combo: { id: 'boost_modal.combo', defaultMessage: 'You can press {combo} to skip this next time' },
|
combo: { id: 'boost_modal.combo', defaultMessage: 'You can press Shift + Repost to skip this next time' },
|
||||||
});
|
})
|
||||||
|
|
||||||
// : todo :
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
|
@ -22,86 +18,62 @@ class BoostModal extends ImmutablePureComponent {
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
router: PropTypes.object,
|
router: PropTypes.object,
|
||||||
};
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
onRepost: PropTypes.func.isRequired,
|
onRepost: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.button.focus();
|
this.button.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRepost = () => {
|
handleRepost = () => {
|
||||||
this.props.onRepost(this.props.status);
|
this.props.onRepost(this.props.status)
|
||||||
this.props.onClose();
|
this.props.onClose()
|
||||||
}
|
|
||||||
|
|
||||||
handleAccountClick = (e) => {
|
|
||||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.onClose();
|
|
||||||
this.context.router.history.push(`/${this.props.status.getIn(['account', 'acct'])}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleStatusClick = (e) => {
|
|
||||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.onClose();
|
|
||||||
this.context.router.history.push(`/${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('url')}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.button = c;
|
this.button = c
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, intl } = this.props;
|
const { status, onClose, intl } = this.props
|
||||||
const buttonText = status.get('reblogged') ? messages.cancel_repost : messages.repost;
|
|
||||||
|
const buttonText = status.get('reblogged') ? messages.removeRepost : messages.repost
|
||||||
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('url')}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal boost-modal'>
|
<ModalLayout
|
||||||
<div className='boost-modal__container'>
|
title={intl.formatMessage(messages.repost)}
|
||||||
<div className='status light'>
|
noPadding
|
||||||
<div className='boost-modal__status-header'>
|
width={480}
|
||||||
<div className='boost-modal__status-time'>
|
onClose={onClose}
|
||||||
<a onClick={this.handleStatusClick} href={statusUrl} className='status__relative-time'>
|
>
|
||||||
<RelativeTimestamp timestamp={status.get('created_at')} />
|
|
||||||
</a>
|
<div className={[_s.default, _s.px15, _s.py10, _s.mt5].join(' ')}>
|
||||||
</div>
|
<StatusContainer
|
||||||
|
id={status.get('id')}
|
||||||
<a onClick={this.handleAccountClick} href={`/${status.getIn(['account', 'acct'])}`} className='status__display-name'>
|
isChild
|
||||||
<div className='status__avatar'>
|
/>
|
||||||
<Avatar account={status.get('account')} size={48} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<DisplayName account={status.get('account')} />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<StatusContent status={status} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='boost-modal__action-bar'>
|
|
||||||
<div>
|
|
||||||
{intl.formatMessage(messages.combo, {
|
|
||||||
values: {
|
|
||||||
combo: <span>Shift + <Icon id='retweet' /></span>
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<Button text={intl.formatMessage(buttonText)} onClick={this.handleRepost} ref={this.setRef} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
|
||||||
|
<div className={[_s.default, _s.justifyContentCenter, _s.px15, _s.mt5, _s.mb15].join(' ')}>
|
||||||
|
<Text align='center'>
|
||||||
|
{intl.formatMessage(messages.combo)}
|
||||||
|
</Text>
|
||||||
|
<div className={[_s.default, _s.flexRow, _s.justifyContentCenter, _s.my10, _s.pt15, _s.pb5].join(' ')}>
|
||||||
|
<Button onClick={this.handleRepost} buttonRef={this.setRef}>
|
||||||
|
<Text color='inherit' className={_s.px15}>
|
||||||
|
{intl.formatMessage(buttonText)}
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalLayout>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,8 +86,8 @@ class GifPickerModal extends PureComponent {
|
||||||
this.props.handleFetchCategories()
|
this.props.handleFetchCategories()
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange = (e) => {
|
onChange = (value) => {
|
||||||
this.props.handleOnChange(e.target.value)
|
this.props.handleOnChange(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
onHandleCloseModal = () => {
|
onHandleCloseModal = () => {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import classNames from 'classnames'
|
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import ReactSwipeableViews from 'react-swipeable-views'
|
import ReactSwipeableViews from 'react-swipeable-views'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { CX } from '../../constants'
|
||||||
import Video from '../video'
|
import Video from '../video'
|
||||||
import ExtendedVideoPlayer from '../extended_video_player'
|
import ExtendedVideoPlayer from '../extended_video_player'
|
||||||
import Button from '../button'
|
import Button from '../button'
|
||||||
import ImageLoader from '../image_loader'
|
import ImageLoader from '../image_loader'
|
||||||
import Icon from '../icon'
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||||
|
@ -16,9 +15,7 @@ const messages = defineMessages({
|
||||||
viewContext: { id: 'lightbox.view_context', defaultMessage: 'View context' },
|
viewContext: { id: 'lightbox.view_context', defaultMessage: 'View context' },
|
||||||
})
|
})
|
||||||
|
|
||||||
export const previewState = 'previewMediaModal';
|
export const previewState = 'previewMediaModal'
|
||||||
|
|
||||||
// : todo :
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
|
@ -30,115 +27,158 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
index: PropTypes.number.isRequired,
|
index: PropTypes.number.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
router: PropTypes.object,
|
router: PropTypes.object,
|
||||||
};
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
index: null,
|
index: null,
|
||||||
navigationHidden: false,
|
navigationHidden: false,
|
||||||
};
|
}
|
||||||
|
|
||||||
|
updateOnProps = [
|
||||||
|
'media',
|
||||||
|
'status',
|
||||||
|
'index',
|
||||||
|
]
|
||||||
|
|
||||||
handleSwipe = (index) => {
|
handleSwipe = (index) => {
|
||||||
this.setState({ index: index % this.props.media.size });
|
this.setState({ index: index % this.props.media.size })
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNextClick = () => {
|
handleNextClick = () => {
|
||||||
this.setState({ index: (this.getIndex() + 1) % this.props.media.size });
|
this.setState({ index: (this.getIndex() + 1) % this.props.media.size })
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePrevClick = () => {
|
handlePrevClick = () => {
|
||||||
this.setState({ index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size });
|
this.setState({ index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size })
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeIndex = (e) => {
|
handleChangeIndex = (e) => {
|
||||||
const index = Number(e.currentTarget.getAttribute('data-index'));
|
const index = Number(e.currentTarget.getAttribute('data-index'))
|
||||||
this.setState({ index: index % this.props.media.size });
|
this.setState({ index: index % this.props.media.size })
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e) => {
|
||||||
switch(e.key) {
|
switch (e.key) {
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
this.handlePrevClick();
|
this.handlePrevClick()
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
break;
|
break
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
this.handleNextClick();
|
this.handleNextClick()
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount() {
|
||||||
window.addEventListener('keydown', this.handleKeyDown, false);
|
window.addEventListener('keydown', this.handleKeyDown, false)
|
||||||
|
|
||||||
if (this.context.router) {
|
if (this.context.router) {
|
||||||
const history = this.context.router.history;
|
const history = this.context.router.history
|
||||||
|
|
||||||
history.push(history.location.pathname, previewState);
|
history.push(history.location.pathname, previewState)
|
||||||
|
|
||||||
this.unlistenHistory = history.listen(() => {
|
this.unlistenHistory = history.listen(() => {
|
||||||
this.props.onClose();
|
this.props.onClose()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('keydown', this.handleKeyDown);
|
window.removeEventListener('keydown', this.handleKeyDown)
|
||||||
|
|
||||||
if (this.context.router) {
|
if (this.context.router) {
|
||||||
this.unlistenHistory();
|
this.unlistenHistory()
|
||||||
|
|
||||||
if (this.context.router.history.location.state === previewState) {
|
if (this.context.router.history.location.state === previewState) {
|
||||||
this.context.router.history.goBack();
|
this.context.router.history.goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getIndex () {
|
getIndex() {
|
||||||
return this.state.index !== null ? this.state.index : this.props.index;
|
return this.state.index !== null ? this.state.index : this.props.index
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleNavigation = () => {
|
toggleNavigation = () => {
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
navigationHidden: !prevState.navigationHidden,
|
navigationHidden: !prevState.navigationHidden,
|
||||||
}));
|
}))
|
||||||
};
|
}
|
||||||
|
|
||||||
handleStatusClick = e => {
|
handleStatusClick = e => {
|
||||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
this.context.router.history.push(`/${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('id')}`);
|
this.context.router.history.push(`/${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('id')}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const { media, status, intl, onClose } = this.props;
|
const {
|
||||||
const { navigationHidden } = this.state;
|
media,
|
||||||
|
status,
|
||||||
|
intl,
|
||||||
|
onClose,
|
||||||
|
} = this.props
|
||||||
|
const { navigationHidden } = this.state
|
||||||
|
|
||||||
const index = this.getIndex();
|
const index = this.getIndex()
|
||||||
let pagination = [];
|
let pagination = []
|
||||||
|
|
||||||
const leftNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='chevron-left' fixedWidth /></button>;
|
const leftNav = media.size > 1 && (
|
||||||
const rightNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='chevron-right' fixedWidth /></button>;
|
<Button
|
||||||
|
tabIndex='0'
|
||||||
|
backgroundColor='black'
|
||||||
|
className={[_s.py15, _s.posFixed, _s.top50PC, _s.left0, _s.mt10, _s.ml10].join(' ')}
|
||||||
|
onClick={this.handlePrevClick}
|
||||||
|
aria-label={intl.formatMessage(messages.previous)}
|
||||||
|
icon='arrow-left'
|
||||||
|
iconSize='18px'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
const rightNav = media.size > 1 && (
|
||||||
|
<Button
|
||||||
|
tabIndex='0'
|
||||||
|
backgroundColor='black'
|
||||||
|
className={[_s.py15, _s.posFixed, _s.top50PC, _s.right0, _s.mt10, _s.mr10].join(' ')}
|
||||||
|
onClick={this.handleNextClick}
|
||||||
|
aria-label={intl.formatMessage(messages.next)}
|
||||||
|
icon='arrow-right'
|
||||||
|
iconSize='18px'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
if (media.size > 1) {
|
if (media.size > 1) {
|
||||||
pagination = media.map((item, i) => {
|
pagination = media.map((item, i) => {
|
||||||
const classes = ['media-modal__button'];
|
const btnClasses = CX({
|
||||||
if (i === index) {
|
default: 1,
|
||||||
classes.push('media-modal__button--active');
|
px5: 1,
|
||||||
}
|
py5: 1,
|
||||||
return (<li className='media-modal__page-dot' key={i}><button tabIndex='0' className={classes.join(' ')} onClick={this.handleChangeIndex} data-index={i}>{i + 1}</button></li>);
|
outlineNone: 1,
|
||||||
});
|
colorPrimary: 1,
|
||||||
|
circle: 1,
|
||||||
|
cursorPointer: 1,
|
||||||
|
bgPrimaryOpaque: i !== index,
|
||||||
|
bgPrimary: i === index,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className={[_s.default, _s.px5].join(' ')} key={`media-pagination-${i}`}>
|
||||||
|
<button tabIndex='0' className={btnClasses} onClick={this.handleChangeIndex} data-index={i} />
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = media.map((image) => {
|
const content = media.map((image) => {
|
||||||
const width = image.getIn(['meta', 'original', 'width']) || null;
|
const width = image.getIn(['meta', 'original', 'width']) || null
|
||||||
const height = image.getIn(['meta', 'original', 'height']) || null;
|
const height = image.getIn(['meta', 'original', 'height']) || null
|
||||||
|
|
||||||
if (image.get('type') === 'image') {
|
if (image.get('type') === 'image') {
|
||||||
return (
|
return (
|
||||||
|
@ -151,9 +191,9 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
key={image.get('url')}
|
key={image.get('url')}
|
||||||
onClick={this.toggleNavigation}
|
onClick={this.toggleNavigation}
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
} else if (image.get('type') === 'video') {
|
} else if (image.get('type') === 'video') {
|
||||||
const { time } = this.props;
|
const { time } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Video
|
<Video
|
||||||
|
@ -168,7 +208,7 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
alt={image.get('description')}
|
alt={image.get('description')}
|
||||||
key={image.get('url')}
|
key={image.get('url')}
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
} else if (image.get('type') === 'gifv') {
|
} else if (image.get('type') === 'gifv') {
|
||||||
return (
|
return (
|
||||||
<ExtendedVideoPlayer
|
<ExtendedVideoPlayer
|
||||||
|
@ -181,11 +221,11 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
alt={image.get('description')}
|
alt={image.get('description')}
|
||||||
onClick={this.toggleNavigation}
|
onClick={this.toggleNavigation}
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null
|
||||||
}).toArray();
|
}).toArray()
|
||||||
|
|
||||||
// you can't use 100vh, because the viewport height is taller
|
// you can't use 100vh, because the viewport height is taller
|
||||||
// than the visible part of the document in some mobile
|
// than the visible part of the document in some mobile
|
||||||
|
@ -194,26 +234,25 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
const swipeableViewsStyle = {
|
const swipeableViewsStyle = {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
};
|
}
|
||||||
|
|
||||||
const containerStyle = {
|
const navigationClasses = CX({
|
||||||
alignItems: 'center', // center vertically
|
default: 1,
|
||||||
};
|
displayNone: navigationHidden,
|
||||||
|
})
|
||||||
const navigationClassName = classNames('media-modal__navigation', {
|
|
||||||
'media-modal__navigation--hidden': navigationHidden,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal media-modal'>
|
<div className={[_s.default, _s.width100PC, _s.height100PC, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
|
||||||
<div
|
<div
|
||||||
className='media-modal__closer'
|
className={[_s.default, _s.top0, _s.right0, _s.bottom0, _s.left0].join(' ')}
|
||||||
role='presentation'
|
role='presentation'
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
<ReactSwipeableViews
|
<ReactSwipeableViews
|
||||||
style={swipeableViewsStyle}
|
style={swipeableViewsStyle}
|
||||||
containerStyle={containerStyle}
|
containerStyle={{
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
onChangeIndex={this.handleSwipe}
|
onChangeIndex={this.handleSwipe}
|
||||||
onSwitching={this.handleSwitching}
|
onSwitching={this.handleSwitching}
|
||||||
index={index}
|
index={index}
|
||||||
|
@ -222,26 +261,36 @@ class MediaModal extends ImmutablePureComponent {
|
||||||
</ReactSwipeableViews>
|
</ReactSwipeableViews>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={navigationClassName}>
|
<div className={navigationClasses}>
|
||||||
<Button className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={40} />
|
<Button
|
||||||
|
title={intl.formatMessage(messages.close)}
|
||||||
|
icon='close'
|
||||||
|
backgroundColor='black'
|
||||||
|
onClick={onClose}
|
||||||
|
iconSize='14px'
|
||||||
|
className={[_s.py15, _s.posFixed, _s.top0, _s.right0, _s.mt10, _s.mr10].join(' ')}
|
||||||
|
/>
|
||||||
|
|
||||||
{leftNav}
|
{leftNav}
|
||||||
{rightNav}
|
{rightNav}
|
||||||
|
|
||||||
{status && (
|
{ /** : todo :
|
||||||
|
status &&
|
||||||
<div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}>
|
<div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}>
|
||||||
<a href={status.get('url')} onClick={this.handleStatusClick}>
|
<a href={status.get('url')} onClick={this.handleStatusClick}>
|
||||||
{intl.formatMessage(messages.viewContext)}
|
{intl.formatMessage(messages.viewContext)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
)}
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
<ul className='media-modal__pagination'>
|
|
||||||
{pagination}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ul className={[_s.default, _s.posAbsolute, _s.bottom0, _s.mb15, _s.flexRow, _s.bgBlackOpaque, _s.circle, _s.py10, _s.px15, _s.listStyleNone].join(' ')}>
|
||||||
|
{pagination}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { closeModal } from '../../actions/modal'
|
import { closeModal } from '../../actions/modal'
|
||||||
import { cancelReplyCompose } from '../../actions/compose'
|
import { cancelReplyCompose } from '../../actions/compose'
|
||||||
import Bundle from '../../features/ui/util/bundle'
|
import Bundle from '../../features/ui/util/bundle'
|
||||||
|
import ModalBase from './modal_base'
|
||||||
|
import BundleModalError from '../bundle_modal_error'
|
||||||
import {
|
import {
|
||||||
MODAL_ACTIONS,
|
MODAL_ACTIONS,
|
||||||
MODAL_BLOCK_ACCOUNT,
|
MODAL_BLOCK_ACCOUNT,
|
||||||
|
@ -64,9 +66,6 @@ import {
|
||||||
VideoModal,
|
VideoModal,
|
||||||
} from '../../features/ui/util/async_components'
|
} from '../../features/ui/util/async_components'
|
||||||
|
|
||||||
import ModalBase from './modal_base'
|
|
||||||
import BundleModalError from '../bundle_modal_error'
|
|
||||||
|
|
||||||
const MODAL_COMPONENTS = {}
|
const MODAL_COMPONENTS = {}
|
||||||
MODAL_COMPONENTS[MODAL_ACTIONS] = ActionsModal
|
MODAL_COMPONENTS[MODAL_ACTIONS] = ActionsModal
|
||||||
MODAL_COMPONENTS[MODAL_BLOCK_ACCOUNT] = BlockAccountModal
|
MODAL_COMPONENTS[MODAL_BLOCK_ACCOUNT] = BlockAccountModal
|
||||||
|
@ -135,12 +134,12 @@ class ModalRoot extends PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoading = modalId => () => {
|
renderLoading = () => {
|
||||||
return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? <ModalLoading /> : null
|
return <ModalLoading />
|
||||||
}
|
}
|
||||||
|
|
||||||
renderError = (props) => {
|
renderError = () => {
|
||||||
return <BundleModalError {...props} onClose={this.onClickClose} />
|
return <BundleModalError {...this.props} onClose={this.onClickClose} />
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickClose = () => {
|
onClickClose = () => {
|
||||||
|
@ -157,12 +156,12 @@ class ModalRoot extends PureComponent {
|
||||||
visible &&
|
visible &&
|
||||||
<Bundle
|
<Bundle
|
||||||
fetchComponent={MODAL_COMPONENTS[type]}
|
fetchComponent={MODAL_COMPONENTS[type]}
|
||||||
loading={this.renderLoading(type)}
|
loading={this.renderLoading}
|
||||||
error={this.renderError}
|
error={this.renderError}
|
||||||
renderDelay={200}
|
renderDelay={200}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
(SpecificComponent) => <SpecificComponent {...props} onClose={this.onClickClose} />
|
(Component) => <Component {...props} onClose={this.onClickClose} />
|
||||||
}
|
}
|
||||||
</Bundle>
|
</Bundle>
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ class NavigationBar extends ImmutablePureComponent {
|
||||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||||
|
|
||||||
<h1 className={[_s.default, _s.mr15].join(' ')}>
|
<h1 className={[_s.default, _s.mr15].join(' ')}>
|
||||||
<Button to='/' aria-label='Gab' className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}>
|
<Button to='/' isText title='Gab' aria-label='Gab' className={[_s.default, _s.justifyContentCenter, _s.noSelect, _s.noUnderline, _s.height53PX, _s.cursorPointer, _s.px10, _s.mr15].join(' ')}>
|
||||||
<Icon id='gab-logo' className={_s.fillWhite} />
|
<Icon id='gab-logo' className={_s.fillWhite} />
|
||||||
</Button>
|
</Button>
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -68,14 +68,21 @@ class NavigationBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
<NavigationBarButtonDivider />
|
<NavigationBarButtonDivider />
|
||||||
|
|
||||||
<NavigationBarButton icon='notifications' to='/notifications' />
|
<NavigationBarButton attrTitle='Notifications' icon='notifications' to='/notifications' />
|
||||||
<NavigationBarButton icon='cog' href='/settings/preferences' />
|
<NavigationBarButton attrTitle='Settings' icon='cog' href='/settings/preferences' />
|
||||||
|
|
||||||
<NavigationBarButtonDivider />
|
<NavigationBarButtonDivider />
|
||||||
|
|
||||||
<button onClick={this.handleProfileClick} className={[_s.height53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.default, _s.justifyContentCenter, _s.ml15].join(' ')}>
|
{
|
||||||
<Avatar account={account} size={32} noHover />
|
!!account &&
|
||||||
</button>
|
<button
|
||||||
|
title={account.get('display_name')}
|
||||||
|
onClick={this.handleProfileClick}
|
||||||
|
className={[_s.height53PX, _s.bgTransparent, _s.outlineNone, _s.cursorPointer, _s.default, _s.justifyContentCenter, _s.ml15].join(' ')}
|
||||||
|
>
|
||||||
|
<Avatar account={account} size={32} noHover />
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -105,6 +112,7 @@ class NavigationBarButton extends PureComponent {
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
to: PropTypes.string,
|
to: PropTypes.string,
|
||||||
href: PropTypes.string,
|
href: PropTypes.string,
|
||||||
|
attrTitle: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -113,6 +121,7 @@ class NavigationBarButton extends PureComponent {
|
||||||
icon,
|
icon,
|
||||||
to,
|
to,
|
||||||
href,
|
href,
|
||||||
|
attrTitle,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const active = false
|
const active = false
|
||||||
|
@ -124,15 +133,16 @@ class NavigationBarButton extends PureComponent {
|
||||||
alignItemsCenter: 1,
|
alignItemsCenter: 1,
|
||||||
justifyContentCenter: 1,
|
justifyContentCenter: 1,
|
||||||
outlineNone: 1,
|
outlineNone: 1,
|
||||||
px10: !!title,
|
|
||||||
px5: !title,
|
|
||||||
cursorPointer: 1,
|
cursorPointer: 1,
|
||||||
bgTransparent: 1,
|
bgTransparent: 1,
|
||||||
|
noUnderline: 1,
|
||||||
|
px10: !!title,
|
||||||
|
px5: !title,
|
||||||
colorWhite: !!title,
|
colorWhite: !!title,
|
||||||
fs13PX: !!title,
|
fs13PX: !!title,
|
||||||
fontWeightNormal: !!title,
|
fontWeightNormal: !!title,
|
||||||
textUppercase: !!title,
|
textUppercase: !!title,
|
||||||
noUnderline: 1,
|
bgBrandDark_onHover: !!title,
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconClasses = CX({
|
const iconClasses = CX({
|
||||||
|
@ -141,12 +151,13 @@ class NavigationBarButton extends PureComponent {
|
||||||
mr10: !!title,
|
mr10: !!title,
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconSize = !!title ? 16 : 18
|
const iconSize = !!title ? '16px' : '18px'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
to={to}
|
to={to}
|
||||||
href={href}
|
href={href}
|
||||||
|
attrTitle={attrTitle}
|
||||||
color='white'
|
color='white'
|
||||||
className={classes}
|
className={classes}
|
||||||
noClasses
|
noClasses
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { injectIntl, defineMessages } from 'react-intl'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { HotKeys } from 'react-hotkeys'
|
import { HotKeys } from 'react-hotkeys'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import { me } from '../initial_state'
|
||||||
import StatusContainer from '../containers/status_container'
|
import StatusContainer from '../containers/status_container'
|
||||||
import Avatar from './avatar'
|
import Avatar from './avatar'
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
|
@ -11,6 +12,7 @@ import DisplayName from './display_name'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' },
|
poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' },
|
||||||
|
ownPoll: { id: 'notification.own_poll', defaultMessage: 'Your poll has ended' },
|
||||||
mentionedInPost: { id: 'mentioned_in_post', defaultMessage: 'mentioned you in their post' },
|
mentionedInPost: { id: 'mentioned_in_post', defaultMessage: 'mentioned you in their post' },
|
||||||
mentionedInComment: { id: 'mentioned_in_comment', defaultMessage: 'mentioned you in their comment' },
|
mentionedInComment: { id: 'mentioned_in_comment', defaultMessage: 'mentioned you in their comment' },
|
||||||
followedYouOne: { id: 'followed_you_one', defaultMessage: 'followed you' },
|
followedYouOne: { id: 'followed_you_one', defaultMessage: 'followed you' },
|
||||||
|
@ -21,6 +23,7 @@ const messages = defineMessages({
|
||||||
repostedStatusMultiple: { id: 'reposted_status_multiple', defaultMessage: 'and {count} others reposted your status' },
|
repostedStatusMultiple: { id: 'reposted_status_multiple', defaultMessage: 'and {count} others reposted your status' },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// : todo :
|
||||||
const notificationForScreenReader = (intl, message, timestamp) => {
|
const notificationForScreenReader = (intl, message, timestamp) => {
|
||||||
const output = [message]
|
const output = [message]
|
||||||
|
|
||||||
|
@ -84,8 +87,14 @@ class Notification extends ImmutablePureComponent {
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'poll':
|
case 'poll':
|
||||||
|
let msg = messages.poll
|
||||||
|
if (accounts.size === 1) {
|
||||||
|
if (accounts.first().get('id') === me) {
|
||||||
|
msg = messages.ownPoll
|
||||||
|
}
|
||||||
|
}
|
||||||
icon = 'poll'
|
icon = 'poll'
|
||||||
message = intl.formatMessage(messages.poll)
|
message = intl.formatMessage(msg)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { List as ImmutableList } from 'immutable'
|
import { List as ImmutableList } from 'immutable'
|
||||||
|
import { DEFAULT_REL } from '../../constants'
|
||||||
import PanelLayout from './panel_layout'
|
import PanelLayout from './panel_layout'
|
||||||
import Divider from '../divider'
|
import Divider from '../divider'
|
||||||
import Icon from '../icon'
|
import Icon from '../icon'
|
||||||
|
@ -110,12 +111,12 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
|
|
||||||
{ /* : todo : */}
|
{ /* : todo : */}
|
||||||
<dd className='verified'>
|
<dd className='verified'>
|
||||||
<a href={proof.get('proof_url')} target='_blank' rel='noopener noreferrer'>
|
<a href={proof.get('proof_url')} target='_blank' rel={DEFAULT_REL}>
|
||||||
<span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
|
<span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
|
||||||
<Icon id='check' size='12px' className='verified__mark' />
|
<Icon id='check' size='12px' className='verified__mark' />
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<a href={proof.get('profile_url')} target='_blank' rel='noopener noreferrer'>
|
<a href={proof.get('profile_url')} target='_blank' rel={DEFAULT_REL}>
|
||||||
<span
|
<span
|
||||||
className={_s.dangerousContent}
|
className={_s.dangerousContent}
|
||||||
dangerouslySetInnerHTML={{ __html: ' ' + proof.get('provider_username') }}
|
dangerouslySetInnerHTML={{ __html: ' ' + proof.get('provider_username') }}
|
||||||
|
|
|
@ -25,6 +25,8 @@ class ProgressPanel extends PureComponent {
|
||||||
|
|
||||||
const value = Math.min(parseFloat(monthlyExpensesComplete), 100)
|
const value = Math.min(parseFloat(monthlyExpensesComplete), 100)
|
||||||
|
|
||||||
|
console.log("monthlyExpensesComplete:", monthlyExpensesComplete)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelLayout
|
<PanelLayout
|
||||||
title={intl.formatMessage(messages.operationsTitle)}
|
title={intl.formatMessage(messages.operationsTitle)}
|
||||||
|
|
|
@ -16,7 +16,7 @@ class PillItem extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
isCurrent: -1,
|
isCurrent: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
|
@ -43,8 +43,7 @@ class PillItem extends PureComponent {
|
||||||
|
|
||||||
// Combine state, props, location to make absolutely
|
// Combine state, props, location to make absolutely
|
||||||
// sure of active status.
|
// sure of active status.
|
||||||
const active = isActive ||
|
const active = isActive || to === location.pathname || isCurrent
|
||||||
(isCurrent === -1 ? to === location.pathname : false)
|
|
||||||
|
|
||||||
const containerClasses = CX({
|
const containerClasses = CX({
|
||||||
default: 1,
|
default: 1,
|
||||||
|
|
|
@ -16,7 +16,7 @@ import '!style-loader!css-loader!emoji-mart/css/emoji-mart.css'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
|
emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
|
||||||
emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search...' },
|
emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search for emoji' },
|
||||||
emoji_not_found: { id: 'emoji_button.not_found', defaultMessage: 'No emojos!! (╯°□°)╯︵ ┻━┻' },
|
emoji_not_found: { id: 'emoji_button.not_found', defaultMessage: 'No emojos!! (╯°□°)╯︵ ┻━┻' },
|
||||||
custom: { id: 'emoji_button.custom', defaultMessage: 'Custom' },
|
custom: { id: 'emoji_button.custom', defaultMessage: 'Custom' },
|
||||||
recent: { id: 'emoji_button.recent', defaultMessage: 'Frequently used' },
|
recent: { id: 'emoji_button.recent', defaultMessage: 'Frequently used' },
|
||||||
|
|
|
@ -1,12 +1,97 @@
|
||||||
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
|
import { quoteCompose } from '../../actions/compose'
|
||||||
|
import { repost, unrepost } from '../../actions/interactions'
|
||||||
|
import { openModal } from '../../actions/modal'
|
||||||
|
import { boostModal, me } from '../../initial_state'
|
||||||
import PopoverLayout from './popover_layout'
|
import PopoverLayout from './popover_layout'
|
||||||
import Text from '../text'
|
import List from '../list'
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
repost: { id: 'repost', defaultMessage: 'Repost' },
|
||||||
|
repostWithComment: { id: 'repost_with_comment', defaultMessage: 'Repost with comment' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
|
onQuote (status, router) {
|
||||||
|
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
||||||
|
|
||||||
|
dispatch((_, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
|
dispatch(openModal('CONFIRM', {
|
||||||
|
message: intl.formatMessage(messages.quoteMessage),
|
||||||
|
confirm: intl.formatMessage(messages.quoteConfirm),
|
||||||
|
onConfirm: () => dispatch(quoteCompose(status, router)),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
dispatch(quoteCompose(status, router));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onRepost (status) {
|
||||||
|
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
||||||
|
|
||||||
|
if (status.get('reblogged')) {
|
||||||
|
dispatch(unrepost(status));
|
||||||
|
} else {
|
||||||
|
dispatch(repost(status));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default
|
||||||
|
@injectIntl
|
||||||
|
@connect(null, mapDispatchToProps)
|
||||||
|
class GroupOptionsPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
|
onQuote: PropTypes.func.isRequired,
|
||||||
|
onRepost: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOnProps = ['status']
|
||||||
|
|
||||||
|
handleOnRepost = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnQuote = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export default class UserInfoPopover extends PureComponent {
|
|
||||||
render() {
|
render() {
|
||||||
|
const { intl } = this.props
|
||||||
|
|
||||||
|
const listItems = [
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
icon: 'repost',
|
||||||
|
title: intl.formatMessage(messages.repost),
|
||||||
|
onClick: this.handleOnRepost,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
icon: 'pencil',
|
||||||
|
title: intl.formatMessage(messages.repostWithComment),
|
||||||
|
onClick: this.handleBlockDomain,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout>
|
<PopoverLayout width={220}>
|
||||||
<Text>testing</Text>
|
<List
|
||||||
|
scrollKey='repost_options'
|
||||||
|
items={listItems}
|
||||||
|
size='large'
|
||||||
|
/>
|
||||||
</PopoverLayout>
|
</PopoverLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,33 +1,20 @@
|
||||||
|
import detectPassiveEvents from 'detect-passive-events'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { Manager, Reference, Popper } from 'react-popper'
|
import { Manager, Reference, Popper } from 'react-popper'
|
||||||
import classnames from 'classnames/bind'
|
import { closePopover } from '../../actions/popover'
|
||||||
import { openPopover, closePopover } from '../../actions/popover'
|
import { CX } from '../../constants'
|
||||||
import { openModal, closeModal } from '../../actions/modal'
|
|
||||||
import { isUserTouching } from '../../utils/is_mobile'
|
import { isUserTouching } from '../../utils/is_mobile'
|
||||||
|
|
||||||
const cx = classnames.bind(_s)
|
const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false
|
||||||
|
|
||||||
let id = 0
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
isModalOpen: state.getIn(['modal', 'modalType']) === 'ACTIONS',
|
isModalOpen: !!state.getIn(['modal', 'modalType']),
|
||||||
popoverPlacement: state.getIn(['popover', 'placement']),
|
popoverPlacement: state.getIn(['popover', 'placement']),
|
||||||
openPopoverType: state.getIn(['popover', 'popoverType']),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { status, items }) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
onOpen(id, onItemClick, popoverPlacement, keyboard) {
|
onClose: (type) => dispatch(closePopover(type)),
|
||||||
// dispatch(isUserTouching() ? openModal('ACTIONS', {
|
|
||||||
// status,
|
|
||||||
// actions: items,
|
|
||||||
// onClick: onItemClick,
|
|
||||||
// }) : openPopover(id, popoverPlacement, keyboard))
|
|
||||||
},
|
|
||||||
onClose(id) {
|
|
||||||
dispatch(closeModal())
|
|
||||||
dispatch(closePopover(id))
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
|
@ -44,10 +31,8 @@ class PopoverBase extends ImmutablePureComponent {
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
isUserTouching: PropTypes.func,
|
isUserTouching: PropTypes.func,
|
||||||
isModalOpen: PropTypes.bool.isRequired,
|
isModalOpen: PropTypes.bool.isRequired,
|
||||||
onOpen: PropTypes.func.isRequired,
|
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
position: PropTypes.string,
|
position: PropTypes.string,
|
||||||
openPopoverType: PropTypes.string,
|
|
||||||
visible: PropTypes.bool,
|
visible: PropTypes.bool,
|
||||||
targetRef: PropTypes.node,
|
targetRef: PropTypes.node,
|
||||||
innerRef: PropTypes.oneOfType([
|
innerRef: PropTypes.oneOfType([
|
||||||
|
@ -61,23 +46,57 @@ class PopoverBase extends ImmutablePureComponent {
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
componentDidMount() {
|
||||||
id: id++,
|
document.addEventListener('click', this.handleDocumentClick, false)
|
||||||
|
document.addEventListener('keydown', this.handleKeyDown, false)
|
||||||
|
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClose = () => {
|
componentWillUnmount() {
|
||||||
this.props.onClose(this.state.id)
|
document.removeEventListener('click', this.handleDocumentClick, false)
|
||||||
|
document.removeEventListener('keydown', this.handleKeyDown, false)
|
||||||
|
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleDocumentClick = (e) => {
|
||||||
|
const { targetRef, visible, onClose } = this.props
|
||||||
|
|
||||||
|
const containsTargetRef = !targetRef ? false : targetRef.contains(e.target)
|
||||||
|
|
||||||
|
if (this.node && !this.node.contains(e.target) && !containsTargetRef && visible) {
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown = (e) => {
|
||||||
|
const items = Array.from(this.node.getElementsByTagName('a'))
|
||||||
|
const index = items.indexOf(document.activeElement)
|
||||||
|
let element
|
||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
element = items[index + 1]
|
||||||
|
if (element) element.focus()
|
||||||
|
break
|
||||||
|
case 'ArrowUp':
|
||||||
|
element = items[index - 1]
|
||||||
|
if (element) element.focus()
|
||||||
|
break
|
||||||
|
case 'Home':
|
||||||
|
element = items[0]
|
||||||
|
if (element) element.focus()
|
||||||
|
break
|
||||||
|
case 'End':
|
||||||
|
element = items[items.length - 1]
|
||||||
|
if (element) element.focus()
|
||||||
|
break
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
this.handleClose()
|
this.handleClose()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleItemClick = e => {
|
handleItemClick = (e) => {
|
||||||
const i = Number(e.currentTarget.getAttribute('data-index'))
|
const i = Number(e.currentTarget.getAttribute('data-index'))
|
||||||
const { action, to } = this.props.items[i]
|
const { action, to } = this.props.items[i]
|
||||||
|
|
||||||
|
@ -92,17 +111,16 @@ class PopoverBase extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTargetRef = c => {
|
handleClose = () => {
|
||||||
this.target = c
|
this.props.onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
findTarget = () => {
|
setRef = (n) => {
|
||||||
return this.target
|
try {
|
||||||
}
|
this.node = n
|
||||||
|
this.props.innerRef = n
|
||||||
componentWillUnmount = () => {
|
} catch (error) {
|
||||||
if (this.state.id === this.props.openPopoverType) {
|
//
|
||||||
this.handleClose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +129,10 @@ class PopoverBase extends ImmutablePureComponent {
|
||||||
children,
|
children,
|
||||||
visible,
|
visible,
|
||||||
position,
|
position,
|
||||||
openPopoverType,
|
|
||||||
targetRef,
|
targetRef,
|
||||||
innerRef,
|
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const containerClasses = cx({
|
const containerClasses = CX({
|
||||||
default: 1,
|
default: 1,
|
||||||
z4: 1,
|
z4: 1,
|
||||||
displayNone: !visible,
|
displayNone: !visible,
|
||||||
|
@ -131,7 +147,7 @@ class PopoverBase extends ImmutablePureComponent {
|
||||||
{({ ref, style, placement, arrowProps }) => (
|
{({ ref, style, placement, arrowProps }) => (
|
||||||
<div ref={ref} style={style} data-placement={placement} className={[_s.mt5, _s.mb5, _s.boxShadowPopover].join(' ')}>
|
<div ref={ref} style={style} data-placement={placement} className={[_s.mt5, _s.mb5, _s.boxShadowPopover].join(' ')}>
|
||||||
<div ref={arrowProps.ref} style={arrowProps.style} />
|
<div ref={arrowProps.ref} style={arrowProps.style} />
|
||||||
<div ref={innerRef} data-popover='true' onKeyDown={this.handleKeyDown} className={containerClasses}>
|
<div ref={this.setRef} data-popover='true' onKeyDown={this.handleKeyDown} className={containerClasses}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import detectPassiveEvents from 'detect-passive-events'
|
|
||||||
import { closePopover } from '../../actions/popover'
|
|
||||||
import {
|
import {
|
||||||
POPOVER_CONTENT_WARNING,
|
POPOVER_CONTENT_WARNING,
|
||||||
POPOVER_DATE_PICKER,
|
POPOVER_DATE_PICKER,
|
||||||
|
@ -31,8 +29,6 @@ import {
|
||||||
import Bundle from '../../features/ui/util/bundle'
|
import Bundle from '../../features/ui/util/bundle'
|
||||||
import PopoverBase from './popover_base'
|
import PopoverBase from './popover_base'
|
||||||
|
|
||||||
const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false
|
|
||||||
|
|
||||||
const POPOVER_COMPONENTS = {}
|
const POPOVER_COMPONENTS = {}
|
||||||
POPOVER_COMPONENTS[POPOVER_CONTENT_WARNING] = ContentWarningPopover
|
POPOVER_COMPONENTS[POPOVER_CONTENT_WARNING] = ContentWarningPopover
|
||||||
POPOVER_COMPONENTS[POPOVER_DATE_PICKER] = DatePickerPopover
|
POPOVER_COMPONENTS[POPOVER_DATE_PICKER] = DatePickerPopover
|
||||||
|
@ -52,108 +48,23 @@ const mapStateToProps = (state) => ({
|
||||||
props: state.getIn(['popover', 'popoverProps'], {}),
|
props: state.getIn(['popover', 'popoverProps'], {}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
onClose(optionalType) {
|
|
||||||
dispatch(closePopover(optionalType))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@connect(mapStateToProps, mapDispatchToProps)
|
@connect(mapStateToProps)
|
||||||
class PopoverRoot extends PureComponent {
|
class PopoverRoot extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
props: PropTypes.object,
|
props: PropTypes.object,
|
||||||
onClose: PropTypes.func.isRequired,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSnapshotBeforeUpdate() {
|
getSnapshotBeforeUpdate() {
|
||||||
// return { visible: !!this.props.type }
|
return {
|
||||||
// }
|
visible: !!this.props.type
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
router: PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
onClose: PropTypes.func.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDocumentClick = e => {
|
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
|
||||||
this.props.onClose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
renderEmpty = () => {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false)
|
return <div />
|
||||||
document.addEventListener('keydown', this.handleKeyDown, false)
|
|
||||||
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
document.removeEventListener('click', this.handleDocumentClick, false)
|
|
||||||
document.removeEventListener('keydown', this.handleKeyDown, false)
|
|
||||||
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
setRef = (c) => {
|
|
||||||
this.node = c
|
|
||||||
}
|
|
||||||
|
|
||||||
handleKeyDown = e => {
|
|
||||||
const items = Array.from(this.node.getElementsByTagName('a'))
|
|
||||||
const index = items.indexOf(document.activeElement)
|
|
||||||
let element
|
|
||||||
|
|
||||||
switch (e.key) {
|
|
||||||
case 'ArrowDown':
|
|
||||||
element = items[index + 1]
|
|
||||||
if (element) element.focus()
|
|
||||||
break
|
|
||||||
case 'ArrowUp':
|
|
||||||
element = items[index - 1]
|
|
||||||
if (element) element.focus()
|
|
||||||
break
|
|
||||||
case 'Home':
|
|
||||||
element = items[0]
|
|
||||||
if (element) element.focus()
|
|
||||||
break
|
|
||||||
case 'End':
|
|
||||||
element = items[items.length - 1]
|
|
||||||
if (element) element.focus()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleItemKeyDown = e => {
|
|
||||||
if (e.key === 'Enter') {
|
|
||||||
this.handleClick(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClick = e => {
|
|
||||||
const i = Number(e.currentTarget.getAttribute('data-index'))
|
|
||||||
const { action, to } = this.props.items[i]
|
|
||||||
|
|
||||||
this.props.onClose()
|
|
||||||
|
|
||||||
if (typeof action === 'function') {
|
|
||||||
e.preventDefault()
|
|
||||||
action(e)
|
|
||||||
} else if (to) {
|
|
||||||
e.preventDefault()
|
|
||||||
this.context.router.history.push(to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderError = () => {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLoading = () => {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -170,8 +81,8 @@ class PopoverRoot extends PureComponent {
|
||||||
visible &&
|
visible &&
|
||||||
<Bundle
|
<Bundle
|
||||||
fetchComponent={POPOVER_COMPONENTS[type]}
|
fetchComponent={POPOVER_COMPONENTS[type]}
|
||||||
loading={this.renderLoading()}
|
loading={this.renderEmpty}
|
||||||
error={this.renderError}
|
error={this.renderEmpty}
|
||||||
renderDelay={200}
|
renderDelay={200}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,7 @@ import List from '../list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
|
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
|
||||||
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
|
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
|
||||||
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
||||||
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
||||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
|
@ -39,13 +39,13 @@ const messages = defineMessages({
|
||||||
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
|
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
|
||||||
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
|
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
|
||||||
media: { id: 'account.media', defaultMessage: 'Media' },
|
media: { id: 'account.media', defaultMessage: 'Media' },
|
||||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
|
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
|
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||||
hideReposts: { id: 'account.hide_reblogs', defaultMessage: 'Hide reposts from @{name}' },
|
hideReposts: { id: 'account.hide_reblogs', defaultMessage: 'Hide reposts from @{name}' },
|
||||||
showReposts: { id: 'account.show_reblogs', defaultMessage: 'Show reposts from @{name}' },
|
showReposts: { id: 'account.show_reblogs', defaultMessage: 'Show reposts from @{name}' },
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||||
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
|
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||||
admin_account: { id: 'admin_account', defaultMessage: 'Open moderation interface' },
|
admin_account: { id: 'admin_account', defaultMessage: 'Open moderation interface' },
|
||||||
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
|
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
|
||||||
|
|
|
@ -1,94 +1,121 @@
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
|
import {
|
||||||
|
MODAL_BOOST,
|
||||||
|
MODAL_CONFIRM,
|
||||||
|
MODAL_UNAUTHORIZED,
|
||||||
|
} from '../../constants'
|
||||||
|
import { boostModal, me } from '../../initial_state'
|
||||||
import { quoteCompose } from '../../actions/compose'
|
import { quoteCompose } from '../../actions/compose'
|
||||||
import { repost, unrepost } from '../../actions/interactions'
|
import { repost, unrepost } from '../../actions/interactions'
|
||||||
|
import { closePopover } from '../../actions/popover'
|
||||||
import { openModal } from '../../actions/modal'
|
import { openModal } from '../../actions/modal'
|
||||||
import { boostModal, me } from '../../initial_state'
|
|
||||||
import PopoverLayout from './popover_layout'
|
import PopoverLayout from './popover_layout'
|
||||||
import List from '../list'
|
import List from '../list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
repost: { id: 'repost', defaultMessage: 'Repost' },
|
repost: { id: 'repost', defaultMessage: 'Repost' },
|
||||||
|
removeRepost: { id: 'status.cancel_repost_private', defaultMessage: 'Remove Repost' },
|
||||||
repostWithComment: { id: 'repost_with_comment', defaultMessage: 'Repost with comment' },
|
repostWithComment: { id: 'repost_with_comment', defaultMessage: 'Repost with comment' },
|
||||||
});
|
quoteMessage: { id: 'confirmations.quote.message', defaultMessage: 'Quoting now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
||||||
|
quoteConfirm: { id: 'confirmations.quote.confirm', defaultMessage: 'Quote' },
|
||||||
|
})
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
onQuote (status, router) {
|
onQuote (status, router) {
|
||||||
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
if (!me) return dispatch(openModal(MODAL_UNAUTHORIZED))
|
||||||
|
|
||||||
|
dispatch(closePopover())
|
||||||
|
|
||||||
dispatch((_, getState) => {
|
dispatch((_, getState) => {
|
||||||
const state = getState();
|
const state = getState()
|
||||||
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal(MODAL_CONFIRM, {
|
||||||
message: intl.formatMessage(messages.quoteMessage),
|
message: intl.formatMessage(messages.quoteMessage),
|
||||||
confirm: intl.formatMessage(messages.quoteConfirm),
|
confirm: intl.formatMessage(messages.quoteConfirm),
|
||||||
onConfirm: () => dispatch(quoteCompose(status, router)),
|
onConfirm: () => dispatch(quoteCompose(status, router)),
|
||||||
}));
|
}))
|
||||||
} else {
|
} else {
|
||||||
dispatch(quoteCompose(status, router));
|
dispatch(quoteCompose(status, router))
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onRepost (status) {
|
onRepost (status) {
|
||||||
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
if (!me) return dispatch(openModal(MODAL_UNAUTHORIZED))
|
||||||
|
|
||||||
if (status.get('reblogged')) {
|
dispatch(closePopover())
|
||||||
dispatch(unrepost(status));
|
|
||||||
|
const alreadyReposted = status.get('reblogged')
|
||||||
|
|
||||||
|
if (boostModal && !alreadyReposted) {
|
||||||
|
dispatch(openModal(MODAL_BOOST, {
|
||||||
|
status,
|
||||||
|
onRepost: () => dispatch(repost(status)),
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
dispatch(repost(status));
|
if (alreadyReposted) {
|
||||||
|
dispatch(unrepost(status))
|
||||||
|
} else {
|
||||||
|
dispatch(repost(status))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
@connect(null, mapDispatchToProps)
|
@connect(null, mapDispatchToProps)
|
||||||
class RepostOptionsPopover extends ImmutablePureComponent {
|
class RepostOptionsPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
|
||||||
onQuote: PropTypes.func.isRequired,
|
onQuote: PropTypes.func.isRequired,
|
||||||
onRepost: PropTypes.func.isRequired,
|
onRepost: PropTypes.func.isRequired,
|
||||||
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOnProps = ['status']
|
updateOnProps = [
|
||||||
|
'status',
|
||||||
handleOnRepost = () => {
|
]
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnQuote = () => {
|
handleOnQuote = () => {
|
||||||
|
this.props.onQuote(this.props.status, this.context.router.history)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnRepost = () => {
|
||||||
|
this.props.onRepost(this.props.status)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl } = this.props
|
const { intl, status } = this.props
|
||||||
|
|
||||||
const listItems = [
|
const alreadyReposted = status.get('reblogged')
|
||||||
{
|
|
||||||
hideArrow: true,
|
|
||||||
icon: 'repost',
|
|
||||||
title: intl.formatMessage(messages.repost),
|
|
||||||
onClick: this.handleOnRepost,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
hideArrow: true,
|
|
||||||
icon: 'pencil',
|
|
||||||
title: intl.formatMessage(messages.repostWithComment),
|
|
||||||
onClick: this.handleBlockDomain,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout width={220}>
|
<PopoverLayout width={220}>
|
||||||
<List
|
<List
|
||||||
scrollKey='repost_options'
|
scrollKey='repost_options'
|
||||||
items={listItems}
|
|
||||||
size='large'
|
size='large'
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
icon: 'repost',
|
||||||
|
title: intl.formatMessage(!alreadyReposted ? messages.repost : messages.removeRepost),
|
||||||
|
onClick: this.handleOnRepost,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hideArrow: true,
|
||||||
|
icon: 'pencil',
|
||||||
|
title: intl.formatMessage(messages.repostWithComment),
|
||||||
|
onClick: this.handleOnQuote,
|
||||||
|
}
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</PopoverLayout>
|
</PopoverLayout>
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,18 +8,16 @@ import List from '../list'
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||||
edit: { id: 'status.edit', defaultMessage: 'Edit' },
|
edit: { id: 'status.edit', defaultMessage: 'Edit' },
|
||||||
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
|
||||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||||
reply: { id: 'status.reply', defaultMessage: 'Reply' },
|
reply: { id: 'status.reply', defaultMessage: 'Reply' },
|
||||||
comment: { id: 'status.comment', defaultMessage: 'Comment' },
|
|
||||||
more: { id: 'status.more', defaultMessage: 'More' },
|
more: { id: 'status.more', defaultMessage: 'More' },
|
||||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
share: { id: 'status.share', defaultMessage: 'Share' },
|
||||||
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
||||||
repost: { id: 'repost', defaultMessage: 'Repost' },
|
repost: { id: 'repost', defaultMessage: 'Repost' },
|
||||||
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
||||||
repost_private: { id: 'status.repost_private', defaultMessage: 'Repost to original audience' },
|
repost_private: { id: 'status.repost_private', defaultMessage: 'Repost to original audience' },
|
||||||
cancel_repost_private: { id: 'status.cancel_repost_private', defaultMessage: 'Un-repost' },
|
cancel_repost_private: { id: 'status.cancel_repost_private', defaultMessage: 'Remove Repost' },
|
||||||
cannot_repost: { id: 'status.cannot_repost', defaultMessage: 'This post cannot be reposted' },
|
cannot_repost: { id: 'status.cannot_repost', defaultMessage: 'This post cannot be reposted' },
|
||||||
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
|
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
|
||||||
like: { id: 'status.like', defaultMessage: 'Like' },
|
like: { id: 'status.like', defaultMessage: 'Like' },
|
||||||
|
@ -34,9 +32,19 @@ const messages = defineMessages({
|
||||||
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove status from group' },
|
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove status from group' },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
|
@connect(mapStateToProps, mapDispatchToProps)
|
||||||
class StatusOptionsPopover extends ImmutablePureComponent {
|
class StatusOptionsPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
account: ImmutablePropTypes.map.isRequired,
|
||||||
|
@ -56,7 +64,10 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOnProps = ['status', 'account']
|
updateOnProps = [
|
||||||
|
'status',
|
||||||
|
'account',
|
||||||
|
]
|
||||||
|
|
||||||
handleConversationMuteClick = () => {
|
handleConversationMuteClick = () => {
|
||||||
this.props.onMuteConversation(this.props.status);
|
this.props.onMuteConversation(this.props.status);
|
||||||
|
@ -111,7 +122,7 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getItems = () => {
|
render() {
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
intl,
|
intl,
|
||||||
|
@ -123,114 +134,104 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
if (!me) return menu
|
if (me) {
|
||||||
|
// if (status.getIn(['account', 'id']) === me) {
|
||||||
|
menu.push({
|
||||||
|
icon: 'audio-mute',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
||||||
|
onClick: this.handleConversationMuteClick,
|
||||||
|
})
|
||||||
|
// }
|
||||||
|
|
||||||
if (status.getIn(['account', 'id']) === me) {
|
// if (status.getIn(['account', 'id']) === me) {
|
||||||
menu.push({
|
// if (publicStatus) {
|
||||||
icon: 'mute',
|
menu.push({
|
||||||
hideArrow: true,
|
icon: 'pin',
|
||||||
title: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
hideArrow: true,
|
||||||
onClick: this.handleConversationMuteClick,
|
title: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin),
|
||||||
})
|
onClick: this.handlePinClick,
|
||||||
}
|
})
|
||||||
|
// } else {
|
||||||
if (status.getIn(['account', 'id']) === me) {
|
// if (status.get('visibility') === 'private') {
|
||||||
if (publicStatus) {
|
menu.push({
|
||||||
|
icon: 'repost',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private),
|
||||||
|
onClick: this.handleRepostClick
|
||||||
|
})
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
menu.push({
|
||||||
|
icon: 'trash',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(messages.delete),
|
||||||
|
action: this.handleDeleteClick
|
||||||
|
});
|
||||||
|
menu.push({
|
||||||
|
icon: 'pencil',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(messages.edit), action:
|
||||||
|
this.handleEditClick
|
||||||
|
});
|
||||||
|
// } else {
|
||||||
|
menu.push({
|
||||||
|
icon: 'audio-mute',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }),
|
||||||
|
action: this.handleMuteClick
|
||||||
|
});
|
||||||
menu.push({
|
menu.push({
|
||||||
icon: 'circle',
|
icon: 'circle',
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
title: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin),
|
title: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }),
|
||||||
onClick: this.handlePinClick,
|
action: this.handleBlockClick
|
||||||
})
|
});
|
||||||
} else {
|
menu.push({
|
||||||
if (status.get('visibility') === 'private') {
|
icon: 'circle',
|
||||||
|
hideArrow: true,
|
||||||
|
title: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }),
|
||||||
|
action: this.handleReport
|
||||||
|
});
|
||||||
|
|
||||||
|
// : todo :
|
||||||
|
// if (withGroupAdmin) {
|
||||||
menu.push({
|
menu.push({
|
||||||
icon: 'circle',
|
icon: 'circle',
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
title: intl.formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private),
|
title: intl.formatMessage(messages.group_remove_account),
|
||||||
onClick: this.handleRepostClick
|
action: this.handleGroupRemoveAccount
|
||||||
})
|
});
|
||||||
}
|
menu.push({
|
||||||
}
|
icon: 'circle',
|
||||||
menu.push({
|
hideArrow: true,
|
||||||
icon: 'circle',
|
title: intl.formatMessage(messages.group_remove_post),
|
||||||
hideArrow: true,
|
action: this.handleGroupRemovePost
|
||||||
title: intl.formatMessage(messages.delete),
|
});
|
||||||
action: this.handleDeleteClick
|
// }
|
||||||
});
|
|
||||||
menu.push({
|
|
||||||
icon: 'circle',
|
|
||||||
hideArrow: true,
|
|
||||||
title: intl.formatMessage(messages.edit), action:
|
|
||||||
this.handleEditClick
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
menu.push({
|
|
||||||
icon: 'comment',
|
|
||||||
hideArrow: true,
|
|
||||||
title: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }),
|
|
||||||
action: this.handleMentionClick
|
|
||||||
});
|
|
||||||
menu.push({
|
|
||||||
icon: 'mute',
|
|
||||||
hideArrow: true,
|
|
||||||
title: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }),
|
|
||||||
action: this.handleMuteClick
|
|
||||||
});
|
|
||||||
menu.push({
|
|
||||||
icon: 'circle',
|
|
||||||
hideArrow: true,
|
|
||||||
title: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }),
|
|
||||||
action: this.handleBlockClick
|
|
||||||
});
|
|
||||||
menu.push({
|
|
||||||
icon: 'circle',
|
|
||||||
hideArrow: true,
|
|
||||||
title: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }),
|
|
||||||
action: this.handleReport
|
|
||||||
});
|
|
||||||
|
|
||||||
// if (withGroupAdmin) {
|
// if (isStaff) {
|
||||||
// menu.push({
|
menu.push({
|
||||||
// icon: 'circle',
|
title: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
|
||||||
// hideArrow: true,
|
href: `/admin/accounts/${status.getIn(['account', 'id'])}`
|
||||||
// title: intl.formatMessage(messages.group_remove_account),
|
});
|
||||||
// action: this.handleGroupRemoveAccount
|
menu.push({
|
||||||
// });
|
title: intl.formatMessage(messages.admin_status),
|
||||||
// menu.push({
|
href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`
|
||||||
// icon: 'circle',
|
});
|
||||||
// hideArrow: true,
|
// }
|
||||||
// title: intl.formatMessage(messages.group_remove_post),
|
|
||||||
// action: this.handleGroupRemovePost
|
|
||||||
// });
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (isStaff) {
|
|
||||||
menu.push({
|
|
||||||
title: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
|
|
||||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}`
|
|
||||||
});
|
|
||||||
menu.push({
|
|
||||||
title: intl.formatMessage(messages.admin_status),
|
|
||||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const items = this.getItems()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout className={_s.width240PX}>
|
<PopoverLayout className={_s.width240PX}>
|
||||||
<List
|
<List
|
||||||
size='large'
|
size='large'
|
||||||
scrollKey='profile_options'
|
scrollKey='profile_options'
|
||||||
items={items}
|
items={menu}
|
||||||
/>
|
/>
|
||||||
</PopoverLayout>
|
</PopoverLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,65 +1,71 @@
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
|
import { closePopover } from '../../actions/popover'
|
||||||
|
import { openModal } from '../../actions/modal'
|
||||||
|
import {
|
||||||
|
MODAL_EMBED,
|
||||||
|
POPOVER_STATUS_SHARE,
|
||||||
|
} from '../../constants'
|
||||||
import PopoverLayout from './popover_layout'
|
import PopoverLayout from './popover_layout'
|
||||||
import List from '../list'
|
import List from '../list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
embed: { id: 'status.embed', defaultMessage: 'Embed gab' },
|
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
||||||
email: { id: 'status.email', defaultMessage: 'Email gab' },
|
email: { id: 'status.email', defaultMessage: 'Email this gab' },
|
||||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to gab' },
|
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
||||||
});
|
});
|
||||||
|
|
||||||
// const makeMapStateToProps = () => {
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
// const getAccount = makeGetAccount();
|
onClosePopover: () => dispatch(closePopover(POPOVER_STATUS_SHARE)),
|
||||||
|
onOpenEmbedModal(url) {
|
||||||
// const mapStateToProps = (state, { account }) => ({
|
dispatch(openModal(MODAL_EMBED, {
|
||||||
|
url,
|
||||||
// });
|
}))
|
||||||
|
},
|
||||||
// return mapStateToProps;
|
});
|
||||||
// };
|
|
||||||
|
|
||||||
// const mapDispatchToProps = (dispatch, { intl }) => ({
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// : todo :
|
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
// @connect(makeMapStateToProps, mapDispatchToProps)
|
@connect(null, mapDispatchToProps)
|
||||||
class StatusSharePopover extends ImmutablePureComponent {
|
class StatusSharePopover extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
onClosePopover: PropTypes.func.isRequired,
|
||||||
|
onOpenEmbedModal: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmbed = () => {
|
handleOnOpenEmbedModal = () => {
|
||||||
// this.props.onEmbed(this.props.status);
|
this.props.onOpenEmbedModal(this.props.status.get('url'))
|
||||||
|
this.props.onClosePopover()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCopy = () => {
|
handleCopy = () => {
|
||||||
// const url = this.props.status.get('url');
|
const url = this.props.status.get('url');
|
||||||
// const textarea = document.createElement('textarea');
|
const textarea = document.createElement('textarea');
|
||||||
|
|
||||||
// textarea.textContent = url;
|
textarea.textContent = url;
|
||||||
// textarea.style.position = 'fixed';
|
textarea.style.position = 'fixed';
|
||||||
|
|
||||||
// document.body.appendChild(textarea);
|
document.body.appendChild(textarea);
|
||||||
|
|
||||||
// try {
|
try {
|
||||||
// textarea.select();
|
textarea.select();
|
||||||
// document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
// } catch (e) {
|
} catch (e) {
|
||||||
// //
|
//
|
||||||
// } finally {
|
}
|
||||||
// document.body.removeChild(textarea);
|
|
||||||
// }
|
document.body.removeChild(textarea);
|
||||||
|
this.props.onClosePopover()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl } = this.props
|
const { intl, status } = this.props
|
||||||
|
|
||||||
|
const mailToHref = !status ? undefined : `mailto:?subject=&body=${status.get('url')}`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout width={220}>
|
<PopoverLayout width={220}>
|
||||||
|
@ -77,13 +83,13 @@ class StatusSharePopover extends ImmutablePureComponent {
|
||||||
icon: 'email',
|
icon: 'email',
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
title: intl.formatMessage(messages.email),
|
title: intl.formatMessage(messages.email),
|
||||||
href: 'mailto:',
|
href: mailToHref,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'code',
|
icon: 'code',
|
||||||
hideArrow: true,
|
hideArrow: true,
|
||||||
title: intl.formatMessage(messages.embed),
|
title: intl.formatMessage(messages.embed),
|
||||||
onClick: this.handleEmbed,
|
onClick: this.handleOnOpenEmbedModal,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
small
|
small
|
||||||
|
|
|
@ -10,11 +10,11 @@ const cx = classNames.bind(_s)
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
|
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
|
||||||
public_long: { id: 'privacy.public.long', defaultMessage: 'Post to public timelines' },
|
public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for anyone on or off Gab' },
|
||||||
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
|
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
|
||||||
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
|
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
|
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
|
||||||
private_long: { id: 'privacy.private.long', defaultMessage: 'Post to followers only' },
|
private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for your followers only' },
|
||||||
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
|
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
|
||||||
visibility: { id: 'privacy.visibility', defaultMessage: 'Visibility' },
|
visibility: { id: 'privacy.visibility', defaultMessage: 'Visibility' },
|
||||||
})
|
})
|
||||||
|
@ -43,14 +43,14 @@ class StatusVisibilityDropdown extends PureComponent {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = value => {
|
handleChange = (value) => {
|
||||||
this.props.onChange(value)
|
this.props.onChange(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
render () {
|
||||||
const { intl } = this.props
|
const { intl, value } = this.props
|
||||||
|
|
||||||
this.options = [
|
const options = [
|
||||||
{
|
{
|
||||||
icon: 'globe',
|
icon: 'globe',
|
||||||
value: 'public',
|
value: 'public',
|
||||||
|
@ -70,18 +70,14 @@ class StatusVisibilityDropdown extends PureComponent {
|
||||||
subtitle: intl.formatMessage(messages.private_long)
|
subtitle: intl.formatMessage(messages.private_long)
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { value } = this.props
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverLayout className={_s.width240PX}>
|
<PopoverLayout width={300}>
|
||||||
<div className={[_s.default].join(' ')}>
|
<div className={[_s.default].join(' ')}>
|
||||||
{
|
{
|
||||||
this.options.map((option, i) => {
|
options.map((option, i) => {
|
||||||
const isActive = option.value === value
|
const isActive = option.value === value
|
||||||
const isLast = i === this.options.length - 1
|
const isLast = i === options.length - 1
|
||||||
|
|
||||||
const containerClasses = cx({
|
const containerClasses = cx({
|
||||||
default: 1,
|
default: 1,
|
||||||
|
|
|
@ -5,7 +5,10 @@ import Text from './text'
|
||||||
export default class ProgressBar extends PureComponent {
|
export default class ProgressBar extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
progress: PropTypes.number,
|
progress: PropTypes.oneOfType([
|
||||||
|
PropTypes.number,
|
||||||
|
PropTypes.string,
|
||||||
|
]).isRequired,
|
||||||
small: PropTypes.bool,
|
small: PropTypes.bool,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
href: PropTypes.string,
|
href: PropTypes.string,
|
||||||
|
|
|
@ -75,10 +75,10 @@ class Search extends PureComponent {
|
||||||
const { value } = this.props
|
const { value } = this.props
|
||||||
|
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
|
|
||||||
this.props.onSubmit();
|
this.props.onSubmit()
|
||||||
this.context.router.history.push(`/search?q=${value}`);
|
this.context.router.history.push(`/search?q=${value}`)
|
||||||
|
|
||||||
} else if (e.key === 'Escape') {
|
} else if (e.key === 'Escape') {
|
||||||
this.textbox.blur()
|
this.textbox.blur()
|
||||||
|
|
|
@ -22,7 +22,7 @@ const messages = defineMessages({
|
||||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||||
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||||
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
|
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||||
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
||||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||||
|
@ -211,11 +211,14 @@ class Sidebar extends ImmutablePureComponent {
|
||||||
<div className={[_s.default, _s.posFixed, _s.heightCalc53PX, _s.bottom0].join(' ')}>
|
<div className={[_s.default, _s.posFixed, _s.heightCalc53PX, _s.bottom0].join(' ')}>
|
||||||
<div className={[_s.default, _s.height100PC, _s.alignItemsStart, _s.width240PX, _s.pr15, _s.py10, _s.overflowYScroll].join(' ')}>
|
<div className={[_s.default, _s.height100PC, _s.alignItemsStart, _s.width240PX, _s.pr15, _s.py10, _s.overflowYScroll].join(' ')}>
|
||||||
<div className={_s.default}>
|
<div className={_s.default}>
|
||||||
<div className={[_s.default, _s.px5, _s.py10].join(' ')}>
|
{
|
||||||
<Heading size='h1'>
|
!!title &&
|
||||||
{title}
|
<div className={[_s.default, _s.px5, _s.py10].join(' ')}>
|
||||||
</Heading>
|
<Heading size='h1'>
|
||||||
</div>
|
{title}
|
||||||
|
</Heading>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
{
|
{
|
||||||
!!tabs &&
|
!!tabs &&
|
||||||
<div className={[_s.default, _s.mt10, _s.pb15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
<div className={[_s.default, _s.mt10, _s.pb15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||||
|
|
|
@ -51,8 +51,9 @@ export default class SidebarSectionItem extends PureComponent {
|
||||||
} = this.props
|
} = this.props
|
||||||
const { hovering } = this.state
|
const { hovering } = this.state
|
||||||
|
|
||||||
|
const noRouter = !this.context.router
|
||||||
const iconSize = '16px'
|
const iconSize = '16px'
|
||||||
const currentPathname = this.context.router ? this.context.router.route.location.pathname : undefined
|
const currentPathname = noRouter ? '' : this.context.router.route.location.pathname
|
||||||
const shouldShowActive = hovering || active || currentPathname === to || currentPathname === href
|
const shouldShowActive = hovering || active || currentPathname === to || currentPathname === href
|
||||||
const isNotifications = to === '/notifications'
|
const isNotifications = to === '/notifications'
|
||||||
|
|
||||||
|
@ -103,8 +104,8 @@ export default class SidebarSectionItem extends PureComponent {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
to={to}
|
to={noRouter ? undefined : to}
|
||||||
href={href}
|
href={noRouter ? (to || href) : href}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
noClasses
|
noClasses
|
||||||
buttonRef={buttonRef}
|
buttonRef={buttonRef}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { injectIntl } from 'react-intl'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { HotKeys } from 'react-hotkeys'
|
import { HotKeys } from 'react-hotkeys'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames/bind'
|
||||||
import { me, displayMedia } from '../initial_state'
|
import { me, displayMedia, compactMode } from '../initial_state'
|
||||||
import StatusCard from './status_card'
|
import StatusCard from './status_card'
|
||||||
import { MediaGallery, Video } from '../features/ui/util/async_components'
|
import { MediaGallery, Video } from '../features/ui/util/async_components'
|
||||||
import ComposeFormContainer from '../features/compose/containers/compose_form_container'
|
import ComposeFormContainer from '../features/compose/containers/compose_form_container'
|
||||||
|
@ -44,8 +44,6 @@ export const textForScreenReader = (intl, status, rebloggedByText = false) => {
|
||||||
export const defaultMediaVisibility = (status) => {
|
export const defaultMediaVisibility = (status) => {
|
||||||
if (!status) return undefined
|
if (!status) return undefined
|
||||||
|
|
||||||
// console.log("status:", status)
|
|
||||||
|
|
||||||
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||||
status = status.get('reblog')
|
status = status.get('reblog')
|
||||||
}
|
}
|
||||||
|
@ -337,7 +335,6 @@ class Status extends ImmutablePureComponent {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
intl,
|
intl,
|
||||||
status,
|
|
||||||
isFeatured,
|
isFeatured,
|
||||||
isPromoted,
|
isPromoted,
|
||||||
isChild,
|
isChild,
|
||||||
|
@ -345,6 +342,8 @@ class Status extends ImmutablePureComponent {
|
||||||
descendantsIds,
|
descendantsIds,
|
||||||
commentsLimited,
|
commentsLimited,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
|
let { status } = this.props
|
||||||
|
|
||||||
if (!status) return null
|
if (!status) return null
|
||||||
|
|
||||||
|
@ -356,6 +355,7 @@ class Status extends ImmutablePureComponent {
|
||||||
{ name: status.getIn(['account', 'acct']) }
|
{ name: status.getIn(['account', 'acct']) }
|
||||||
)
|
)
|
||||||
reblogContent = status.get('contentHtml')
|
reblogContent = status.get('contentHtml')
|
||||||
|
status = status.get('reblog')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlers = (this.props.isMuted || isChild) ? {} : {
|
const handlers = (this.props.isMuted || isChild) ? {} : {
|
||||||
|
@ -445,14 +445,15 @@ class Status extends ImmutablePureComponent {
|
||||||
const containerClasses = cx({
|
const containerClasses = cx({
|
||||||
default: 1,
|
default: 1,
|
||||||
pb15: isFeatured,
|
pb15: isFeatured,
|
||||||
radiusSmall: !isChild,
|
radiusSmall: !isChild && !compactMode,
|
||||||
bgPrimary: !isChild,
|
bgPrimary: !isChild,
|
||||||
boxShadowBlock: !isChild,
|
boxShadowBlock: !isChild && !compactMode,
|
||||||
outlineNone: 1,
|
outlineNone: 1,
|
||||||
mb15: !isChild,
|
mb15: !isChild && !compactMode,
|
||||||
// border1PX: !isChild,
|
borderRight1PX: !isChild && compactMode,
|
||||||
// borderBottom1PX: isFeatured && !isChild,
|
borderLeft1PX: !isChild && compactMode,
|
||||||
// borderColorSecondary: !isChild,
|
borderBottom1PX: !isChild && compactMode,
|
||||||
|
borderColorSecondary: !isChild && compactMode,
|
||||||
})
|
})
|
||||||
|
|
||||||
const innerContainerClasses = cx({
|
const innerContainerClasses = cx({
|
||||||
|
@ -481,7 +482,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
<div data-id={status.get('id')}>
|
<div data-id={status.get('id')}>
|
||||||
|
|
||||||
<StatusPrepend status={status} isPromoted={isPromoted} isFeatured={isFeatured} />
|
<StatusPrepend status={this.props.status} isPromoted={isPromoted} isFeatured={isFeatured} />
|
||||||
|
|
||||||
<StatusHeader status={status} reduced={isChild} />
|
<StatusHeader status={status} reduced={isChild} />
|
||||||
|
|
||||||
|
@ -517,19 +518,19 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!isChild && !!me &&
|
!isChild && !compactMode && !!me &&
|
||||||
<div className={[_s.default, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}>
|
<div className={[_s.default, _s.borderTop1PX, _s.borderColorSecondary, _s.pt10, _s.px15, _s.mb10].join(' ')}>
|
||||||
<ComposeFormContainer replyToId={status.get('id')} shouldCondense />
|
<ComposeFormContainer replyToId={status.get('id')} shouldCondense />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
descendantsIds && !isChild && descendantsIds.size > 0 &&
|
descendantsIds && !compactMode && !isChild && descendantsIds.size > 0 &&
|
||||||
<div className={[_s.default, _s.mr10, _s.ml10, _s.mb10, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')}/>
|
<div className={[_s.default, _s.mr10, _s.ml10, _s.mb10, _s.borderColorSecondary, _s.borderBottom1PX].join(' ')}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
descendantsIds && !isChild && descendantsIds.size > 0 &&
|
descendantsIds && !compactMode && !isChild && descendantsIds.size > 0 &&
|
||||||
<CommentList
|
<CommentList
|
||||||
commentsLimited={commentsLimited}
|
commentsLimited={commentsLimited}
|
||||||
descendants={descendantsIds}
|
descendants={descendantsIds}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import { defineMessages, injectIntl } from 'react-intl'
|
import { defineMessages, injectIntl } from 'react-intl'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
|
import { compactMode } from '../initial_state'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import StatusActionBarItem from './status_action_bar_item'
|
import StatusActionBarItem from './status_action_bar_item'
|
||||||
import {
|
import {
|
||||||
|
@ -21,6 +22,10 @@ const messages = defineMessages({
|
||||||
commentsLabel: { id: 'comments.label', defaultMessage: '{number, plural, one {# comment} other {# comments}}' },
|
commentsLabel: { id: 'comments.label', defaultMessage: '{number, plural, one {# comment} other {# comments}}' },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const NOU = (num) => {
|
||||||
|
return num <= 0 ? undefined : num
|
||||||
|
}
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@injectIntl
|
@injectIntl
|
||||||
class StatusActionBar extends ImmutablePureComponent {
|
class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
@ -102,9 +107,9 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
py2: 1,
|
py2: 1,
|
||||||
flexRow: 1,
|
flexRow: 1,
|
||||||
width100PC: 1,
|
width100PC: 1,
|
||||||
borderTop1PX: !shouldCondense,
|
borderTop1PX: !shouldCondense && !compactMode,
|
||||||
borderColorSecondary: !shouldCondense,
|
borderColorSecondary: !shouldCondense && !compactMode,
|
||||||
mt5: hasInteractions,
|
mt5: hasInteractions && !compactMode,
|
||||||
})
|
})
|
||||||
|
|
||||||
const interactionBtnClasses = CX({
|
const interactionBtnClasses = CX({
|
||||||
|
@ -122,7 +127,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className={containerClasses}>
|
<div className={containerClasses}>
|
||||||
{
|
{
|
||||||
hasInteractions &&
|
hasInteractions && !compactMode &&
|
||||||
<div className={[_s.default, _s.flexRow, _s.alignItemsEnd, _s.px5].join(' ')}>
|
<div className={[_s.default, _s.flexRow, _s.alignItemsEnd, _s.px5].join(' ')}>
|
||||||
{
|
{
|
||||||
favoriteCount > 0 &&
|
favoriteCount > 0 &&
|
||||||
|
@ -162,18 +167,18 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
<div className={innerContainerClasses}>
|
<div className={innerContainerClasses}>
|
||||||
<div className={[_s.default, _s.flexRow, _s.py2, _s.width100PC].join(' ')}>
|
<div className={[_s.default, _s.flexRow, _s.py2, _s.width100PC].join(' ')}>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.like)}
|
title={compactMode ? NOU(favoriteCount) : intl.formatMessage(messages.like)}
|
||||||
icon={!!status.get('favourited') ? 'liked' : 'like'}
|
icon={!!status.get('favourited') ? 'liked' : 'like'}
|
||||||
active={!!status.get('favourited')}
|
active={!!status.get('favourited')}
|
||||||
onClick={this.handleFavoriteClick}
|
onClick={this.handleFavoriteClick}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.comment)}
|
title={compactMode ? NOU(replyCount) : intl.formatMessage(messages.comment)}
|
||||||
icon='comment'
|
icon='comment'
|
||||||
onClick={this.handleReplyClick}
|
onClick={this.handleReplyClick}
|
||||||
/>
|
/>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
title={intl.formatMessage(messages.repost)}
|
title={compactMode ? NOU(repostCount) : intl.formatMessage(messages.repost)}
|
||||||
altTitle={!publicStatus ? intl.formatMessage(messages.cannot_repost) : ''}
|
altTitle={!publicStatus ? intl.formatMessage(messages.cannot_repost) : ''}
|
||||||
icon={!publicStatus ? 'lock' : 'repost'}
|
icon={!publicStatus ? 'lock' : 'repost'}
|
||||||
disabled={!publicStatus}
|
disabled={!publicStatus}
|
||||||
|
@ -184,7 +189,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||||
<StatusActionBarItem
|
<StatusActionBarItem
|
||||||
buttonRef={this.setShareButton}
|
buttonRef={this.setShareButton}
|
||||||
title={intl.formatMessage(messages.share)}
|
title={compactMode ? '' : intl.formatMessage(messages.share)}
|
||||||
icon='share'
|
icon='share'
|
||||||
onClick={this.handleShareClick}
|
onClick={this.handleShareClick}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import classNames from 'classnames/bind'
|
import { compactMode } from '../initial_state'
|
||||||
|
import { CX } from '../constants'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Icon from './icon'
|
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
|
|
||||||
const cx = classNames.bind(_s)
|
|
||||||
|
|
||||||
export default class StatusActionBarItem extends PureComponent {
|
export default class StatusActionBarItem extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
|
@ -30,18 +28,34 @@ export default class StatusActionBarItem extends PureComponent {
|
||||||
altTitle
|
altTitle
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const btnClasses = cx({
|
const containerClasses = CX({
|
||||||
|
default: 1,
|
||||||
|
px5: !compactMode,
|
||||||
|
px10: compactMode,
|
||||||
|
flexNormal: !compactMode,
|
||||||
|
})
|
||||||
|
|
||||||
|
const btnClasses = CX({
|
||||||
justifyContentCenter: 1,
|
justifyContentCenter: 1,
|
||||||
alignItemsCenter: 1,
|
alignItemsCenter: 1,
|
||||||
px10: 1,
|
px10: !compactMode,
|
||||||
|
px15: compactMode,
|
||||||
|
pt10: compactMode,
|
||||||
bgSubtle_onHover: !disabled,
|
bgSubtle_onHover: !disabled,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const iconClasses = CX({
|
||||||
|
default: 1,
|
||||||
|
inheritFill: 1,
|
||||||
|
mr10: !!title,
|
||||||
|
})
|
||||||
|
|
||||||
const color = active ? 'brand' : 'secondary'
|
const color = active ? 'brand' : 'secondary'
|
||||||
const weight = active ? 'bold' : 'medium'
|
const weight = active ? 'bold' : 'medium'
|
||||||
|
const iconSize = compactMode ? '14px' : '16px'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.default, _s.flexNormal, _s.px5].join(' ')}>
|
<div className={containerClasses}>
|
||||||
<Button
|
<Button
|
||||||
isBlock
|
isBlock
|
||||||
radiusSmall
|
radiusSmall
|
||||||
|
@ -53,12 +67,15 @@ export default class StatusActionBarItem extends PureComponent {
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
isDisabled={disabled}
|
isDisabled={disabled}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
iconSize='16px'
|
iconSize={iconSize}
|
||||||
iconClassName={[_s.default, _s.mr10, _s.inheritFill].join(' ')}
|
iconClassName={iconClasses}
|
||||||
>
|
>
|
||||||
<Text color='inherit' size='small' weight={weight}>
|
{
|
||||||
{title}
|
!!title &&
|
||||||
</Text>
|
<Text color='inherit' size='small' weight={weight}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Immutable from 'immutable'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import punycode from 'punycode'
|
import punycode from 'punycode'
|
||||||
|
import { DEFAULT_REL } from '../constants'
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
|
|
||||||
const IDNA_PREFIX = 'xn--'
|
const IDNA_PREFIX = 'xn--'
|
||||||
|
@ -144,7 +145,7 @@ export default class Card extends ImmutablePureComponent {
|
||||||
className={[_s.default, _s.displayFlex, _s.text, _s.noUnderline, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fs15PX, _s.fontWeightMedium].join(' ')}
|
className={[_s.default, _s.displayFlex, _s.text, _s.noUnderline, _s.overflowWrapBreakWord, _s.colorPrimary, _s.fs15PX, _s.fontWeightMedium].join(' ')}
|
||||||
href={card.get('url')}
|
href={card.get('url')}
|
||||||
title={card.get('title')}
|
title={card.get('title')}
|
||||||
rel='noopener noreferrer'
|
rel={DEFAULT_REL}
|
||||||
target='_blank'
|
target='_blank'
|
||||||
>
|
>
|
||||||
{card.get('title')}
|
{card.get('title')}
|
||||||
|
@ -229,7 +230,7 @@ export default class Card extends ImmutablePureComponent {
|
||||||
<a
|
<a
|
||||||
href={card.get('url')}
|
href={card.get('url')}
|
||||||
className={[_s.default, _s.cursorPointer, _s.flexRow, _s.overflowHidden, _s.noUnderline, _s.width100PC, _s.bgSubtle_onHover, _s.borderColorSecondary, _s.border1PX, _s.radiusSmall].join(' ')}
|
className={[_s.default, _s.cursorPointer, _s.flexRow, _s.overflowHidden, _s.noUnderline, _s.width100PC, _s.bgSubtle_onHover, _s.borderColorSecondary, _s.border1PX, _s.radiusSmall].join(' ')}
|
||||||
rel='noopener noreferrer'
|
rel={DEFAULT_REL}
|
||||||
ref={this.setRef}
|
ref={this.setRef}
|
||||||
>
|
>
|
||||||
{embed}
|
{embed}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { NavLink } from 'react-router-dom'
|
||||||
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'
|
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
|
import { compactMode } from '../initial_state'
|
||||||
|
import { CX } from '../constants'
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
|
|
||||||
|
@ -39,8 +41,16 @@ class StatusPrepend extends ImmutablePureComponent {
|
||||||
|
|
||||||
const iconId = isFeatured ? 'pin' : isPromoted ? 'star' : 'repost'
|
const iconId = isFeatured ? 'pin' : isPromoted ? 'star' : 'repost'
|
||||||
|
|
||||||
|
const containerClasses = CX({
|
||||||
|
default: 1,
|
||||||
|
width100PC: 1,
|
||||||
|
alignItemsStart: 1,
|
||||||
|
borderBottom1PX: !compactMode,
|
||||||
|
borderColorSecondary: !compactMode,
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.default, _s.width100PC, _s.alignItemsStart, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
<div className={containerClasses}>
|
||||||
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.alignItemsCenter, _s.py5, _s.px15].join(' ')}>
|
<div className={[_s.default, _s.width100PC, _s.flexRow, _s.alignItemsCenter, _s.py5, _s.px15].join(' ')}>
|
||||||
<Icon id={iconId} size='12px' className={[_s.fillSecondary, _s.mr5].join(' ')} />
|
<Icon id={iconId} size='12px' className={[_s.fillSecondary, _s.mr5].join(' ')} />
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import { withRouter } from 'react-router-dom'
|
import { withRouter } from 'react-router-dom'
|
||||||
import classNames from 'classnames/bind'
|
import { CX } from '../constants'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
|
|
||||||
// Bind CSS Modules global variable `_s` to classNames module
|
|
||||||
const cx = classNames.bind(_s)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a tab bar item component
|
* Renders a tab bar item component
|
||||||
* @param {bool} [props.isLarge] - to style the tab bar larger
|
* @param {bool} [props.isLarge] - to style the tab bar larger
|
||||||
|
@ -27,7 +24,7 @@ class TabBarItem extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
isCurrent: -1,
|
isCurrent: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
|
@ -55,10 +52,9 @@ class TabBarItem extends PureComponent {
|
||||||
|
|
||||||
// Combine state, props, location to make absolutely
|
// Combine state, props, location to make absolutely
|
||||||
// sure of active status.
|
// sure of active status.
|
||||||
const active = isActive ||
|
const active = isActive || to === location.pathname || isCurrent
|
||||||
(isCurrent === -1 ? to === location.pathname : false)
|
|
||||||
|
|
||||||
const containerClasses = cx({
|
const containerClasses = CX({
|
||||||
default: 1,
|
default: 1,
|
||||||
height53PX: 1,
|
height53PX: 1,
|
||||||
noUnderline: 1,
|
noUnderline: 1,
|
||||||
|
@ -77,7 +73,7 @@ class TabBarItem extends PureComponent {
|
||||||
mr2: !isLarge,
|
mr2: !isLarge,
|
||||||
})
|
})
|
||||||
|
|
||||||
const textParentClasses = cx({
|
const textParentClasses = CX({
|
||||||
default: 1,
|
default: 1,
|
||||||
height100PC: 1,
|
height100PC: 1,
|
||||||
alignItemsCenter: 1,
|
alignItemsCenter: 1,
|
||||||
|
|
|
@ -14,6 +14,7 @@ export default class UserStat extends PureComponent {
|
||||||
to: PropTypes.string.isRequired,
|
to: PropTypes.string.isRequired,
|
||||||
value: PropTypes.oneOfType([
|
value: PropTypes.oneOfType([
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
|
PropTypes.number,
|
||||||
PropTypes.object,
|
PropTypes.object,
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames/bind'
|
||||||
export const CX = classNames.bind(_s)
|
export const CX = classNames.bind(_s)
|
||||||
|
|
||||||
export const APP_NAME = 'Gab'
|
export const APP_NAME = 'Gab Social'
|
||||||
|
|
||||||
export const DEFAULT_REL = 'noopener noreferrer'
|
export const DEFAULT_REL = 'noopener noreferrer'
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,6 @@ const messages = defineMessages({
|
||||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
||||||
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
|
||||||
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
||||||
quoteConfirm: { id: 'confirmations.quote.confirm', defaultMessage: 'Quote' },
|
|
||||||
quoteMessage: { id: 'confirmations.quote.message', defaultMessage: 'Quoting now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
|
|
||||||
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -114,33 +112,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onRepost (targetRef, status, ) {
|
onRepost (targetRef, status, e) {
|
||||||
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
||||||
|
|
||||||
dispatch(openPopover('REPOST_OPTIONS', {
|
if (e.shiftKey) {
|
||||||
status,
|
this.onModalRepost(status);
|
||||||
targetRef,
|
} else {
|
||||||
position: 'top',
|
dispatch(openPopover('REPOST_OPTIONS', {
|
||||||
}))
|
status,
|
||||||
|
targetRef,
|
||||||
// if (e.shiftKey || !boostModal) {
|
position: 'top',
|
||||||
// this.onModalRepost(status);
|
}))
|
||||||
// } else {
|
}
|
||||||
// dispatch(openModal('BOOST', { status, onRepost: this.onModalRepost }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// dispatch((_, getState) => {
|
|
||||||
// const state = getState();
|
|
||||||
// if (state.getIn(['compose', 'text']).trim().length !== 0) {
|
|
||||||
// dispatch(openModal('CONFIRM', {
|
|
||||||
// message: intl.formatMessage(messages.quoteMessage),
|
|
||||||
// confirm: intl.formatMessage(messages.quoteConfirm),
|
|
||||||
// onConfirm: () => dispatch(quoteCompose(status, router)),
|
|
||||||
// }));
|
|
||||||
// } else {
|
|
||||||
// dispatch(quoteCompose(status, router));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onModalRepost (status) {
|
onModalRepost (status) {
|
||||||
|
@ -187,13 +170,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onEmbed (status) {
|
|
||||||
// dispatch(openModal('EMBED', {
|
|
||||||
// url: status.get('url'),
|
|
||||||
// onError: error => dispatch(showAlertForError(error)),
|
|
||||||
// }));
|
|
||||||
},
|
|
||||||
|
|
||||||
onDelete (status, history) {
|
onDelete (status, history) {
|
||||||
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
if (!me) return dispatch(openModal('UNAUTHORIZED'))
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
import 'intersection-observer';
|
import 'intersection-observer';
|
||||||
import 'requestidlecallback';
|
import 'requestidlecallback';
|
||||||
import objectFitImages from 'object-fit-images';
|
import objectFitImages from 'object-fit-images';
|
||||||
|
|
||||||
objectFitImages();
|
objectFitImages();
|
||||||
|
|
|
@ -4,7 +4,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import { fetchBlocks, expandBlocks } from '../actions/blocks'
|
import { fetchBlocks, expandBlocks } from '../actions/blocks'
|
||||||
import Account from '../components/account'
|
import Account from '../components/account'
|
||||||
import ColumnIndicator from '../components/column_indicator'
|
|
||||||
import ScrollableList from '../components/scrollable_list'
|
import ScrollableList from '../components/scrollable_list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -14,6 +13,7 @@ const messages = defineMessages({
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'blocks', 'items']),
|
accountIds: state.getIn(['user_lists', 'blocks', 'items']),
|
||||||
hasMore: !!state.getIn(['user_lists', 'blocks', 'next']),
|
hasMore: !!state.getIn(['user_lists', 'blocks', 'next']),
|
||||||
|
isLoading: state.getIn(['user_lists', 'blocks', 'isLoading'], true),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
|
@ -26,6 +26,7 @@ class Blocks extends ImmutablePureComponent {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +42,10 @@ class Blocks extends ImmutablePureComponent {
|
||||||
const {
|
const {
|
||||||
intl,
|
intl,
|
||||||
accountIds,
|
accountIds,
|
||||||
hasMore
|
hasMore,
|
||||||
|
isLoading,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!accountIds) {
|
|
||||||
return <ColumnIndicator type='loading' />
|
|
||||||
}
|
|
||||||
|
|
||||||
const emptyMessage = intl.formatMessage(messages.empty)
|
const emptyMessage = intl.formatMessage(messages.empty)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -56,9 +54,10 @@ class Blocks extends ImmutablePureComponent {
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
emptyMessage={emptyMessage}
|
emptyMessage={emptyMessage}
|
||||||
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
accountIds.map(id =>
|
!!accountIds && accountIds.map(id =>
|
||||||
<Account key={`blocked-${id}`} id={id} compact />
|
<Account key={`blocked-${id}`} id={id} compact />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ import ColumnIndicator from '../components/column_indicator'
|
||||||
import List from '../components/list'
|
import List from '../components/list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' },
|
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
|
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||||
emptyMessage: { id: 'empty_column.domain_blocks', defaultMessage: 'There are no hidden domains yet.' },
|
emptyMessage: { id: 'empty_column.domain_blocks', defaultMessage: 'There are no blocked domains yet.' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { openModal } from '../../../actions/modal'
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
|
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
|
||||||
unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Text is not hidden' },
|
unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Text is not hidden' },
|
||||||
title: { id: 'compose_form.spoiler.title', defaultMessage: 'Warning' },
|
title: { id: 'compose_form.gif.title', defaultMessage: 'Insert gif' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
|
|
|
@ -12,7 +12,7 @@ const messages = defineMessages({
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']),
|
acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']),
|
||||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')),
|
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')),
|
||||||
unavailable: state.getIn(['compose', 'poll']) !== null,
|
unavailable: state.getIn(['compose', 'poll']) !== null,
|
||||||
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ import ComposeExtraButton from './compose_extra_button'
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
|
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
|
||||||
unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Text is not hidden' },
|
unmarked: { id: 'compose_form.spoiler.unmarked', defaultMessage: 'Text is not hidden' },
|
||||||
title: { id: 'compose_form.spoiler.title', defaultMessage: 'Warning' },
|
title: { id: 'compose_form.rte.title', defaultMessage: 'Rich Text Editor' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
|
import { me } from '../../initial_state'
|
||||||
import ColumnIndicator from '../../components/column_indicator';
|
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts'
|
||||||
import AccountAuthorize from './components/account_authorize';
|
import AccountAuthorize from './components/account_authorize'
|
||||||
import ScrollableList from '../../components/scrollable_list';
|
import ScrollableList from '../../components/scrollable_list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
});
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
|
accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
|
||||||
|
isLoading: state.getIn(['user_lists', 'follow_requests', 'isLoading'], true),
|
||||||
hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
|
hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
|
||||||
});
|
locked: !!state.getIn(['accounts', me, 'locked']),
|
||||||
|
domain: state.getIn(['meta', 'domain']),
|
||||||
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
@connect(mapStateToProps)
|
@connect(mapStateToProps)
|
||||||
|
@ -25,35 +28,48 @@ class FollowRequests extends ImmutablePureComponent {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
|
locked: PropTypes.bool,
|
||||||
|
domain: PropTypes.string,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
}
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
this.props.dispatch(fetchFollowRequests());
|
this.props.dispatch(fetchFollowRequests())
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLoadMore = debounce(() => {
|
handleLoadMore = debounce(() => {
|
||||||
this.props.dispatch(expandFollowRequests());
|
this.props.dispatch(expandFollowRequests())
|
||||||
}, 300, { leading: true });
|
}, 300, { leading: true })
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, accountIds, hasMore } = this.props;
|
const { intl, accountIds, hasMore, locked, domain, isLoading } = this.props
|
||||||
|
|
||||||
if (!accountIds) {
|
// : todo :
|
||||||
return (<ColumnIndicator type='loading' />);
|
const unlockedPrependMessage = locked ? null : (
|
||||||
}
|
<div className='follow_requests-unlocked_explanation'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='follow_requests.unlocked_explanation'
|
||||||
|
defaultMessage='Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.'
|
||||||
|
values={{ domain: domain }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='follow_requests'
|
scrollKey='follow_requests'
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
isLoading={isLoading}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />}
|
emptyMessage={<FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />}
|
||||||
>
|
>
|
||||||
{accountIds.map(id =>
|
{
|
||||||
<AccountAuthorize key={id} id={id} />
|
!!accountIds && accountIds.map(id =>
|
||||||
)}
|
<AccountAuthorize key={id} id={id} />
|
||||||
|
)
|
||||||
|
}
|
||||||
</ScrollableList>
|
</ScrollableList>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ const mapStateToProps = (state, { account }) => {
|
||||||
accountId,
|
accountId,
|
||||||
accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
|
accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
|
||||||
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
|
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
|
||||||
|
isLoading: state.getIn(['user_lists', 'followers', accountId, 'isLoading'], true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ class Followers extends ImmutablePureComponent {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
@ -67,7 +69,8 @@ class Followers extends ImmutablePureComponent {
|
||||||
account,
|
account,
|
||||||
accountIds,
|
accountIds,
|
||||||
hasMore,
|
hasMore,
|
||||||
intl
|
intl,
|
||||||
|
isLoading,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!account) return null
|
if (!account) return null
|
||||||
|
@ -83,6 +86,7 @@ class Followers extends ImmutablePureComponent {
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='followers'
|
scrollKey='followers'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
isLoading={isLoading}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={intl.formatMessage(messages.empty)}
|
emptyMessage={intl.formatMessage(messages.empty)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -18,6 +18,7 @@ const mapStateToProps = (state, { account }) => {
|
||||||
accountId,
|
accountId,
|
||||||
accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
|
accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
|
||||||
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
|
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
|
||||||
|
isLoading: state.getIn(['user_lists', 'following', accountId, 'isLoading'], true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ class Following extends ImmutablePureComponent {
|
||||||
account: ImmutablePropTypes.map,
|
account: ImmutablePropTypes.map,
|
||||||
accountId: PropTypes.string,
|
accountId: PropTypes.string,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -68,6 +70,7 @@ class Following extends ImmutablePureComponent {
|
||||||
accountIds,
|
accountIds,
|
||||||
hasMore,
|
hasMore,
|
||||||
intl,
|
intl,
|
||||||
|
isLoading,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!account) return null
|
if (!account) return null
|
||||||
|
@ -83,6 +86,7 @@ class Following extends ImmutablePureComponent {
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='following'
|
scrollKey='following'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
isLoading={isLoading}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={intl.formatMessage(messages.empty)}
|
emptyMessage={intl.formatMessage(messages.empty)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -38,8 +38,6 @@ class GroupsCollection extends ImmutablePureComponent {
|
||||||
|
|
||||||
const halfCount = parseInt(groupIds.size / 2)
|
const halfCount = parseInt(groupIds.size / 2)
|
||||||
|
|
||||||
console.log("halfCount", halfCount)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
|
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
|
||||||
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
<div className={[_s.default, _s.flexNormal].join(' ')}>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import StatusList from '../components/status_list'
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.home', defaultMessage: 'Home' },
|
title: { id: 'column.home', defaultMessage: 'Home' },
|
||||||
empty: { id: 'empty_column.home', defaultMessage: 'Your home timeline is empty. Start following other users to recieve their content here.' },
|
empty: { id: 'empty_timeline.home', defaultMessage: 'Your home timeline is empty. Start following other users to recieve their content here.' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
|
|
|
@ -4,12 +4,12 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import { fetchMutes, expandMutes } from '../actions/mutes'
|
import { fetchMutes, expandMutes } from '../actions/mutes'
|
||||||
import Account from '../components/account'
|
import Account from '../components/account'
|
||||||
import ColumnIndicator from '../components/column_indicator'
|
|
||||||
import ScrollableList from '../components/scrollable_list'
|
import ScrollableList from '../components/scrollable_list'
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'mutes', 'items']),
|
accountIds: state.getIn(['user_lists', 'mutes', 'items']),
|
||||||
hasMore: !!state.getIn(['user_lists', 'mutes', 'next']),
|
hasMore: !!state.getIn(['user_lists', 'mutes', 'next']),
|
||||||
|
isLoading: state.getIn(['user_lists', 'mutes', 'isLoading'], true),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default
|
export default
|
||||||
|
@ -22,6 +22,7 @@ class Mutes extends ImmutablePureComponent {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
accountIds: ImmutablePropTypes.list,
|
accountIds: ImmutablePropTypes.list,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
@ -33,21 +34,18 @@ class Mutes extends ImmutablePureComponent {
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true })
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { hasMore, accountIds } = this.props
|
const { hasMore, accountIds, isLoading } = this.props
|
||||||
|
|
||||||
if (!accountIds) {
|
|
||||||
return <ColumnIndicator type='loading' />
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='mutes'
|
scrollKey='mutes'
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
isLoading={isLoading}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />}
|
emptyMessage={<FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
accountIds.map(id =>
|
accountIds && accountIds.map(id =>
|
||||||
<Account key={`mutes-${id}`} id={id} compact />
|
<Account key={`mutes-${id}`} id={id} compact />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ import StatusContainer from '../containers/status_container'
|
||||||
|
|
||||||
export default class Status extends PureComponent {
|
export default class Status extends PureComponent {
|
||||||
render() {
|
render() {
|
||||||
console.log("this.props:", this.props)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatusContainer {...this.props} />
|
<StatusContainer {...this.props} />
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,5 +26,6 @@ export const promotions = initialState && initialState.promotions;
|
||||||
export const unreadCount = getMeta('unread_count');
|
export const unreadCount = getMeta('unread_count');
|
||||||
export const monthlyExpensesComplete = getMeta('monthly_expenses_complete');
|
export const monthlyExpensesComplete = getMeta('monthly_expenses_complete');
|
||||||
export const favouritesCount = getMeta('favourites_count');
|
export const favouritesCount = getMeta('favourites_count');
|
||||||
|
export const compactMode = false;
|
||||||
|
|
||||||
export default initialState;
|
export default initialState;
|
||||||
|
|
|
@ -17,7 +17,6 @@ export default class Layout extends PureComponent {
|
||||||
showBackBtn: PropTypes.bool,
|
showBackBtn: PropTypes.bool,
|
||||||
noSidebar: PropTypes.bool,
|
noSidebar: PropTypes.bool,
|
||||||
noRightSidebar: PropTypes.bool,
|
noRightSidebar: PropTypes.bool,
|
||||||
noHeader: PropTypes.bool,
|
|
||||||
noComposeButton: PropTypes.bool,
|
noComposeButton: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ export default class Layout extends PureComponent {
|
||||||
tabs,
|
tabs,
|
||||||
noSidebar,
|
noSidebar,
|
||||||
noRightSidebar,
|
noRightSidebar,
|
||||||
noHeader,
|
|
||||||
noComposeButton,
|
noComposeButton,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Guetar ente la xente que sigues",
|
"lists.search": "Guetar ente la xente que sigues",
|
||||||
"lists.subheading": "Les tos llistes",
|
"lists.subheading": "Les tos llistes",
|
||||||
"loading_indicator.label": "Cargando...",
|
"loading_indicator.label": "Cargando...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Nun s'alcontró",
|
"missing_indicator.label": "Nun s'alcontró",
|
||||||
"missing_indicator.sublabel": "Esti recursu nun pudo alcontrase",
|
"missing_indicator.sublabel": "Esti recursu nun pudo alcontrase",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Namái siguidores",
|
"privacy.private.short": "Namái siguidores",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Блокирай",
|
"account.block": "Блокирай",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct Message @{name}",
|
"account.direct": "Direct Message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Не блокирай",
|
"account.unblock": "Не блокирай",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Не следвай",
|
"account.unfollow": "Не следвай",
|
||||||
"account.unmute": "Unmute @{name}",
|
"account.unmute": "Unmute @{name}",
|
||||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||||
"alert.unexpected.message": "An unexpected error occurred.",
|
"alert.unexpected.message": "An unexpected error occurred.",
|
||||||
"alert.unexpected.title": "Oops!",
|
"alert.unexpected.title": "Oops!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||||
"bundle_column_error.retry": "Try again",
|
"bundle_column_error.retry": "Try again",
|
||||||
"bundle_column_error.title": "Network error",
|
"bundle_column_error.title": "Network error",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blocked users",
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Community timeline",
|
"column.community": "Community timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorites",
|
"column.favorites": "Favorites",
|
||||||
"column.follow_requests": "Follow requests",
|
"column.follow_requests": "Follow requests",
|
||||||
"column.home": "Начало",
|
"column.home": "Начало",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Зареждане...",
|
"loading_indicator.label": "Зареждане...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Редактирай профил",
|
"navigation_bar.edit_profile": "Редактирай профил",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Изтриване",
|
"status.delete": "Изтриване",
|
||||||
|
|
|
@ -125,7 +125,7 @@
|
||||||
{
|
{
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
"defaultMessage": "Unhide {domain}",
|
"defaultMessage": "Unblock domain {domain}",
|
||||||
"id": "account.unblock_domain"
|
"id": "account.unblock_domain"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
{
|
{
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
"defaultMessage": "Toggle visibility",
|
"defaultMessage": "Hide media",
|
||||||
"id": "media_gallery.toggle_visible"
|
"id": "media_gallery.toggle_visible"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -314,7 +314,7 @@
|
||||||
"id": "status.repost_private"
|
"id": "status.repost_private"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Un-repost",
|
"defaultMessage": "Remove Repost",
|
||||||
"id": "status.cancel_repost_private"
|
"id": "status.cancel_repost_private"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -435,7 +435,7 @@
|
||||||
{
|
{
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hide entire domain",
|
"defaultMessage": "Block entire domain",
|
||||||
"id": "confirmations.domain_block.confirm"
|
"id": "confirmations.domain_block.confirm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -523,7 +523,7 @@
|
||||||
"id": "confirmations.block.confirm"
|
"id": "confirmations.block.confirm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hide entire domain",
|
"defaultMessage": "Block entire domain",
|
||||||
"id": "confirmations.domain_block.confirm"
|
"id": "confirmations.domain_block.confirm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -621,11 +621,11 @@
|
||||||
"id": "account.media"
|
"id": "account.media"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hide everything from {domain}",
|
"defaultMessage": "Block domain {domain}",
|
||||||
"id": "account.block_domain"
|
"id": "account.block_domain"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Unhide {domain}",
|
"defaultMessage": "Unblock domain {domain}",
|
||||||
"id": "account.unblock_domain"
|
"id": "account.unblock_domain"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -661,7 +661,7 @@
|
||||||
"id": "navigation_bar.blocks"
|
"id": "navigation_bar.blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hidden domains",
|
"defaultMessage": "Blocked domains",
|
||||||
"id": "navigation_bar.domain_blocks"
|
"id": "navigation_bar.domain_blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -785,7 +785,7 @@
|
||||||
"id": "navigation_bar.blocks"
|
"id": "navigation_bar.blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hidden domains",
|
"defaultMessage": "Blocked domains",
|
||||||
"id": "navigation_bar.domain_blocks"
|
"id": "navigation_bar.domain_blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -943,7 +943,7 @@
|
||||||
"id": "privacy.public.short"
|
"id": "privacy.public.short"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Post to public timelines",
|
"defaultMessage": "Visible for anyone on or off Gab",
|
||||||
"id": "privacy.public.long"
|
"id": "privacy.public.long"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -959,7 +959,7 @@
|
||||||
"id": "privacy.private.short"
|
"id": "privacy.private.short"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Post to followers only",
|
"defaultMessage": "Visible for your followers only",
|
||||||
"id": "privacy.private.long"
|
"id": "privacy.private.long"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1191,15 +1191,15 @@
|
||||||
{
|
{
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hidden domains",
|
"defaultMessage": "Blocked domains",
|
||||||
"id": "column.domain_blocks"
|
"id": "column.domain_blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Unhide {domain}",
|
"defaultMessage": "Unblock domain {domain}",
|
||||||
"id": "account.unblock_domain"
|
"id": "account.unblock_domain"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "There are no hidden domains yet.",
|
"defaultMessage": "There are no blocked domains yet.",
|
||||||
"id": "empty_column.domain_blocks"
|
"id": "empty_column.domain_blocks"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1322,7 +1322,7 @@
|
||||||
"id": "navigation_bar.blocks"
|
"id": "navigation_bar.blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Hidden domains",
|
"defaultMessage": "Blocked domains",
|
||||||
"id": "navigation_bar.domain_blocks"
|
"id": "navigation_bar.domain_blocks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1962,7 +1962,7 @@
|
||||||
"id": "status.repost_private"
|
"id": "status.repost_private"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "Un-repost",
|
"defaultMessage": "Remove Repost",
|
||||||
"id": "status.cancel_repost_private"
|
"id": "status.cancel_repost_private"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2121,7 +2121,7 @@
|
||||||
{
|
{
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
"defaultMessage": "Un-repost",
|
"defaultMessage": "Remove Repost",
|
||||||
"id": "status.cancel_repost_private"
|
"id": "status.cancel_repost_private"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2129,7 +2129,7 @@
|
||||||
"id": "status.repost"
|
"id": "status.repost"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultMessage": "You can press {combo} to skip this next time",
|
"defaultMessage": "You can press Shift + Repost to skip this next time",
|
||||||
"id": "boost_modal.combo"
|
"id": "boost_modal.combo"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Block @{name}",
|
"account.block": "Block @{name}",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct message @{name}",
|
"account.direct": "Direct message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Unblock @{name}",
|
"account.unblock": "Unblock @{name}",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Unfollow",
|
"account.unfollow": "Unfollow",
|
||||||
"account.unmute": "Unmute @{name}",
|
"account.unmute": "Unmute @{name}",
|
||||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||||
"alert.unexpected.message": "An unexpected error occurred.",
|
"alert.unexpected.message": "An unexpected error occurred.",
|
||||||
"alert.unexpected.title": "Oops!",
|
"alert.unexpected.title": "Oops!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||||
"bundle_column_error.retry": "Try again",
|
"bundle_column_error.retry": "Try again",
|
||||||
"bundle_column_error.title": "Network error",
|
"bundle_column_error.title": "Network error",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blocked users",
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Community timeline",
|
"column.community": "Community timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorites",
|
"column.favorites": "Favorites",
|
||||||
"column.follow_requests": "Follow requests",
|
"column.follow_requests": "Follow requests",
|
||||||
"column.home": "Home",
|
"column.home": "Home",
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
"navigation_bar.compose": "Compose new gab",
|
"navigation_bar.compose": "Compose new gab",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -285,11 +285,11 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not post to public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
"regeneration_indicator.label": "Loading…",
|
"regeneration_indicator.label": "Loading…",
|
||||||
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
||||||
|
@ -319,7 +319,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "חסימות",
|
"column.blocks": "חסימות",
|
||||||
"column.community": "ציר זמן מקומי",
|
"column.community": "ציר זמן מקומי",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "חיבובים",
|
"column.favorites": "חיבובים",
|
||||||
"column.follow_requests": "בקשות מעקב",
|
"column.follow_requests": "בקשות מעקב",
|
||||||
"column.home": "בבית",
|
"column.home": "בבית",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
|
"empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "עריכת פרופיל",
|
"navigation_bar.edit_profile": "עריכת פרופיל",
|
||||||
"navigation_bar.favorites": "חיבובים",
|
"navigation_bar.favorites": "חיבובים",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Block @{name}",
|
"account.block": "Block @{name}",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct message @{name}",
|
"account.direct": "Direct message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Unblock @{name}",
|
"account.unblock": "Unblock @{name}",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Unfollow",
|
"account.unfollow": "Unfollow",
|
||||||
"account.unmute": "Unmute @{name}",
|
"account.unmute": "Unmute @{name}",
|
||||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||||
"alert.unexpected.message": "An unexpected error occurred.",
|
"alert.unexpected.message": "An unexpected error occurred.",
|
||||||
"alert.unexpected.title": "Oops!",
|
"alert.unexpected.title": "Oops!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||||
"bundle_column_error.retry": "Try again",
|
"bundle_column_error.retry": "Try again",
|
||||||
"bundle_column_error.title": "Network error",
|
"bundle_column_error.title": "Network error",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blocked users",
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Community timeline",
|
"column.community": "Community timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorites",
|
"column.favorites": "Favorites",
|
||||||
"column.follow_requests": "Follow requests",
|
"column.follow_requests": "Follow requests",
|
||||||
"column.home": "Home",
|
"column.home": "Home",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blokirani korisnici",
|
"column.blocks": "Blokirani korisnici",
|
||||||
"column.community": "Lokalni timeline",
|
"column.community": "Lokalni timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favoriti",
|
"column.favorites": "Favoriti",
|
||||||
"column.follow_requests": "Zahtjevi za slijeđenje",
|
"column.follow_requests": "Zahtjevi za slijeđenje",
|
||||||
"column.home": "Dom",
|
"column.home": "Dom",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!",
|
"empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Uredi profil",
|
"navigation_bar.edit_profile": "Uredi profil",
|
||||||
"navigation_bar.favorites": "Favoriti",
|
"navigation_bar.favorites": "Favoriti",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Ovaj post ne može biti repostan",
|
"status.cannot_repost": "Ovaj post ne može biti repostan",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Obriši",
|
"status.delete": "Obriši",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Letiltott felhasználók",
|
"column.blocks": "Letiltott felhasználók",
|
||||||
"column.community": "Helyi idővonal",
|
"column.community": "Helyi idővonal",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Kedvencek",
|
"column.favorites": "Kedvencek",
|
||||||
"column.follow_requests": "Követési kérések",
|
"column.follow_requests": "Követési kérések",
|
||||||
"column.home": "Kezdőlap",
|
"column.home": "Kezdőlap",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "A helyi idővonal üres. Írj egy publikus stástuszt, hogy elindítsd a labdát!",
|
"empty_column.community": "A helyi idővonal üres. Írj egy publikus stástuszt, hogy elindítsd a labdát!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Profil szerkesztése",
|
"navigation_bar.edit_profile": "Profil szerkesztése",
|
||||||
"navigation_bar.favorites": "Kedvencek",
|
"navigation_bar.favorites": "Kedvencek",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Ezen státusz nem rebloggolható",
|
"status.cannot_repost": "Ezen státusz nem rebloggolható",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Törlés",
|
"status.delete": "Törlés",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Արգելափակված օգտատերեր",
|
"column.blocks": "Արգելափակված օգտատերեր",
|
||||||
"column.community": "Տեղական հոսք",
|
"column.community": "Տեղական հոսք",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Հավանածներ",
|
"column.favorites": "Հավանածներ",
|
||||||
"column.follow_requests": "Հետեւելու հայցեր",
|
"column.follow_requests": "Հետեւելու հայցեր",
|
||||||
"column.home": "Հիմնական",
|
"column.home": "Հիմնական",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
|
"empty_column.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Խմբագրել անձնական էջը",
|
"navigation_bar.edit_profile": "Խմբագրել անձնական էջը",
|
||||||
"navigation_bar.favorites": "Հավանածներ",
|
"navigation_bar.favorites": "Հավանածներ",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Արգելափակել @{name}֊ին",
|
"status.block": "Արգելափակել @{name}֊ին",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Այս թութը չի կարող տարածվել",
|
"status.cannot_repost": "Այս թութը չի կարող տարածվել",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Ջնջել",
|
"status.delete": "Ջնջել",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Pengguna diblokir",
|
"column.blocks": "Pengguna diblokir",
|
||||||
"column.community": "Linimasa Lokal",
|
"column.community": "Linimasa Lokal",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorit",
|
"column.favorites": "Favorit",
|
||||||
"column.follow_requests": "Permintaan mengikuti",
|
"column.follow_requests": "Permintaan mengikuti",
|
||||||
"column.home": "Beranda",
|
"column.home": "Beranda",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!",
|
"empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Ubah profil",
|
"navigation_bar.edit_profile": "Ubah profil",
|
||||||
"navigation_bar.favorites": "Favorit",
|
"navigation_bar.favorites": "Favorit",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Hapus",
|
"status.delete": "Hapus",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Blokusar @{name}",
|
"account.block": "Blokusar @{name}",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct Message @{name}",
|
"account.direct": "Direct Message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Desblokusar @{name}",
|
"account.unblock": "Desblokusar @{name}",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Ne plus sequar",
|
"account.unfollow": "Ne plus sequar",
|
||||||
"account.unmute": "Ne plus celar @{name}",
|
"account.unmute": "Ne plus celar @{name}",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blokusita uzeri",
|
"column.blocks": "Blokusita uzeri",
|
||||||
"column.community": "Lokala tempolineo",
|
"column.community": "Lokala tempolineo",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorati",
|
"column.favorites": "Favorati",
|
||||||
"column.follow_requests": "Demandi di sequado",
|
"column.follow_requests": "Demandi di sequado",
|
||||||
"column.home": "Hemo",
|
"column.home": "Hemo",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "La lokala tempolineo esas vakua. Skribez ulo publike por iniciar la agiveso!",
|
"empty_column.community": "La lokala tempolineo esas vakua. Skribez ulo publike por iniciar la agiveso!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Modifikar profilo",
|
"navigation_bar.edit_profile": "Modifikar profilo",
|
||||||
"navigation_bar.favorites": "Favorati",
|
"navigation_bar.favorites": "Favorati",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Efacar",
|
"status.delete": "Efacar",
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "ლოკალური თაიმლაინი ცარიელია. დაწერეთ რაიმე ღიად ან ქენით რაიმე სხვა!",
|
"empty_column.community": "ლოკალური თაიმლაინი ცარიელია. დაწერეთ რაიმე ღიად ან ქენით რაიმე სხვა!",
|
||||||
"empty_column.direct": "ჯერ პირდაპირი წერილები არ გაქვთ. როდესაც მიიღებთ ან გააგზავნით, გამოჩნდება აქ.",
|
"empty_column.direct": "ჯერ პირდაპირი წერილები არ გაქვთ. როდესაც მიიღებთ ან გააგზავნით, გამოჩნდება აქ.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
|
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Block @{name}",
|
"account.block": "Block @{name}",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct message @{name}",
|
"account.direct": "Direct message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Unblock @{name}",
|
"account.unblock": "Unblock @{name}",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Unfollow",
|
"account.unfollow": "Unfollow",
|
||||||
"account.unmute": "Unmute @{name}",
|
"account.unmute": "Unmute @{name}",
|
||||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||||
"alert.unexpected.message": "An unexpected error occurred.",
|
"alert.unexpected.message": "An unexpected error occurred.",
|
||||||
"alert.unexpected.title": "Oops!",
|
"alert.unexpected.title": "Oops!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||||
"bundle_column_error.retry": "Try again",
|
"bundle_column_error.retry": "Try again",
|
||||||
"bundle_column_error.title": "Network error",
|
"bundle_column_error.title": "Network error",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blocked users",
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Community timeline",
|
"column.community": "Community timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorites",
|
"column.favorites": "Favorites",
|
||||||
"column.follow_requests": "Follow requests",
|
"column.follow_requests": "Follow requests",
|
||||||
"column.home": "Home",
|
"column.home": "Home",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blokkerte brukere",
|
"column.blocks": "Blokkerte brukere",
|
||||||
"column.community": "Lokal tidslinje",
|
"column.community": "Lokal tidslinje",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Likt",
|
"column.favorites": "Likt",
|
||||||
"column.follow_requests": "Følgeforespørsler",
|
"column.follow_requests": "Følgeforespørsler",
|
||||||
"column.home": "Hjem",
|
"column.home": "Hjem",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Den lokale tidslinjen er tom. Skriv noe offentlig for å få snøballen til å rulle!",
|
"empty_column.community": "Den lokale tidslinjen er tom. Skriv noe offentlig for å få snøballen til å rulle!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Rediger profil",
|
"navigation_bar.edit_profile": "Rediger profil",
|
||||||
"navigation_bar.favorites": "Favoritter",
|
"navigation_bar.favorites": "Favoritter",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Denne posten kan ikke fremheves",
|
"status.cannot_repost": "Denne posten kan ikke fremheves",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Slett",
|
"status.delete": "Slett",
|
||||||
|
|
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blokirani korisnici",
|
"column.blocks": "Blokirani korisnici",
|
||||||
"column.community": "Lokalna lajna",
|
"column.community": "Lokalna lajna",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Omiljeni",
|
"column.favorites": "Omiljeni",
|
||||||
"column.follow_requests": "Zahtevi za praćenje",
|
"column.follow_requests": "Zahtevi za praćenje",
|
||||||
"column.home": "Početna",
|
"column.home": "Početna",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Lokalna lajna je prazna. Napišite nešto javno da lajna produva!",
|
"empty_column.community": "Lokalna lajna je prazna. Napišite nešto javno da lajna produva!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Izmeni profil",
|
"navigation_bar.edit_profile": "Izmeni profil",
|
||||||
"navigation_bar.favorites": "Omiljeni",
|
"navigation_bar.favorites": "Omiljeni",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Ovaj status ne može da se podrži",
|
"status.cannot_repost": "Ovaj status ne može da se podrži",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Obriši",
|
"status.delete": "Obriši",
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Den lokala tidslinjen är tom. Skriv något offentligt för att få bollen att rulla!",
|
"empty_column.community": "Den lokala tidslinjen är tom. Skriv något offentligt för att få bollen att rulla!",
|
||||||
"empty_column.direct": "Du har inga direktmeddelanden än. När du skickar eller tar emot kommer den att dyka upp här.",
|
"empty_column.direct": "Du har inga direktmeddelanden än. När du skickar eller tar emot kommer den att dyka upp här.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite gabs yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this gab yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.block": "Block @{name}",
|
"account.block": "Block @{name}",
|
||||||
"account.block_domain": "Hide everything from {domain}",
|
"account.block_domain": "Block domain {domain}",
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.direct": "Direct message @{name}",
|
"account.direct": "Direct message @{name}",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
"account.share": "Share @{name}'s profile",
|
"account.share": "Share @{name}'s profile",
|
||||||
"account.show_reposts": "Show reposts from @{name}",
|
"account.show_reposts": "Show reposts from @{name}",
|
||||||
"account.unblock": "Unblock @{name}",
|
"account.unblock": "Unblock @{name}",
|
||||||
"account.unblock_domain": "Unhide {domain}",
|
"account.unblock_domain": "Unblock domain {domain}",
|
||||||
"account.unendorse": "Don't feature on profile",
|
"account.unendorse": "Don't feature on profile",
|
||||||
"account.unfollow": "Unfollow",
|
"account.unfollow": "Unfollow",
|
||||||
"account.unmute": "Unmute @{name}",
|
"account.unmute": "Unmute @{name}",
|
||||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||||
"alert.unexpected.message": "An unexpected error occurred.",
|
"alert.unexpected.message": "An unexpected error occurred.",
|
||||||
"alert.unexpected.title": "Oops!",
|
"alert.unexpected.title": "Oops!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||||
"bundle_column_error.retry": "Try again",
|
"bundle_column_error.retry": "Try again",
|
||||||
"bundle_column_error.title": "Network error",
|
"bundle_column_error.title": "Network error",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
"column.blocks": "Blocked users",
|
"column.blocks": "Blocked users",
|
||||||
"column.community": "Community timeline",
|
"column.community": "Community timeline",
|
||||||
"column.direct": "Direct messages",
|
"column.direct": "Direct messages",
|
||||||
"column.domain_blocks": "Hidden domains",
|
"column.domain_blocks": "Blocked domains",
|
||||||
"column.favorites": "Favorites",
|
"column.favorites": "Favorites",
|
||||||
"column.follow_requests": "Follow requests",
|
"column.follow_requests": "Follow requests",
|
||||||
"column.home": "Home",
|
"column.home": "Home",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "Delete",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
|
||||||
"confirmations.mute.confirm": "Mute",
|
"confirmations.mute.confirm": "Mute",
|
||||||
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
"confirmations.mute.message": "Are you sure you want to mute {name}?",
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
|
||||||
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading...",
|
||||||
"media_gallery.toggle_visible": "Toggle visibility",
|
"media_gallery.toggle_visible": "Hide media",
|
||||||
"missing_indicator.label": "Not found",
|
"missing_indicator.label": "Not found",
|
||||||
"missing_indicator.sublabel": "This resource could not be found",
|
"missing_indicator.sublabel": "This resource could not be found",
|
||||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||||
|
@ -232,7 +232,7 @@
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.compose": "Compose new toot",
|
||||||
"navigation_bar.direct": "Direct messages",
|
"navigation_bar.direct": "Direct messages",
|
||||||
"navigation_bar.discover": "Discover",
|
"navigation_bar.discover": "Discover",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Blocked domains",
|
||||||
"navigation_bar.edit_profile": "Edit profile",
|
"navigation_bar.edit_profile": "Edit profile",
|
||||||
"navigation_bar.favorites": "Favorites",
|
"navigation_bar.favorites": "Favorites",
|
||||||
"navigation_bar.filters": "Muted words",
|
"navigation_bar.filters": "Muted words",
|
||||||
|
@ -282,9 +282,9 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.long": "Post to mentioned users only",
|
"privacy.direct.long": "Post to mentioned users only",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.long": "Post to followers only",
|
"privacy.private.long": "Visible for your followers only",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
"privacy.public.long": "Post to public timelines",
|
"privacy.public.long": "Visible for anyone on or off Gab",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
"privacy.unlisted.long": "Do not show in public timelines",
|
"privacy.unlisted.long": "Do not show in public timelines",
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "This post cannot be reposted",
|
"status.cannot_repost": "This post cannot be reposted",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Delete",
|
"status.delete": "Delete",
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
"account.unmute_notifications": "เลิกปิดเสียงการแจ้งเตือนจาก @{name}",
|
"account.unmute_notifications": "เลิกปิดเสียงการแจ้งเตือนจาก @{name}",
|
||||||
"alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด",
|
"alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด",
|
||||||
"alert.unexpected.title": "อุปส์!",
|
"alert.unexpected.title": "อุปส์!",
|
||||||
"boost_modal.combo": "You can press {combo} to skip this next time",
|
"boost_modal.combo": "You can press Shift + Repost to skip this next time",
|
||||||
"bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้",
|
"bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้",
|
||||||
"bundle_column_error.retry": "ลองอีกครั้ง",
|
"bundle_column_error.retry": "ลองอีกครั้ง",
|
||||||
"bundle_column_error.title": "ข้อผิดพลาดเครือข่าย",
|
"bundle_column_error.title": "ข้อผิดพลาดเครือข่าย",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"confirmations.delete.message": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะนี้?",
|
"confirmations.delete.message": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะนี้?",
|
||||||
"confirmations.delete_list.confirm": "ลบ",
|
"confirmations.delete_list.confirm": "ลบ",
|
||||||
"confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?",
|
"confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Block entire domain",
|
||||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
||||||
"confirmations.mute.confirm": "ปิดเสียง",
|
"confirmations.mute.confirm": "ปิดเสียง",
|
||||||
"confirmations.mute.message": "คุณแน่ใจหรือไม่ว่าต้องการปิดเสียง {name}?",
|
"confirmations.mute.message": "คุณแน่ใจหรือไม่ว่าต้องการปิดเสียง {name}?",
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",
|
"empty_column.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",
|
||||||
"empty_column.direct": "У вас ще немає прямих повідомлень. Коли ви відправите чи отримаєте якесь, воно з'явиться тут.",
|
"empty_column.direct": "У вас ще немає прямих повідомлень. Коли ви відправите чи отримаєте якесь, воно з'явиться тут.",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
"status.admin_account": "Open moderation interface for @{name}",
|
"status.admin_account": "Open moderation interface for @{name}",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Block @{name}",
|
"status.block": "Block @{name}",
|
||||||
"status.cancel_repost_private": "Un-repost",
|
"status.cancel_repost_private": "Remove Repost",
|
||||||
"status.cannot_repost": "Цей допис не може бути передмухнутий",
|
"status.cannot_repost": "Цей допис не може бути передмухнутий",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Видалити",
|
"status.delete": "Видалити",
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "本站时间轴暂时没有内容,快嘟几个来抢头香啊!",
|
"empty_column.community": "本站时间轴暂时没有内容,快嘟几个来抢头香啊!",
|
||||||
"empty_column.direct": "你还没有使用过私信。当你发出或者收到私信时,它会在这里显示。",
|
"empty_column.direct": "你还没有使用过私信。当你发出或者收到私信时,它会在这里显示。",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
"empty_column.blocks": "You haven't blocked any users yet.",
|
"empty_column.blocks": "You haven't blocked any users yet.",
|
||||||
"empty_column.community": "本站時間軸暫時未有內容,快寫一點東西來搶頭香啊!",
|
"empty_column.community": "本站時間軸暫時未有內容,快寫一點東西來搶頭香啊!",
|
||||||
"empty_column.direct": "你沒有個人訊息。當你發出或接收個人訊息,就會在這裡出現。",
|
"empty_column.direct": "你沒有個人訊息。當你發出或接收個人訊息,就會在這裡出現。",
|
||||||
"empty_column.domain_blocks": "There are no hidden domains yet.",
|
"empty_column.domain_blocks": "There are no blocked domains yet.",
|
||||||
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
"empty_column.favorited_statuses": "You don't have any favorite toots yet. When you favorite one, it will show up here.",
|
||||||
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
"empty_column.favorites": "No one has favorited this toot yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
|
|
|
@ -62,7 +62,6 @@ class ProfilePage extends ImmutablePureComponent {
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const name = !!account ? account.get('display_name_html') : ''
|
const name = !!account ? account.get('display_name_html') : ''
|
||||||
console.log("name:", name, account)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProfileLayout
|
<ProfileLayout
|
||||||
|
|
|
@ -66,6 +66,7 @@ const initialState = ImmutableMap({
|
||||||
is_uploading: false,
|
is_uploading: false,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
media_attachments: ImmutableList(),
|
media_attachments: ImmutableList(),
|
||||||
|
pending_media_attachments: 0,
|
||||||
poll: null,
|
poll: null,
|
||||||
suggestion_token: null,
|
suggestion_token: null,
|
||||||
suggestions: ImmutableList(),
|
suggestions: ImmutableList(),
|
||||||
|
@ -122,6 +123,7 @@ function appendMedia(state, media) {
|
||||||
map.set('is_uploading', false);
|
map.set('is_uploading', false);
|
||||||
map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
|
map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
|
||||||
map.set('idempotencyKey', uuid());
|
map.set('idempotencyKey', uuid());
|
||||||
|
map.update('pending_media_attachments', n => n - 1)
|
||||||
|
|
||||||
if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
|
if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
|
||||||
map.set('sensitive', true);
|
map.set('sensitive', true);
|
||||||
|
@ -314,11 +316,11 @@ export default function compose(state = initialState, action) {
|
||||||
case COMPOSE_UPLOAD_CHANGE_FAIL:
|
case COMPOSE_UPLOAD_CHANGE_FAIL:
|
||||||
return state.set('is_changing_upload', false);
|
return state.set('is_changing_upload', false);
|
||||||
case COMPOSE_UPLOAD_REQUEST:
|
case COMPOSE_UPLOAD_REQUEST:
|
||||||
return state.set('is_uploading', true);
|
return state.set('is_uploading', true).update('pending_media_attachments', n => n + 1)
|
||||||
case COMPOSE_UPLOAD_SUCCESS:
|
case COMPOSE_UPLOAD_SUCCESS:
|
||||||
return appendMedia(state, fromJS(action.media));
|
return appendMedia(state, fromJS(action.media));
|
||||||
case COMPOSE_UPLOAD_FAIL:
|
case COMPOSE_UPLOAD_FAIL:
|
||||||
return state.set('is_uploading', false);
|
return state.set('is_uploading', false).update('pending_media_attachments', n => action.decrement ? n - 1 : n);
|
||||||
case COMPOSE_UPLOAD_UNDO:
|
case COMPOSE_UPLOAD_UNDO:
|
||||||
return removeMedia(state, action.media_id);
|
return removeMedia(state, action.media_id);
|
||||||
case COMPOSE_UPLOAD_PROGRESS:
|
case COMPOSE_UPLOAD_PROGRESS:
|
||||||
|
|
|
@ -69,8 +69,6 @@ const expandNormalizedNotifications = (state, notifications, next) => {
|
||||||
|
|
||||||
let items = ImmutableList()
|
let items = ImmutableList()
|
||||||
|
|
||||||
console.log("notifications:", notifications)
|
|
||||||
|
|
||||||
notifications.forEach((n) => {
|
notifications.forEach((n) => {
|
||||||
const notification = notificationToMap(n)
|
const notification = notificationToMap(n)
|
||||||
const statusId = notification.get('status')
|
const statusId = notification.get('status')
|
||||||
|
@ -136,8 +134,6 @@ const expandNormalizedNotifications = (state, notifications, next) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("final items: ", items)
|
|
||||||
|
|
||||||
return state.withMutations(mutable => {
|
return state.withMutations(mutable => {
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
mutable.update('items', list => {
|
mutable.update('items', list => {
|
||||||
|
@ -149,12 +145,8 @@ const expandNormalizedNotifications = (state, notifications, next) => {
|
||||||
item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
|
item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
// console.log("firstIndex, lastIndex: ", firstIndex, lastIndex)
|
|
||||||
|
|
||||||
const pop = list.take(firstIndex).concat(items, list.skip(lastIndex))
|
const pop = list.take(firstIndex).concat(items, list.skip(lastIndex))
|
||||||
|
|
||||||
// console.log("pop:", pop)
|
|
||||||
|
|
||||||
return pop
|
return pop
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -224,7 +216,6 @@ export default function notifications(state = initialState, action) {
|
||||||
case NOTIFICATIONS_FILTER_SET:
|
case NOTIFICATIONS_FILTER_SET:
|
||||||
return state.withMutations(mutable => {
|
return state.withMutations(mutable => {
|
||||||
mutable.set('items', ImmutableList()).set('hasMore', true)
|
mutable.set('items', ImmutableList()).set('hasMore', true)
|
||||||
console.log("NOTIFICATIONS_FILTER_SET:", action.path, action.value)
|
|
||||||
mutable.setIn(['filter', action.path], action.value)
|
mutable.setIn(['filter', action.path], action.value)
|
||||||
})
|
})
|
||||||
case NOTIFICATIONS_SCROLL_TOP:
|
case NOTIFICATIONS_SCROLL_TOP:
|
||||||
|
|
|
@ -1,32 +1,52 @@
|
||||||
|
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'
|
||||||
import {
|
import {
|
||||||
|
FOLLOWERS_FETCH_REQUEST,
|
||||||
FOLLOWERS_FETCH_SUCCESS,
|
FOLLOWERS_FETCH_SUCCESS,
|
||||||
FOLLOWERS_EXPAND_SUCCESS,
|
FOLLOWERS_EXPAND_SUCCESS,
|
||||||
|
FOLLOWERS_FETCH_FAIL,
|
||||||
|
FOLLOWERS_EXPAND_REQUEST,
|
||||||
|
FOLLOWERS_EXPAND_FAIL,
|
||||||
|
FOLLOWING_FETCH_REQUEST,
|
||||||
|
FOLLOWING_FETCH_FAIL,
|
||||||
|
FOLLOWING_EXPAND_REQUEST,
|
||||||
FOLLOWING_FETCH_SUCCESS,
|
FOLLOWING_FETCH_SUCCESS,
|
||||||
FOLLOWING_EXPAND_SUCCESS,
|
FOLLOWING_EXPAND_SUCCESS,
|
||||||
|
FOLLOWING_EXPAND_FAIL,
|
||||||
|
FOLLOW_REQUESTS_FETCH_REQUEST,
|
||||||
|
FOLLOW_REQUESTS_FETCH_FAIL,
|
||||||
|
FOLLOW_REQUESTS_EXPAND_REQUEST,
|
||||||
FOLLOW_REQUESTS_FETCH_SUCCESS,
|
FOLLOW_REQUESTS_FETCH_SUCCESS,
|
||||||
FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
||||||
|
FOLLOW_REQUESTS_EXPAND_FAIL,
|
||||||
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
||||||
FOLLOW_REQUEST_REJECT_SUCCESS,
|
FOLLOW_REQUEST_REJECT_SUCCESS,
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts'
|
||||||
import {
|
import {
|
||||||
REPOSTS_FETCH_SUCCESS,
|
REPOSTS_FETCH_SUCCESS,
|
||||||
} from '../actions/interactions';
|
} from '../actions/interactions'
|
||||||
import {
|
import {
|
||||||
|
BLOCKS_FETCH_REQUEST,
|
||||||
BLOCKS_FETCH_SUCCESS,
|
BLOCKS_FETCH_SUCCESS,
|
||||||
|
BLOCKS_FETCH_FAIL,
|
||||||
|
BLOCKS_EXPAND_REQUEST,
|
||||||
BLOCKS_EXPAND_SUCCESS,
|
BLOCKS_EXPAND_SUCCESS,
|
||||||
} from '../actions/blocks';
|
BLOCKS_EXPAND_FAIL,
|
||||||
|
} from '../actions/blocks'
|
||||||
import {
|
import {
|
||||||
|
MUTES_FETCH_REQUEST,
|
||||||
MUTES_FETCH_SUCCESS,
|
MUTES_FETCH_SUCCESS,
|
||||||
|
MUTES_FETCH_FAIL,
|
||||||
|
MUTES_EXPAND_REQUEST,
|
||||||
MUTES_EXPAND_SUCCESS,
|
MUTES_EXPAND_SUCCESS,
|
||||||
} from '../actions/mutes';
|
MUTES_EXPAND_FAIL,
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
} from '../actions/mutes'
|
||||||
import {
|
import {
|
||||||
GROUP_MEMBERS_FETCH_SUCCESS,
|
GROUP_MEMBERS_FETCH_SUCCESS,
|
||||||
GROUP_MEMBERS_EXPAND_SUCCESS,
|
GROUP_MEMBERS_EXPAND_SUCCESS,
|
||||||
GROUP_REMOVED_ACCOUNTS_FETCH_SUCCESS,
|
GROUP_REMOVED_ACCOUNTS_FETCH_SUCCESS,
|
||||||
GROUP_REMOVED_ACCOUNTS_EXPAND_SUCCESS,
|
GROUP_REMOVED_ACCOUNTS_EXPAND_SUCCESS,
|
||||||
GROUP_REMOVED_ACCOUNTS_REMOVE_SUCCESS,
|
GROUP_REMOVED_ACCOUNTS_REMOVE_SUCCESS,
|
||||||
} from '../actions/groups';
|
} from '../actions/groups'
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
followers: ImmutableMap(),
|
followers: ImmutableMap(),
|
||||||
|
@ -44,12 +64,18 @@ const normalizeList = (state, type, id, accounts, next) => {
|
||||||
return state.setIn([type, id], ImmutableMap({
|
return state.setIn([type, id], ImmutableMap({
|
||||||
next,
|
next,
|
||||||
items: ImmutableList(accounts.map(item => item.id)),
|
items: ImmutableList(accounts.map(item => item.id)),
|
||||||
|
isLoading: false,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const appendToList = (state, type, id, accounts, next) => {
|
const appendToList = (state, type, id, accounts, next) => {
|
||||||
return state.updateIn([type, id], map => {
|
return state.updateIn([type, id], map => {
|
||||||
return map.set('next', next).update('items', list => list.concat(accounts.map(item => item.id)));
|
return map
|
||||||
|
.set('next', next)
|
||||||
|
.set('isLoading', false)
|
||||||
|
.update('items', (list) => {
|
||||||
|
list.concat(accounts.map(item => item.id))
|
||||||
|
})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,16 +85,34 @@ export default function userLists(state = initialState, action) {
|
||||||
return normalizeList(state, 'followers', action.id, action.accounts, action.next);
|
return normalizeList(state, 'followers', action.id, action.accounts, action.next);
|
||||||
case FOLLOWERS_EXPAND_SUCCESS:
|
case FOLLOWERS_EXPAND_SUCCESS:
|
||||||
return appendToList(state, 'followers', action.id, action.accounts, action.next);
|
return appendToList(state, 'followers', action.id, action.accounts, action.next);
|
||||||
|
case FOLLOWERS_FETCH_REQUEST:
|
||||||
|
case FOLLOWERS_EXPAND_REQUEST:
|
||||||
|
return state.setIn(['followers', action.id, 'isLoading'], true);
|
||||||
|
case FOLLOWERS_FETCH_FAIL:
|
||||||
|
case FOLLOWERS_EXPAND_FAIL:
|
||||||
|
return state.setIn(['followers', action.id, 'isLoading'], false);
|
||||||
case FOLLOWING_FETCH_SUCCESS:
|
case FOLLOWING_FETCH_SUCCESS:
|
||||||
return normalizeList(state, 'following', action.id, action.accounts, action.next);
|
return normalizeList(state, 'following', action.id, action.accounts, action.next);
|
||||||
case FOLLOWING_EXPAND_SUCCESS:
|
case FOLLOWING_EXPAND_SUCCESS:
|
||||||
return appendToList(state, 'following', action.id, action.accounts, action.next);
|
return appendToList(state, 'following', action.id, action.accounts, action.next);
|
||||||
|
case FOLLOWING_FETCH_REQUEST:
|
||||||
|
case FOLLOWING_EXPAND_REQUEST:
|
||||||
|
return state.setIn(['following', action.id, 'isLoading'], true);
|
||||||
|
case FOLLOWING_FETCH_FAIL:
|
||||||
|
case FOLLOWING_EXPAND_FAIL:
|
||||||
|
return state.setIn(['following', action.id, 'isLoading'], false);
|
||||||
case REPOSTS_FETCH_SUCCESS:
|
case REPOSTS_FETCH_SUCCESS:
|
||||||
return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id)));
|
return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id)));
|
||||||
case FOLLOW_REQUESTS_FETCH_SUCCESS:
|
case FOLLOW_REQUESTS_FETCH_SUCCESS:
|
||||||
return state.setIn(['follow_requests', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next);
|
return state.setIn(['follow_requests', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next).setIn(['follow_requests', 'isLoading'], false);
|
||||||
case FOLLOW_REQUESTS_EXPAND_SUCCESS:
|
case FOLLOW_REQUESTS_EXPAND_SUCCESS:
|
||||||
return state.updateIn(['follow_requests', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next);
|
return state.updateIn(['follow_requests', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next).setIn(['follow_requests', 'isLoading'], false);
|
||||||
|
case FOLLOW_REQUESTS_FETCH_REQUEST:
|
||||||
|
case FOLLOW_REQUESTS_EXPAND_REQUEST:
|
||||||
|
return state.setIn(['follow_requests', 'isLoading'], true);
|
||||||
|
case FOLLOW_REQUESTS_FETCH_FAIL:
|
||||||
|
case FOLLOW_REQUESTS_EXPAND_FAIL:
|
||||||
|
return state.setIn(['follow_requests', 'isLoading'], false);
|
||||||
case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
||||||
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
||||||
return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id));
|
return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id));
|
||||||
|
@ -76,10 +120,22 @@ export default function userLists(state = initialState, action) {
|
||||||
return state.setIn(['blocks', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
|
return state.setIn(['blocks', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
|
||||||
case BLOCKS_EXPAND_SUCCESS:
|
case BLOCKS_EXPAND_SUCCESS:
|
||||||
return state.updateIn(['blocks', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
|
return state.updateIn(['blocks', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['blocks', 'next'], action.next);
|
||||||
|
case BLOCKS_FETCH_REQUEST:
|
||||||
|
case BLOCKS_EXPAND_REQUEST:
|
||||||
|
return state.setIn(['blocks', 'isLoading'], true);
|
||||||
|
case BLOCKS_FETCH_FAIL:
|
||||||
|
case BLOCKS_EXPAND_FAIL:
|
||||||
|
return state.setIn(['blocks', 'isLoading'], false);
|
||||||
case MUTES_FETCH_SUCCESS:
|
case MUTES_FETCH_SUCCESS:
|
||||||
return state.setIn(['mutes', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
|
return state.setIn(['mutes', 'items'], ImmutableList(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
|
||||||
case MUTES_EXPAND_SUCCESS:
|
case MUTES_EXPAND_SUCCESS:
|
||||||
return state.updateIn(['mutes', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
|
return state.updateIn(['mutes', 'items'], list => list.concat(action.accounts.map(item => item.id))).setIn(['mutes', 'next'], action.next);
|
||||||
|
case MUTES_FETCH_REQUEST:
|
||||||
|
case MUTES_EXPAND_REQUEST:
|
||||||
|
return state.setIn(['mutes', 'isLoading'], true);
|
||||||
|
case MUTES_FETCH_FAIL:
|
||||||
|
case MUTES_EXPAND_FAIL:
|
||||||
|
return state.setIn(['mutes', 'isLoading'], false);
|
||||||
case GROUP_MEMBERS_FETCH_SUCCESS:
|
case GROUP_MEMBERS_FETCH_SUCCESS:
|
||||||
return normalizeList(state, 'groups', action.id, action.accounts, action.next);
|
return normalizeList(state, 'groups', action.id, action.accounts, action.next);
|
||||||
case GROUP_MEMBERS_EXPAND_SUCCESS:
|
case GROUP_MEMBERS_EXPAND_SUCCESS:
|
||||||
|
|
|
@ -2,6 +2,45 @@ import EXIF from 'exif-js';
|
||||||
|
|
||||||
const MAX_IMAGE_PIXELS = 1638400; // 1280x1280px
|
const MAX_IMAGE_PIXELS = 1638400; // 1280x1280px
|
||||||
|
|
||||||
|
const _browser_quirks = {};
|
||||||
|
|
||||||
|
// Some browsers will automatically draw images respecting their EXIF orientation
|
||||||
|
// while others won't, and the safest way to detect that is to examine how it
|
||||||
|
// is done on a known image.
|
||||||
|
// See https://github.com/w3c/csswg-drafts/issues/4666
|
||||||
|
// and https://github.com/blueimp/JavaScript-Load-Image/commit/1e4df707821a0afcc11ea0720ee403b8759f3881
|
||||||
|
const dropOrientationIfNeeded = (orientation) => new Promise(resolve => {
|
||||||
|
switch (_browser_quirks['image-orientation-automatic']) {
|
||||||
|
case true:
|
||||||
|
resolve(1);
|
||||||
|
break;
|
||||||
|
case false:
|
||||||
|
resolve(orientation);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// black 2x1 JPEG, with the following meta information set:
|
||||||
|
// - EXIF Orientation: 6 (Rotated 90° CCW)
|
||||||
|
const testImageURL =
|
||||||
|
'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
|
||||||
|
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
|
||||||
|
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
|
||||||
|
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/x' +
|
||||||
|
'ABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAA' +
|
||||||
|
'AAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==';
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
const automatic = (img.width === 1 && img.height === 2);
|
||||||
|
_browser_quirks['image-orientation-automatic'] = automatic;
|
||||||
|
resolve(automatic ? 1 : orientation);
|
||||||
|
};
|
||||||
|
img.onerror = () => {
|
||||||
|
_browser_quirks['image-orientation-automatic'] = false;
|
||||||
|
resolve(orientation);
|
||||||
|
};
|
||||||
|
img.src = testImageURL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const getImageUrl = inputFile => new Promise((resolve, reject) => {
|
const getImageUrl = inputFile => new Promise((resolve, reject) => {
|
||||||
if (window.URL && URL.createObjectURL) {
|
if (window.URL && URL.createObjectURL) {
|
||||||
try {
|
try {
|
||||||
|
@ -38,7 +77,11 @@ const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
|
||||||
|
|
||||||
EXIF.getData(img, () => {
|
EXIF.getData(img, () => {
|
||||||
const orientation = EXIF.getTag(img, 'Orientation');
|
const orientation = EXIF.getTag(img, 'Orientation');
|
||||||
resolve(orientation);
|
if (orientation !== 1) {
|
||||||
|
dropOrientationIfNeeded(orientation).then(resolve).catch(() => resolve(orientation));
|
||||||
|
} else {
|
||||||
|
resolve(orientation);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,6 +110,14 @@ const processImage = (img, { width, height, orientation, type = 'image/png' }) =
|
||||||
|
|
||||||
context.drawImage(img, 0, 0, width, height);
|
context.drawImage(img, 0, 0, width, height);
|
||||||
|
|
||||||
|
// The Tor Browser and maybe other browsers may prevent reading from canvas
|
||||||
|
// and return an all-white image instead. Assume reading failed if the resized
|
||||||
|
// image is perfectly white.
|
||||||
|
const imageData = context.getImageData(0, 0, width, height);
|
||||||
|
if (imageData.data.every(value => value === 255)) {
|
||||||
|
throw 'Failed to read from canvas';
|
||||||
|
}
|
||||||
|
|
||||||
canvas.toBlob(resolve, type);
|
canvas.toBlob(resolve, type);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,6 @@ function main ( ) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const reactComponents = document.querySelectorAll('[data-component]');
|
const reactComponents = document.querySelectorAll('[data-component]');
|
||||||
console.log("reactComponents:", reactComponents)
|
|
||||||
|
|
||||||
if (reactComponents.length > 0) {
|
if (reactComponents.length > 0) {
|
||||||
import(/* webpackChunkName: "containers/media_container" */ '../gabsocial/containers/media_container')
|
import(/* webpackChunkName: "containers/media_container" */ '../gabsocial/containers/media_container')
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
--fs_m: 1.0714285714rem;
|
--fs_m: 1.0714285714rem;
|
||||||
--fs_l: 1.1428571429rem;
|
--fs_l: 1.1428571429rem;
|
||||||
--fs_xl: 1.3571428571rem;
|
--fs_xl: 1.3571428571rem;
|
||||||
--fs_xxl: 1.7142857143;
|
--fs_xxl: 1.7142857143rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
@ -372,6 +372,7 @@ body {
|
||||||
.top0 { top: 0; }
|
.top0 { top: 0; }
|
||||||
.top80PX { top: 80px; }
|
.top80PX { top: 80px; }
|
||||||
.top60PC { top: 60%; }
|
.top60PC { top: 60%; }
|
||||||
|
.top50PC { top: 50%; }
|
||||||
|
|
||||||
.bottom0 { bottom: 0; }
|
.bottom0 { bottom: 0; }
|
||||||
.bottomAuto { bottom: auto; }
|
.bottomAuto { bottom: auto; }
|
||||||
|
@ -425,6 +426,7 @@ body {
|
||||||
.height1PX { height: 1px; }
|
.height1PX { height: 1px; }
|
||||||
|
|
||||||
.maxWidth100PC { max-width: 100%; }
|
.maxWidth100PC { max-width: 100%; }
|
||||||
|
.maxWidth640PX { max-width: 640px; }
|
||||||
|
|
||||||
.width100PC { width: 100%; }
|
.width100PC { width: 100%; }
|
||||||
.width50PC { width: 50%; }
|
.width50PC { width: 50%; }
|
||||||
|
|
|
@ -104,7 +104,8 @@ class MediaAttachment < ApplicationRecord
|
||||||
|
|
||||||
validates :account, presence: true
|
validates :account, presence: true
|
||||||
validates :description, length: { maximum: 420 }, if: :local?
|
validates :description, length: { maximum: 420 }, if: :local?
|
||||||
|
validates :file, presence: true, if: :local?
|
||||||
|
|
||||||
scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
|
scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
|
||||||
scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
|
scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
|
||||||
scope :local, -> { where(remote_url: '') }
|
scope :local, -> { where(remote_url: '') }
|
||||||
|
|
|
@ -351,7 +351,7 @@ class Status < ApplicationRecord
|
||||||
apply_timeline_filters(query, account, local_only)
|
apply_timeline_filters(query, account, local_only)
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_tag_timeline(tag, account = nil, local_only = false)
|
def as_tag_timeline(tag, account = nil, local_only = true)
|
||||||
query = timeline_scope(local_only).tagged_with(tag).without_replies
|
query = timeline_scope(local_only).tagged_with(tag).without_replies
|
||||||
|
|
||||||
apply_timeline_filters(query, account, local_only)
|
apply_timeline_filters(query, account, local_only)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class HashtagQueryService < BaseService
|
class HashtagQueryService < BaseService
|
||||||
|
LIMIT_PER_MODE = 1
|
||||||
|
|
||||||
def call(tag, params, account = nil, local = false)
|
def call(tag, params, account = nil, local = false)
|
||||||
tags = tags_for(Array(tag.name) | Array(params[:any])).pluck(:id)
|
tags = tags_for(Array(tag.name) | Array(params[:any])).pluck(:id)
|
||||||
all = tags_for(params[:all])
|
all = tags_for(params[:all])
|
||||||
|
@ -14,7 +16,7 @@ class HashtagQueryService < BaseService
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def tags_for(tags)
|
def tags_for(names)
|
||||||
Tag.where(name: tags.map(&:downcase)) if tags.presence
|
Tag.matching_name(Array(names).take(LIMIT_PER_MODE)) if names.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -53,7 +53,7 @@ class PostStatusService < BaseService
|
||||||
def preprocess_attributes!
|
def preprocess_attributes!
|
||||||
@text = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
|
@text = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
|
||||||
@visibility = @options[:visibility] || @account.user&.setting_default_privacy
|
@visibility = @options[:visibility] || @account.user&.setting_default_privacy
|
||||||
@visibility = :unlisted if @visibility == :public && @account.silenced?
|
@visibility = :unlisted if @visibility&.to_sym == :public && @account.silenced?
|
||||||
@scheduled_at = @options[:scheduled_at]&.to_datetime
|
@scheduled_at = @options[:scheduled_at]&.to_datetime
|
||||||
@scheduled_at = nil if scheduled_in_the_past?
|
@scheduled_at = nil if scheduled_in_the_past?
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
|
|
|
@ -13,7 +13,7 @@ class VoteService < BaseService
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
@choices.each do |choice|
|
@choices.each do |choice|
|
||||||
@votes << @poll.votes.create!(account: @account, choice: choice)
|
@votes << @poll.votes.create!(account: @account, choice: Integer(choice))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Rack::Attack
|
||||||
/auth/sign_in
|
/auth/sign_in
|
||||||
/auth
|
/auth
|
||||||
/auth/password
|
/auth/password
|
||||||
|
/auth/confirmation
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
||||||
|
|
|
@ -29,8 +29,8 @@ en:
|
||||||
setting_aggregate_reblogs: Do not show new reposts for gabs that have been recently reposted (only affects newly-received reposts)
|
setting_aggregate_reblogs: Do not show new reposts for gabs that have been recently reposted (only affects newly-received reposts)
|
||||||
setting_default_language: The language of your gabs can be detected automatically, but it's not always accurate
|
setting_default_language: The language of your gabs can be detected automatically, but it's not always accurate
|
||||||
setting_display_media_default: Hide media marked as sensitive
|
setting_display_media_default: Hide media marked as sensitive
|
||||||
setting_display_media_hide_all: Always hide all media
|
setting_display_media_hide_all: Always hide media
|
||||||
setting_display_media_show_all: Always show media marked as sensitive
|
setting_display_media_show_all: Always show media
|
||||||
setting_hide_network: Who you follow and who follows you will not be shown on your profile
|
setting_hide_network: Who you follow and who follows you will not be shown on your profile
|
||||||
setting_noindex: Affects your public profile and status pages
|
setting_noindex: Affects your public profile and status pages
|
||||||
setting_show_application: The application you use to gab will be displayed in the detailed view of your gabs
|
setting_show_application: The application you use to gab will be displayed in the detailed view of your gabs
|
||||||
|
|
|
@ -29,8 +29,8 @@ en_GB:
|
||||||
setting_aggregate_reblogs: Do not show new reposts for gabs that have been recently reposted (only affects newly-received reposts)
|
setting_aggregate_reblogs: Do not show new reposts for gabs that have been recently reposted (only affects newly-received reposts)
|
||||||
setting_default_language: The language of your gabs can be detected automatically, but it's not always accurate
|
setting_default_language: The language of your gabs can be detected automatically, but it's not always accurate
|
||||||
setting_display_media_default: Hide media marked as sensitive
|
setting_display_media_default: Hide media marked as sensitive
|
||||||
setting_display_media_hide_all: Always hide all media
|
setting_display_media_hide_all: Always hide media
|
||||||
setting_display_media_show_all: Always show media marked as sensitive
|
setting_display_media_show_all: Always show media
|
||||||
setting_hide_network: Who you follow and who follows you will not be shown on your profile
|
setting_hide_network: Who you follow and who follows you will not be shown on your profile
|
||||||
setting_noindex: Affects your public profile and status pages
|
setting_noindex: Affects your public profile and status pages
|
||||||
setting_show_application: The application you use to gab will be displayed in the detailed view of your gabs
|
setting_show_application: The application you use to gab will be displayed in the detailed view of your gabs
|
||||||
|
|
|
@ -886,16 +886,12 @@ module GabSocial
|
||||||
Your database user is not allowed to create, drop, or execute triggers on the
|
Your database user is not allowed to create, drop, or execute triggers on the
|
||||||
table #{table}.
|
table #{table}.
|
||||||
|
|
||||||
If you are using PostgreSQL you can solve this by logging in to the GitLab
|
If you are using PostgreSQL you can solve this by logging in to the GabSocial
|
||||||
database (#{dbname}) using a super user and running:
|
database (#{dbname}) using a super user and running:
|
||||||
|
|
||||||
ALTER USER #{user} WITH SUPERUSER
|
ALTER USER #{user} WITH SUPERUSER
|
||||||
|
|
||||||
For MySQL you instead need to run:
|
The query will grant the user super user permissions, ensuring you don't run
|
||||||
|
|
||||||
GRANT ALL PRIVILEGES ON *.* TO #{user}@'%'
|
|
||||||
|
|
||||||
Both queries will grant the user super user permissions, ensuring you don't run
|
|
||||||
into similar problems in the future (e.g. when new tables are created).
|
into similar problems in the future (e.g. when new tables are created).
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue