eslint --fix
This commit is contained in:
parent
5cf3affcd8
commit
fc72e39ff4
101 changed files with 1014 additions and 969 deletions
|
@ -14,7 +14,7 @@ export function createAuthApp() {
|
|||
// TODO: Add commit hash to client_name
|
||||
client_name: `SoapboxFE_${(new Date()).toISOString()}`,
|
||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
scopes: 'read write follow push admin'
|
||||
scopes: 'read write follow push admin',
|
||||
}).then(response => {
|
||||
dispatch(authAppCreated(response.data));
|
||||
}).then(() => {
|
||||
|
@ -23,12 +23,12 @@ export function createAuthApp() {
|
|||
client_id: app.get('client_id'),
|
||||
client_secret: app.get('client_secret'),
|
||||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
grant_type: 'client_credentials'
|
||||
grant_type: 'client_credentials',
|
||||
});
|
||||
}).then(response => {
|
||||
dispatch(authAppAuthorized(response.data));
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function logIn(username, password) {
|
||||
|
@ -40,14 +40,14 @@ export function logIn(username, password) {
|
|||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
grant_type: 'password',
|
||||
username: username,
|
||||
password: password
|
||||
password: password,
|
||||
}).then(response => {
|
||||
dispatch(authLoggedIn(response.data));
|
||||
}).catch((error) => {
|
||||
dispatch(showAlert('Login failed.', 'Invalid username or password.'));
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function logOut() {
|
||||
|
@ -60,20 +60,20 @@ export function logOut() {
|
|||
export function authAppCreated(app) {
|
||||
return {
|
||||
type: AUTH_APP_CREATED,
|
||||
app
|
||||
app,
|
||||
};
|
||||
}
|
||||
|
||||
export function authAppAuthorized(app) {
|
||||
return {
|
||||
type: AUTH_APP_AUTHORIZED,
|
||||
app
|
||||
app,
|
||||
};
|
||||
}
|
||||
|
||||
export function authLoggedIn(user) {
|
||||
return {
|
||||
type: AUTH_LOGGED_IN,
|
||||
user
|
||||
user,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,100 +13,100 @@ export const GROUP_EDITOR_RESET = 'GROUP_EDITOR_RESET';
|
|||
export const GROUP_EDITOR_SETUP = 'GROUP_EDITOR_SETUP';
|
||||
|
||||
export const submit = (routerHistory) => (dispatch, getState) => {
|
||||
const groupId = getState().getIn(['group_editor', 'groupId']);
|
||||
const title = getState().getIn(['group_editor', 'title']);
|
||||
const description = getState().getIn(['group_editor', 'description']);
|
||||
const coverImage = getState().getIn(['group_editor', 'coverImage']);
|
||||
const groupId = getState().getIn(['group_editor', 'groupId']);
|
||||
const title = getState().getIn(['group_editor', 'title']);
|
||||
const description = getState().getIn(['group_editor', 'description']);
|
||||
const coverImage = getState().getIn(['group_editor', 'coverImage']);
|
||||
|
||||
if (groupId === null) {
|
||||
dispatch(create(title, description, coverImage, routerHistory));
|
||||
} else {
|
||||
dispatch(update(groupId, title, description, coverImage, routerHistory));
|
||||
}
|
||||
if (groupId === null) {
|
||||
dispatch(create(title, description, coverImage, routerHistory));
|
||||
} else {
|
||||
dispatch(update(groupId, title, description, coverImage, routerHistory));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const create = (title, description, coverImage, routerHistory) => (dispatch, getState) => {
|
||||
if (!getState().get('me')) return;
|
||||
if (!getState().get('me')) return;
|
||||
|
||||
dispatch(createRequest());
|
||||
dispatch(createRequest());
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('title', title);
|
||||
formData.append('description', description);
|
||||
const formData = new FormData();
|
||||
formData.append('title', title);
|
||||
formData.append('description', description);
|
||||
|
||||
if (coverImage !== null) {
|
||||
formData.append('cover_image', coverImage);
|
||||
}
|
||||
if (coverImage !== null) {
|
||||
formData.append('cover_image', coverImage);
|
||||
}
|
||||
|
||||
api(getState).post('/api/v1/groups', formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(({ data }) => {
|
||||
dispatch(createSuccess(data));
|
||||
routerHistory.push(`/groups/${data.id}`);
|
||||
}).catch(err => dispatch(createFail(err)));
|
||||
};
|
||||
api(getState).post('/api/v1/groups', formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(({ data }) => {
|
||||
dispatch(createSuccess(data));
|
||||
routerHistory.push(`/groups/${data.id}`);
|
||||
}).catch(err => dispatch(createFail(err)));
|
||||
};
|
||||
|
||||
|
||||
export const createRequest = id => ({
|
||||
type: GROUP_CREATE_REQUEST,
|
||||
id,
|
||||
type: GROUP_CREATE_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const createSuccess = group => ({
|
||||
type: GROUP_CREATE_SUCCESS,
|
||||
group,
|
||||
type: GROUP_CREATE_SUCCESS,
|
||||
group,
|
||||
});
|
||||
|
||||
export const createFail = error => ({
|
||||
type: GROUP_CREATE_FAIL,
|
||||
error,
|
||||
type: GROUP_CREATE_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const update = (groupId, title, description, coverImage, routerHistory) => (dispatch, getState) => {
|
||||
if (!getState().get('me')) return;
|
||||
if (!getState().get('me')) return;
|
||||
|
||||
dispatch(updateRequest());
|
||||
dispatch(updateRequest());
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('title', title);
|
||||
formData.append('description', description);
|
||||
const formData = new FormData();
|
||||
formData.append('title', title);
|
||||
formData.append('description', description);
|
||||
|
||||
if (coverImage !== null) {
|
||||
formData.append('cover_image', coverImage);
|
||||
}
|
||||
if (coverImage !== null) {
|
||||
formData.append('cover_image', coverImage);
|
||||
}
|
||||
|
||||
api(getState).put(`/api/v1/groups/${groupId}`, formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(({ data }) => {
|
||||
dispatch(updateSuccess(data));
|
||||
routerHistory.push(`/groups/${data.id}`);
|
||||
}).catch(err => dispatch(updateFail(err)));
|
||||
};
|
||||
api(getState).put(`/api/v1/groups/${groupId}`, formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(({ data }) => {
|
||||
dispatch(updateSuccess(data));
|
||||
routerHistory.push(`/groups/${data.id}`);
|
||||
}).catch(err => dispatch(updateFail(err)));
|
||||
};
|
||||
|
||||
|
||||
export const updateRequest = id => ({
|
||||
type: GROUP_UPDATE_REQUEST,
|
||||
id,
|
||||
type: GROUP_UPDATE_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const updateSuccess = group => ({
|
||||
type: GROUP_UPDATE_SUCCESS,
|
||||
group,
|
||||
type: GROUP_UPDATE_SUCCESS,
|
||||
group,
|
||||
});
|
||||
|
||||
export const updateFail = error => ({
|
||||
type: GROUP_UPDATE_FAIL,
|
||||
error,
|
||||
type: GROUP_UPDATE_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const changeValue = (field, value) => ({
|
||||
type: GROUP_EDITOR_VALUE_CHANGE,
|
||||
field,
|
||||
value,
|
||||
type: GROUP_EDITOR_VALUE_CHANGE,
|
||||
field,
|
||||
value,
|
||||
});
|
||||
|
||||
export const reset = () => ({
|
||||
type: GROUP_EDITOR_RESET
|
||||
type: GROUP_EDITOR_RESET,
|
||||
});
|
||||
|
||||
export const setUp = (group) => ({
|
||||
type: GROUP_EDITOR_SETUP,
|
||||
group,
|
||||
type: GROUP_EDITOR_SETUP,
|
||||
group,
|
||||
});
|
||||
|
|
|
@ -193,7 +193,7 @@ export function joinGroupRequest(id) {
|
|||
export function joinGroupSuccess(relationship) {
|
||||
return {
|
||||
type: GROUP_JOIN_SUCCESS,
|
||||
relationship
|
||||
relationship,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ export const INSTANCE_FAIL = 'INSTANCE_FAIL';
|
|||
|
||||
export function fetchInstance() {
|
||||
return (dispatch, getState) => {
|
||||
api(getState).get(`/api/v1/instance`).then(response => {
|
||||
api(getState).get('/api/v1/instance').then(response => {
|
||||
dispatch(importInstance(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(instanceFail(error));
|
||||
|
@ -16,7 +16,7 @@ export function fetchInstance() {
|
|||
export function importInstance(instance) {
|
||||
return {
|
||||
type: INSTANCE_IMPORT,
|
||||
instance
|
||||
instance,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ export const ME_FETCH_SKIP = 'ME_FETCH_SKIP';
|
|||
export function fetchMe() {
|
||||
return (dispatch, getState) => {
|
||||
const accessToken = getState().getIn(['auth', 'user', 'access_token']);
|
||||
if (!accessToken) return dispatch({type: ME_FETCH_SKIP});
|
||||
if (!accessToken) return dispatch({ type: ME_FETCH_SKIP });
|
||||
dispatch(fetchMeRequest());
|
||||
api(getState).get(`/api/v1/accounts/verify_credentials`).then(response => {
|
||||
api(getState).get('/api/v1/accounts/verify_credentials').then(response => {
|
||||
dispatch(fetchMeSuccess(response.data));
|
||||
dispatch(importFetchedAccount(response.data));
|
||||
}).catch(error => {
|
||||
|
@ -29,7 +29,7 @@ export function fetchMeRequest() {
|
|||
export function fetchMeSuccess(me) {
|
||||
return {
|
||||
type: ME_FETCH_SUCCESS,
|
||||
me
|
||||
me,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
|
|||
|
||||
export function initializeNotifications() {
|
||||
return {
|
||||
type: NOTIFICATIONS_INITIALIZE
|
||||
type: NOTIFICATIONS_INITIALIZE,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -115,11 +115,10 @@ export function updateNotificationsQueue(notification, intlMessages, intlLocale,
|
|||
intlMessages,
|
||||
intlLocale,
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dispatch(updateNotifications(notification, intlMessages, intlLocale));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export function dequeueNotifications() {
|
||||
|
@ -129,13 +128,11 @@ export function dequeueNotifications() {
|
|||
|
||||
if (totalQueuedNotificationsCount == 0) {
|
||||
return;
|
||||
}
|
||||
else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) {
|
||||
} else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) {
|
||||
queuedNotifications.forEach(block => {
|
||||
dispatch(updateNotifications(block.notification, block.intlMessages, block.intlLocale));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dispatch(expandNotifications());
|
||||
}
|
||||
|
||||
|
@ -143,7 +140,7 @@ export function dequeueNotifications() {
|
|||
type: NOTIFICATIONS_DEQUEUE,
|
||||
});
|
||||
dispatch(markReadNotifications());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
|
||||
|
@ -240,7 +237,7 @@ export function scrollTopNotifications(top) {
|
|||
top,
|
||||
});
|
||||
dispatch(markReadNotifications());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function setFilter (filterType) {
|
||||
|
@ -262,12 +259,12 @@ export function markReadNotifications() {
|
|||
const last_read = getState().getIn(['notifications', 'lastRead']);
|
||||
|
||||
if (top_notification && top_notification > last_read) {
|
||||
api(getState).post('/api/v1/notifications/mark_read', {id: top_notification}).then(response => {
|
||||
api(getState).post('/api/v1/notifications/mark_read', { id: top_notification }).then(response => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_MARK_READ,
|
||||
notification: top_notification,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ export const PATRON_FUNDING_FETCH_FAIL = 'PATRON_FUNDING_FETCH_FAIL';
|
|||
|
||||
export function fetchFunding() {
|
||||
return (dispatch, getState) => {
|
||||
api(getState).get(`/patron/v1/funding`).then(response => {
|
||||
api(getState).get('/patron/v1/funding').then(response => {
|
||||
dispatch(importFetchedFunding(response.data));
|
||||
}).then(() => {
|
||||
dispatch(fetchFundingSuccess());
|
||||
|
@ -18,7 +18,7 @@ export function fetchFunding() {
|
|||
export function importFetchedFunding(funding) {
|
||||
return {
|
||||
type: PATRON_FUNDING_IMPORT,
|
||||
funding
|
||||
funding,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ export const SOAPBOX_CONFIG_FAIL = 'SOAPBOX_CONFIG_FAIL';
|
|||
|
||||
export function fetchSoapboxConfig() {
|
||||
return (dispatch, getState) => {
|
||||
api(getState).get(`/soapbox/soapbox.json`).then(response => {
|
||||
api(getState).get('/soapbox/soapbox.json').then(response => {
|
||||
dispatch(importSoapboxConfig(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(soapboxConfigFail(error));
|
||||
|
@ -16,7 +16,7 @@ export function fetchSoapboxConfig() {
|
|||
export function importSoapboxConfig(soapboxConfig) {
|
||||
return {
|
||||
type: SOAPBOX_CONFIG_IMPORT,
|
||||
soapboxConfig
|
||||
soapboxConfig,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ export function updateTimelineQueue(timeline, status, accept) {
|
|||
timeline,
|
||||
status,
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export function dequeueTimeline(timeline, expandFunc, optionalExpandArgs) {
|
||||
|
@ -57,27 +57,22 @@ export function dequeueTimeline(timeline, expandFunc, optionalExpandArgs) {
|
|||
|
||||
if (totalQueuedItemsCount == 0) {
|
||||
return;
|
||||
}
|
||||
else if (totalQueuedItemsCount > 0 && totalQueuedItemsCount <= MAX_QUEUED_ITEMS) {
|
||||
} else if (totalQueuedItemsCount > 0 && totalQueuedItemsCount <= MAX_QUEUED_ITEMS) {
|
||||
queuedItems.forEach(status => {
|
||||
dispatch(updateTimeline(timeline, status.toJS(), null));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (typeof expandFunc === 'function') {
|
||||
dispatch(clearTimeline(timeline));
|
||||
expandFunc();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (timeline === 'home') {
|
||||
dispatch(clearTimeline(timeline));
|
||||
dispatch(expandHomeTimeline(optionalExpandArgs));
|
||||
}
|
||||
else if (timeline === 'community') {
|
||||
} else if (timeline === 'community') {
|
||||
dispatch(clearTimeline(timeline));
|
||||
dispatch(expandCommunityTimeline(optionalExpandArgs));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
shouldDispatchDequeue = false;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +84,7 @@ export function dequeueTimeline(timeline, expandFunc, optionalExpandArgs) {
|
|||
type: TIMELINE_DEQUEUE,
|
||||
timeline,
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export function deleteFromTimelines(id) {
|
||||
|
|
|
@ -131,7 +131,7 @@ class Account extends ImmutablePureComponent {
|
|||
<span className='relationship-tag'>
|
||||
<FormattedMessage id='account.follows_you' defaultMessage='Follows you' />
|
||||
</span>
|
||||
: '' }
|
||||
: '' }
|
||||
|
||||
<div className='account__relationship'>
|
||||
{buttons}
|
||||
|
|
|
@ -22,7 +22,7 @@ export default class DisplayName extends React.PureComponent {
|
|||
<bdi key={a.get('id')}>
|
||||
<strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} />
|
||||
</bdi>,
|
||||
a.get('is_verified') && <VerificationBadge />
|
||||
a.get('is_verified') && <VerificationBadge />,
|
||||
]).reduce((prev, cur) => [prev, ', ', cur]);
|
||||
|
||||
if (others.size - 2 > 0) {
|
||||
|
|
|
@ -135,7 +135,8 @@ class DropdownMenu extends React.PureComponent {
|
|||
onKeyDown={this.handleItemKeyDown}
|
||||
data-index={i}
|
||||
target={newTab ? '_blank' : null}
|
||||
data-method={isLogout ? 'delete' : null}>
|
||||
data-method={isLogout ? 'delete' : null}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -41,9 +41,9 @@ export default class ExtendedVideoPlayer extends React.PureComponent {
|
|||
|
||||
render () {
|
||||
const { src, muted, controls, alt } = this.props;
|
||||
let conditionalAttributes = {}
|
||||
let conditionalAttributes = {};
|
||||
if (isIOS()) {
|
||||
conditionalAttributes.playsInline = '1'
|
||||
conditionalAttributes.playsInline = '1';
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -119,34 +119,34 @@ class ColumnHeader extends React.PureComponent {
|
|||
let expandedContent = null;
|
||||
if ((expandedFor === 'lists' || activeItem === 'lists') && lists) {
|
||||
expandedContent = lists.map(list =>
|
||||
<Link
|
||||
(<Link
|
||||
key={list.get('id')}
|
||||
to={`/list/${list.get('id')}`}
|
||||
className={
|
||||
classNames('btn btn--sub grouped', {
|
||||
'active': list.get('id') === activeSubItem
|
||||
'active': list.get('id') === activeSubItem,
|
||||
})
|
||||
}
|
||||
>
|
||||
{list.get('title')}
|
||||
</Link>
|
||||
)
|
||||
</Link>)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={wrapperClassName}>
|
||||
<h1 className={buttonClassName}>
|
||||
<Link to='/' className={classNames('btn grouped', {'active': 'home' === activeItem})}>
|
||||
<Link to='/' className={classNames('btn grouped', { 'active': 'home' === activeItem })}>
|
||||
<Icon id='home' fixedWidth className='column-header__icon' />
|
||||
{formatMessage(messages.homeTitle)}
|
||||
</Link>
|
||||
|
||||
<Link to='/timeline/local' className={classNames('btn grouped', {'active': 'local' === activeItem})}>
|
||||
<Link to='/timeline/local' className={classNames('btn grouped', { 'active': 'local' === activeItem })}>
|
||||
<Icon id='site-icon' fixedWidth className='column-header__icon' />
|
||||
{siteTitle}
|
||||
</Link>
|
||||
|
||||
<Link to='/timeline/fediverse' className={classNames('btn grouped', {'active': 'fediverse' === activeItem})}>
|
||||
<Link to='/timeline/fediverse' className={classNames('btn grouped', { 'active': 'fediverse' === activeItem })}>
|
||||
<Icon id='fediverse' fixedWidth className='column-header__icon' />
|
||||
{formatMessage(messages.fediverseTitle)}
|
||||
</Link>
|
||||
|
@ -171,6 +171,7 @@ class ColumnHeader extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(ColumnHeader));
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class Icon extends React.PureComponent {
|
|||
// tag. There is a common adblocker rule which hides elements with
|
||||
// alt='retweet' unless the domain is twitter.com. This should
|
||||
// change what screenreaders call it as well.
|
||||
var alt_id = (id == "retweet") ? "repost" : id;
|
||||
var alt_id = (id == 'retweet') ? 'repost' : id;
|
||||
return (
|
||||
<i role='img' alt={alt_id} className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />
|
||||
);
|
||||
|
|
|
@ -4,19 +4,19 @@ import Icon from 'gabsocial/components/icon';
|
|||
import { shortNumberFormat } from 'gabsocial/utils/numbers';
|
||||
|
||||
const IconWithBadge = ({ id, count, className }) => {
|
||||
if (count < 1) return null;
|
||||
if (count < 1) return null;
|
||||
|
||||
return (
|
||||
<i className='icon-with-badge'>
|
||||
{count > 0 && <i className='icon-with-badge__badge'>{shortNumberFormat(count)}</i>}
|
||||
</i>
|
||||
)
|
||||
return (
|
||||
<i className='icon-with-badge'>
|
||||
{count > 0 && <i className='icon-with-badge__badge'>{shortNumberFormat(count)}</i>}
|
||||
</i>
|
||||
);
|
||||
};
|
||||
|
||||
IconWithBadge.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
count: PropTypes.number.isRequired,
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string.isRequired,
|
||||
count: PropTypes.number.isRequired,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default IconWithBadge;
|
||||
|
|
|
@ -178,12 +178,12 @@ class Item extends React.PureComponent {
|
|||
</a>
|
||||
);
|
||||
} else if (attachment.get('type') === 'gifv') {
|
||||
let conditionalAttributes = {}
|
||||
let conditionalAttributes = {};
|
||||
if (isIOS()) {
|
||||
conditionalAttributes.playsInline = '1'
|
||||
conditionalAttributes.playsInline = '1';
|
||||
}
|
||||
if (autoPlayGif) {
|
||||
conditionalAttributes.autoPlay = '1'
|
||||
conditionalAttributes.autoPlay = '1';
|
||||
}
|
||||
|
||||
thumbnail = (
|
||||
|
@ -329,12 +329,12 @@ class MediaGallery extends React.PureComponent {
|
|||
if (isPortrait(ar1) && isPortrait(ar2)) {
|
||||
itemsDimensions = [
|
||||
{ w: 50, h: '100%', r: '2px' },
|
||||
{ w: 50, h: '100%', l: '2px' }
|
||||
{ w: 50, h: '100%', l: '2px' },
|
||||
];
|
||||
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
|
||||
itemsDimensions = [
|
||||
{ w: 100, h: panoSize_px, b: '2px' },
|
||||
{ w: 100, h: panoSize_px, t: '2px' }
|
||||
{ w: 100, h: panoSize_px, t: '2px' },
|
||||
];
|
||||
} else if (
|
||||
(isPanoramic(ar1) && isPortrait(ar2)) ||
|
||||
|
@ -355,7 +355,7 @@ class MediaGallery extends React.PureComponent {
|
|||
} else {
|
||||
itemsDimensions = [
|
||||
{ w: 50, h: '100%', r: '2px' },
|
||||
{ w: 50, h: '100%', l: '2px' }
|
||||
{ w: 50, h: '100%', l: '2px' },
|
||||
];
|
||||
}
|
||||
} else if (size == 3) {
|
||||
|
@ -371,19 +371,19 @@ class MediaGallery extends React.PureComponent {
|
|||
|
||||
if (isPanoramic(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
||||
itemsDimensions = [
|
||||
{ w: 100, h: `50%`, b: '2px' },
|
||||
{ w: 100, h: '50%', b: '2px' },
|
||||
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
||||
{ w: 50, h: '50%', t: '2px', l: '2px' }
|
||||
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
||||
];
|
||||
} else if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
|
||||
itemsDimensions = [
|
||||
{ w: 100, h: panoSize_px, b: '4px' },
|
||||
{ w: 100, h: panoSize_px },
|
||||
{ w: 100, h: panoSize_px, t: '4px' }
|
||||
{ w: 100, h: panoSize_px, t: '4px' },
|
||||
];
|
||||
} else if (isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
||||
itemsDimensions = [
|
||||
{ w: 50, h: `100%`, r: '2px' },
|
||||
{ w: 50, h: '100%', r: '2px' },
|
||||
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
||||
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
||||
];
|
||||
|
@ -391,7 +391,7 @@ class MediaGallery extends React.PureComponent {
|
|||
itemsDimensions = [
|
||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
||||
{ w: 50, h: '50%', l: '-2px', b: '-2px', pos: 'absolute', float: 'none' },
|
||||
{ w: 50, h: `100%`, r: '-2px', t: '0px', b: '0px', pos: 'absolute', float: 'none' }
|
||||
{ w: 50, h: '100%', r: '-2px', t: '0px', b: '0px', pos: 'absolute', float: 'none' },
|
||||
];
|
||||
} else if (
|
||||
(isNonConformingRatio(ar1) && isPortrait(ar2) && isNonConformingRatio(ar3)) ||
|
||||
|
@ -399,8 +399,8 @@ class MediaGallery extends React.PureComponent {
|
|||
) {
|
||||
itemsDimensions = [
|
||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
||||
{ w: 50, h: `100%`, l: '2px', float: 'right' },
|
||||
{ w: 50, h: '50%', t: '2px', r: '2px' }
|
||||
{ w: 50, h: '100%', l: '2px', float: 'right' },
|
||||
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
||||
];
|
||||
} else if (
|
||||
(isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3)) ||
|
||||
|
@ -409,7 +409,7 @@ class MediaGallery extends React.PureComponent {
|
|||
itemsDimensions = [
|
||||
{ w: 50, h: panoSize_px, b: '2px', r: '2px' },
|
||||
{ w: 50, h: panoSize_px, b: '2px', l: '2px' },
|
||||
{ w: 100, h: `${width - panoSize}px`, t: '2px' }
|
||||
{ w: 100, h: `${width - panoSize}px`, t: '2px' },
|
||||
];
|
||||
} else if (
|
||||
(isNonConformingRatio(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) ||
|
||||
|
@ -424,7 +424,7 @@ class MediaGallery extends React.PureComponent {
|
|||
itemsDimensions = [
|
||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
||||
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
||||
{ w: 100, h: `50%`, t: '2px' }
|
||||
{ w: 100, h: '50%', t: '2px' },
|
||||
];
|
||||
}
|
||||
} else if (size == 4) {
|
||||
|
@ -471,7 +471,7 @@ class MediaGallery extends React.PureComponent {
|
|||
{ w: 67, h: '100%', r: '2px' },
|
||||
{ w: 33, h: '33%', b: '4px', l: '2px' },
|
||||
{ w: 33, h: '33%', l: '2px' },
|
||||
{ w: 33, h: '33%', t: '4px', l: '2px' }
|
||||
{ w: 33, h: '33%', t: '4px', l: '2px' },
|
||||
];
|
||||
} else {
|
||||
itemsDimensions = [
|
||||
|
|
|
@ -19,7 +19,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
},
|
||||
onCancelReplyCompose() {
|
||||
dispatch(cancelReplyCompose());
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
class ModalRoot extends React.PureComponent {
|
||||
|
@ -57,8 +57,7 @@ class ModalRoot extends React.PureComponent {
|
|||
onConfirm: () => onCancelReplyCompose(),
|
||||
onCancel: () => onOpenModal('COMPOSE'),
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.onClose();
|
||||
}
|
||||
};
|
||||
|
@ -124,6 +123,7 @@ class ModalRoot extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ModalRoot));
|
||||
|
|
|
@ -3,13 +3,15 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
|
||||
|
||||
export default class ProgressBar extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const { progress } = this.props;
|
||||
|
||||
return (
|
||||
<div className='progress-bar'>
|
||||
<div className='progress-bar__progress' style={{width: `${Math.floor(progress*100)}%`}}></div>
|
||||
<div className='progress-bar__progress' style={{ width: `${Math.floor(progress*100)}%` }} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -27,11 +27,11 @@ const messages = defineMessages({
|
|||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
|
||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||
lists: { id: 'column.lists', defaultMessage: 'Lists', },
|
||||
lists: { id: 'column.lists', defaultMessage: 'Lists' },
|
||||
apps: { id: 'tabs_bar.apps', defaultMessage: 'Apps' },
|
||||
news: { id: 'tabs_bar.news', defaultMessage: 'News' },
|
||||
donate: { id: 'donate', defaultMessage: 'Donate' },
|
||||
})
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const me = state.get('me');
|
||||
|
@ -92,7 +92,7 @@ class SidebarMenu extends ImmutablePureComponent {
|
|||
</Link>
|
||||
</div>
|
||||
<div className='sidebar-menu-profile__name'>
|
||||
<DisplayName account={account}/>
|
||||
<DisplayName account={account} />
|
||||
</div>
|
||||
|
||||
<div className='sidebar-menu-profile__stats'>
|
||||
|
@ -113,7 +113,7 @@ class SidebarMenu extends ImmutablePureComponent {
|
|||
<Icon id='user' />
|
||||
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.profile)}</span>
|
||||
</NavLink>
|
||||
<NavLink className='sidebar-menu-item' to={`/messages`} onClick={onClose}>
|
||||
<NavLink className='sidebar-menu-item' to={'/messages'} onClick={onClose}>
|
||||
<Icon id='envelope' />
|
||||
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.messages)}</span>
|
||||
</NavLink>
|
||||
|
|
|
@ -303,20 +303,22 @@ class Status extends ImmutablePureComponent {
|
|||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend-icon-wrapper'><Icon id='retweet' className='status__prepend-icon' fixedWidth /></div>
|
||||
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} reposted' values={{
|
||||
name: <NavLink to={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'>
|
||||
<bdi>
|
||||
<strong dangerouslySetInnerHTML={display_name_html} />
|
||||
</bdi>
|
||||
</NavLink>
|
||||
}} />
|
||||
<FormattedMessage
|
||||
id='status.reblogged_by' defaultMessage='{name} reposted' values={{
|
||||
name: <NavLink to={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'>
|
||||
<bdi>
|
||||
<strong dangerouslySetInnerHTML={display_name_html} />
|
||||
</bdi>
|
||||
</NavLink>,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
rebloggedByText = intl.formatMessage({ id: 'status.reblogged_by', defaultMessage: '{name} reposted' }, { name: status.getIn(['account', 'acct']) });
|
||||
|
||||
account = status.get('account');
|
||||
reblogContent = status.get('contentHtml')
|
||||
reblogContent = status.get('contentHtml');
|
||||
status = status.get('reblog');
|
||||
}
|
||||
|
||||
|
|
|
@ -298,6 +298,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
|
@ -314,4 +315,4 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
|
||||
export default injectIntl(
|
||||
connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true }
|
||||
)(StatusActionBar))
|
||||
)(StatusActionBar));
|
||||
|
|
|
@ -141,7 +141,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
<TimelineQueueButtonHeader key='timeline-queue-button-header' onClick={this.handleDequeueTimeline} count={totalQueuedItemsCount} itemType='post' />,
|
||||
<ScrollableList key='scrollable-list' {...other} isLoading={isLoading} showLoading={isLoading && statusIds.size === 0} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}>
|
||||
{scrollableContent}
|
||||
</ScrollableList>
|
||||
</ScrollableList>,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { shortNumberFormat } from '../utils/numbers';
|
|||
import classNames from 'classnames';
|
||||
|
||||
export default class TimelineQueueButtonHeader extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
count: PropTypes.number,
|
||||
|
@ -20,7 +21,7 @@ export default class TimelineQueueButtonHeader extends React.PureComponent {
|
|||
const { count, itemType, onClick } = this.props;
|
||||
|
||||
const classes = classNames('timeline-queue-header', {
|
||||
'hidden': (count <= 0)
|
||||
'hidden': (count <= 0),
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -38,4 +39,5 @@ export default class TimelineQueueButtonHeader extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ import React from 'react';
|
|||
import Icon from './icon';
|
||||
|
||||
const VerificationBadge = () => (
|
||||
<span className="verified-icon">
|
||||
<span className="visuallyhidden">Verified Account</span>
|
||||
<span className='verified-icon'>
|
||||
<span className='visuallyhidden'>Verified Account</span>
|
||||
</span>
|
||||
);
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ const mapStateToProps = (state) => {
|
|||
return {
|
||||
showIntroduction,
|
||||
me,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@connect(mapStateToProps)
|
||||
class GabSocialMount extends React.PureComponent {
|
||||
|
|
|
@ -31,7 +31,7 @@ import { boostModal, deleteModal } from '../initial_state';
|
|||
import { showAlertForError } from '../actions/alerts';
|
||||
import {
|
||||
createRemovedAccount,
|
||||
groupRemoveStatus
|
||||
groupRemoveStatus,
|
||||
} from '../actions/groups';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
|
|
@ -230,10 +230,10 @@ class Header extends ImmutablePureComponent {
|
|||
if (!account) {
|
||||
return (
|
||||
<div className='account__header'>
|
||||
<div className='account__header__image account__header__image--none'></div>
|
||||
<div className='account__header__image account__header__image--none' />
|
||||
<div className='account__header__bar'>
|
||||
<div className='account__header__extra'>
|
||||
<div className='account__header__avatar'></div>
|
||||
<div className='account__header__avatar' />
|
||||
</div>
|
||||
{
|
||||
isSmallScreen &&
|
||||
|
@ -296,15 +296,15 @@ class Header extends ImmutablePureComponent {
|
|||
{
|
||||
account.get('id') === me &&
|
||||
<div>
|
||||
<NavLink exact activeClassName='active' to={`/@${account.get('acct')}/favorites`}
|
||||
/* : TODO : title={intl.formatNumber(account.get('favourite_count'))} */
|
||||
<NavLink
|
||||
exact activeClassName='active' to={`/@${account.get('acct')}/favorites`}
|
||||
>
|
||||
{ /* : TODO : shortNumberFormat(account.get('favourite_count')) */ }
|
||||
<span>•</span>
|
||||
<FormattedMessage id='navigation_bar.favourites' defaultMessage='Favorites' />
|
||||
</NavLink>
|
||||
<NavLink exact activeClassName='active' to={`/@${account.get('acct')}/pins`}
|
||||
/* : TODO : title={intl.formatNumber(account.get('pinned_count'))} */
|
||||
<NavLink
|
||||
exact activeClassName='active' to={`/@${account.get('acct')}/pins`}
|
||||
>
|
||||
{ /* : TODO : shortNumberFormat(account.get('pinned_count')) */ }
|
||||
<span>•</span>
|
||||
|
@ -327,9 +327,11 @@ class Header extends ImmutablePureComponent {
|
|||
{actionBtn}
|
||||
{account.get('id') !== me &&
|
||||
<Button className='button button-alternative-2' onClick={this.props.onDirect}>
|
||||
<FormattedMessage id='account.message' defaultMessage='Message' values={{
|
||||
name: account.get('acct')
|
||||
}} />
|
||||
<FormattedMessage
|
||||
id='account.message' defaultMessage='Message' values={{
|
||||
name: account.get('acct'),
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
<DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
|
||||
|
|
|
@ -112,12 +112,12 @@ export default class MediaItem extends ImmutablePureComponent {
|
|||
/>
|
||||
);
|
||||
} else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
|
||||
let conditionalAttributes = {}
|
||||
let conditionalAttributes = {};
|
||||
if (isIOS()) {
|
||||
conditionalAttributes.playsInline = '1'
|
||||
conditionalAttributes.playsInline = '1';
|
||||
}
|
||||
if (autoPlayGif) {
|
||||
conditionalAttributes.autoPlay = '1'
|
||||
conditionalAttributes.autoPlay = '1';
|
||||
}
|
||||
thumbnail = (
|
||||
<div className={classNames('media-gallery__gifv', { autoplay: autoPlayGif })}>
|
||||
|
|
|
@ -27,8 +27,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
let accountUsername = username;
|
||||
if (accountFetchError) {
|
||||
accountId = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
|
||||
accountId = account ? account.getIn(['id'], null) : -1;
|
||||
accountUsername = account ? account.getIn(['acct'], '') : '';
|
||||
|
@ -69,6 +68,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
|
@ -94,8 +94,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
if (accountId && accountId !== -1) {
|
||||
this.props.dispatch(fetchAccount(accountId));
|
||||
this.props.dispatch(expandAccountMediaTimeline(accountId));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.dispatch(fetchAccountByUsername(username));
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +189,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
<Column>
|
||||
<div className='slist slist--flex' onScroll={this.handleScroll}>
|
||||
<div className='account__section-headline'>
|
||||
<div style={{width: '100%', display: 'flex'}}>
|
||||
<div style={{ width: '100%', display: 'flex' }}>
|
||||
<NavLink exact to={`/@${accountUsername}`}>
|
||||
<FormattedMessage id='account.posts' defaultMessage='Posts' />
|
||||
</NavLink>
|
||||
|
@ -213,7 +212,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
{
|
||||
attachments.size == 0 &&
|
||||
<div className='empty-column-indicator'>
|
||||
<FormattedMessage id='account_gallery.none' defaultMessage='No media to show.'/>
|
||||
<FormattedMessage id='account_gallery.none' defaultMessage='No media to show.' />
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
let accountUsername = username;
|
||||
if (accountFetchError) {
|
||||
accountId = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
|
||||
accountId = account ? account.getIn(['id'], null) : -1;
|
||||
accountUsername = account ? account.getIn(['acct'], '') : '';
|
||||
|
@ -79,8 +78,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
this.props.dispatch(expandAccountTimeline(accountId, { withReplies }));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.dispatch(fetchAccountByUsername(username));
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +135,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
|||
return (
|
||||
<Column>
|
||||
<div className='account__section-headline'>
|
||||
<div style={{width: '100%', display: 'flex'}}>
|
||||
<div style={{ width: '100%', display: 'flex' }}>
|
||||
<NavLink exact to={`/@${accountUsername}`}>
|
||||
<FormattedMessage id='account.posts' defaultMessage='Posts' />
|
||||
</NavLink>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux'
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { createAuthApp, logIn } from 'gabsocial/actions/auth';
|
||||
import { fetchMe } from 'gabsocial/actions/me';
|
||||
|
@ -7,9 +7,10 @@ import { Link } from 'react-router-dom';
|
|||
|
||||
export default @connect()
|
||||
class LoginForm extends ImmutablePureComponent {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {isLoading: false};
|
||||
this.state = { isLoading: false };
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
|
@ -28,9 +29,9 @@ class LoginForm extends ImmutablePureComponent {
|
|||
dispatch(logIn(username, password)).then(() => {
|
||||
return dispatch(fetchMe());
|
||||
}).catch((error) => {
|
||||
this.setState({isLoading: false});
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
this.setState({isLoading: true});
|
||||
this.setState({ isLoading: true });
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
@ -52,6 +53,7 @@ class LoginForm extends ImmutablePureComponent {
|
|||
<button name='button' type='submit' className='btn button button-primary'>Log in</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux'
|
||||
import { connect } from 'react-redux';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import LoginForm from './login_form';
|
||||
|
@ -10,10 +10,12 @@ const mapStateToProps = state => ({
|
|||
|
||||
export default @connect(mapStateToProps)
|
||||
class LoginPage extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const { me } = this.props;
|
||||
if (me) return <Redirect to='/' />;
|
||||
|
||||
return <LoginForm />
|
||||
return <LoginForm />;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class ActionBar extends React.PureComponent {
|
|||
let menu = [];
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.profile), to: `/@${meUsername}` });
|
||||
menu.push({ text: intl.formatMessage(messages.messages), to: `/messages` });
|
||||
menu.push({ text: intl.formatMessage(messages.messages), to: '/messages' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
|
||||
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
|
||||
|
@ -62,13 +62,14 @@ class ActionBar extends React.PureComponent {
|
|||
menu.push({ text: intl.formatMessage(messages.logout), to: '/auth/sign_out', action: onClickLogOut });
|
||||
|
||||
return (
|
||||
<div className='compose__action-bar' style={{'marginTop':'-6px'}}>
|
||||
<div className='compose__action-bar' style={{ 'marginTop':'-6px' }}>
|
||||
<div className='compose__action-bar-dropdown'>
|
||||
<DropdownMenuContainer items={menu} icon='chevron-down' size={size} direction='right' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(null, mapDispatchToProps)(ActionBar));
|
||||
|
|
|
@ -26,7 +26,7 @@ import Icon from 'gabsocial/components/icon';
|
|||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: "What's on your mind?" },
|
||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What\'s on your mind?' },
|
||||
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
|
||||
publish: { id: 'compose_form.publish', defaultMessage: 'Publish' },
|
||||
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
|
||||
|
@ -151,11 +151,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener("click", this.handleClick, false);
|
||||
document.addEventListener('click', this.handleClick, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener("click", this.handleClick, false);
|
||||
document.removeEventListener('click', this.handleClick, false);
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
|
@ -211,7 +211,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
const disabled = this.props.isSubmitting;
|
||||
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
|
||||
const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > maxTootChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
|
||||
const shouldAutoFocus = autoFocus && !showSearch && !isMobile(window.innerWidth)
|
||||
const shouldAutoFocus = autoFocus && !showSearch && !isMobile(window.innerWidth);
|
||||
|
||||
let publishText = '';
|
||||
|
||||
|
@ -224,7 +224,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
const composeClassNames = classNames({
|
||||
'compose-form': true,
|
||||
'condensed': condensed,
|
||||
})
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={composeClassNames} ref={this.setForm} onClick={this.handleClick}>
|
||||
|
|
|
@ -67,8 +67,8 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
return Object.assign({}, ownProps, {
|
||||
...stateProps,
|
||||
...dispatchProps
|
||||
})
|
||||
...dispatchProps,
|
||||
});
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(ComposeForm);
|
||||
|
|
|
@ -12,7 +12,7 @@ const mapStateToProps = state => {
|
|||
needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']),
|
||||
hashtagWarning: state.getIn(['compose', 'privacy']) !== 'public' && APPROX_HASHTAG_RE.test(state.getIn(['compose', 'text'])),
|
||||
directMessageWarning: state.getIn(['compose', 'privacy']) === 'direct',
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning }) => {
|
||||
|
|
|
@ -26,8 +26,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
let accountUsername = username;
|
||||
if (accountFetchError) {
|
||||
accountId = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
|
||||
accountId = account ? account.getIn(['id'], null) : -1;
|
||||
}
|
||||
|
@ -64,8 +63,7 @@ class Followers extends ImmutablePureComponent {
|
|||
if (accountId && accountId !== -1) {
|
||||
this.props.dispatch(fetchAccount(accountId));
|
||||
this.props.dispatch(fetchFollowers(accountId));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.dispatch(fetchAccountByUsername(username));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
let accountId = -1;
|
||||
if (accountFetchError) {
|
||||
accountId = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
|
||||
accountId = account ? account.getIn(['id'], null) : -1;
|
||||
}
|
||||
|
@ -64,8 +63,7 @@ class Following extends ImmutablePureComponent {
|
|||
if (accountId && accountId !== -1) {
|
||||
this.props.dispatch(fetchAccount(accountId));
|
||||
this.props.dispatch(fetchFollowing(accountId));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.dispatch(fetchAccountByUsername(username));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ const mapStateToProps = state => {
|
|||
return {
|
||||
myAccount: state.getIn(['accounts', me]),
|
||||
unreadFollowRequests: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
|
|
@ -7,26 +7,26 @@ import { defineMessages, injectIntl } from 'react-intl';
|
|||
import classNames from 'classnames';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'groups.form.title', defaultMessage: 'Enter a new group title' },
|
||||
description: { id: 'groups.form.description', defaultMessage: 'Enter the group description' },
|
||||
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload a banner image' },
|
||||
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
|
||||
create: { id: 'groups.form.create', defaultMessage: 'Create group' },
|
||||
title: { id: 'groups.form.title', defaultMessage: 'Enter a new group title' },
|
||||
description: { id: 'groups.form.description', defaultMessage: 'Enter the group description' },
|
||||
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload a banner image' },
|
||||
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
|
||||
create: { id: 'groups.form.create', defaultMessage: 'Create group' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
title: state.getIn(['group_editor', 'title']),
|
||||
description: state.getIn(['group_editor', 'description']),
|
||||
coverImage: state.getIn(['group_editor', 'coverImage']),
|
||||
disabled: state.getIn(['group_editor', 'isSubmitting']),
|
||||
title: state.getIn(['group_editor', 'title']),
|
||||
description: state.getIn(['group_editor', 'description']),
|
||||
coverImage: state.getIn(['group_editor', 'coverImage']),
|
||||
disabled: state.getIn(['group_editor', 'isSubmitting']),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onTitleChange: value => dispatch(changeValue('title', value)),
|
||||
onDescriptionChange: value => dispatch(changeValue('description', value)),
|
||||
onCoverImageChange: value => dispatch(changeValue('coverImage', value)),
|
||||
onSubmit: routerHistory => dispatch(submit(routerHistory)),
|
||||
reset: () => dispatch(reset()),
|
||||
onTitleChange: value => dispatch(changeValue('title', value)),
|
||||
onDescriptionChange: value => dispatch(changeValue('description', value)),
|
||||
onCoverImageChange: value => dispatch(changeValue('coverImage', value)),
|
||||
onSubmit: routerHistory => dispatch(submit(routerHistory)),
|
||||
reset: () => dispatch(reset()),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps, mapDispatchToProps)
|
||||
|
@ -34,80 +34,80 @@ export default @connect(mapStateToProps, mapDispatchToProps)
|
|||
class Create extends React.PureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object
|
||||
router: PropTypes.object,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
coverImage: PropTypes.object,
|
||||
disabled: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onTitleChange: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
coverImage: PropTypes.object,
|
||||
disabled: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onTitleChange: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
this.props.reset();
|
||||
this.props.reset();
|
||||
}
|
||||
|
||||
handleTitleChange = e => {
|
||||
this.props.onTitleChange(e.target.value);
|
||||
this.props.onTitleChange(e.target.value);
|
||||
}
|
||||
|
||||
handleDescriptionChange = e => {
|
||||
this.props.onDescriptionChange(e.target.value);
|
||||
this.props.onDescriptionChange(e.target.value);
|
||||
}
|
||||
|
||||
handleCoverImageChange = e => {
|
||||
this.props.onCoverImageChange(e.target.files[0]);
|
||||
this.props.onCoverImageChange(e.target.files[0]);
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
e.preventDefault();
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { title, description, coverImage, disabled, intl } = this.props;
|
||||
const { title, description, coverImage, disabled, intl } = this.props;
|
||||
|
||||
return (
|
||||
<form className='group-form' onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
className='standard'
|
||||
type='text'
|
||||
value={title}
|
||||
disabled={disabled}
|
||||
onChange={this.handleTitleChange}
|
||||
placeholder={intl.formatMessage(messages.title)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<textarea
|
||||
className='standard'
|
||||
type='text'
|
||||
value={description}
|
||||
disabled={disabled}
|
||||
onChange={this.handleDescriptionChange}
|
||||
placeholder={intl.formatMessage(messages.description)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
|
||||
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
|
||||
</label>
|
||||
<input
|
||||
type='file'
|
||||
className='group-form__file'
|
||||
id='group_cover_image'
|
||||
disabled={disabled}
|
||||
onChange={this.handleCoverImageChange}
|
||||
/>
|
||||
<button className='standard-small'>{intl.formatMessage(messages.create)}</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
return (
|
||||
<form className='group-form' onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
className='standard'
|
||||
type='text'
|
||||
value={title}
|
||||
disabled={disabled}
|
||||
onChange={this.handleTitleChange}
|
||||
placeholder={intl.formatMessage(messages.title)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<textarea
|
||||
className='standard'
|
||||
type='text'
|
||||
value={description}
|
||||
disabled={disabled}
|
||||
onChange={this.handleDescriptionChange}
|
||||
placeholder={intl.formatMessage(messages.description)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
|
||||
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
|
||||
</label>
|
||||
<input
|
||||
type='file'
|
||||
className='group-form__file'
|
||||
id='group_cover_image'
|
||||
disabled={disabled}
|
||||
onChange={this.handleCoverImageChange}
|
||||
/>
|
||||
<button className='standard-small'>{intl.formatMessage(messages.create)}</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,27 +10,27 @@ import Column from '../../../components/column';
|
|||
import classNames from 'classnames';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'groups.form.title', defaultMessage: 'Title' },
|
||||
description: { id: 'groups.form.description', defaultMessage: 'Description' },
|
||||
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload new banner image (optional)' },
|
||||
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
|
||||
update: { id: 'groups.form.update', defaultMessage: 'Update group' },
|
||||
title: { id: 'groups.form.title', defaultMessage: 'Title' },
|
||||
description: { id: 'groups.form.description', defaultMessage: 'Description' },
|
||||
coverImage: { id: 'groups.form.coverImage', defaultMessage: 'Upload new banner image (optional)' },
|
||||
coverImageChange: { id: 'groups.form.coverImageChange', defaultMessage: 'Banner image selected' },
|
||||
update: { id: 'groups.form.update', defaultMessage: 'Update group' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
group: state.getIn(['groups', props.params.id]),
|
||||
title: state.getIn(['group_editor', 'title']),
|
||||
description: state.getIn(['group_editor', 'description']),
|
||||
coverImage: state.getIn(['group_editor', 'coverImage']),
|
||||
disabled: state.getIn(['group_editor', 'isSubmitting']),
|
||||
group: state.getIn(['groups', props.params.id]),
|
||||
title: state.getIn(['group_editor', 'title']),
|
||||
description: state.getIn(['group_editor', 'description']),
|
||||
coverImage: state.getIn(['group_editor', 'coverImage']),
|
||||
disabled: state.getIn(['group_editor', 'isSubmitting']),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onTitleChange: value => dispatch(changeValue('title', value)),
|
||||
onDescriptionChange: value => dispatch(changeValue('description', value)),
|
||||
onCoverImageChange: value => dispatch(changeValue('coverImage', value)),
|
||||
onSubmit: routerHistory => dispatch(submit(routerHistory)),
|
||||
setUp: group => dispatch(setUp(group)),
|
||||
onTitleChange: value => dispatch(changeValue('title', value)),
|
||||
onDescriptionChange: value => dispatch(changeValue('description', value)),
|
||||
onCoverImageChange: value => dispatch(changeValue('coverImage', value)),
|
||||
onSubmit: routerHistory => dispatch(submit(routerHistory)),
|
||||
setUp: group => dispatch(setUp(group)),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps, mapDispatchToProps)
|
||||
|
@ -38,111 +38,111 @@ export default @connect(mapStateToProps, mapDispatchToProps)
|
|||
class Edit extends React.PureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object
|
||||
router: PropTypes.object,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
coverImage: PropTypes.object,
|
||||
disabled: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onTitleChange: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
group: ImmutablePropTypes.map,
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
coverImage: PropTypes.object,
|
||||
disabled: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onTitleChange: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
componentWillMount(nextProps) {
|
||||
if (this.props.group) {
|
||||
this.props.setUp(this.props.group);
|
||||
}
|
||||
componentWillMount(nextProps) {
|
||||
if (this.props.group) {
|
||||
this.props.setUp(this.props.group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!this.props.group && nextProps.group) {
|
||||
this.props.setUp(nextProps.group);
|
||||
}
|
||||
if (!this.props.group && nextProps.group) {
|
||||
this.props.setUp(nextProps.group);
|
||||
}
|
||||
}
|
||||
|
||||
handleTitleChange = e => {
|
||||
this.props.onTitleChange(e.target.value);
|
||||
this.props.onTitleChange(e.target.value);
|
||||
}
|
||||
|
||||
handleDescriptionChange = e => {
|
||||
this.props.onDescriptionChange(e.target.value);
|
||||
this.props.onDescriptionChange(e.target.value);
|
||||
}
|
||||
|
||||
handleCoverImageChange = e => {
|
||||
this.props.onCoverImageChange(e.target.files[0]);
|
||||
this.props.onCoverImageChange(e.target.files[0]);
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
e.preventDefault();
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
this.props.onSubmit(this.context.router.history);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { group, title, description, coverImage, disabled, intl } = this.props;
|
||||
|
||||
if (typeof group === 'undefined') {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
} else if (group === false) {
|
||||
return (
|
||||
<Column>
|
||||
<MissingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
const { group, title, description, coverImage, disabled, intl } = this.props;
|
||||
|
||||
return (
|
||||
<form className='group-form' onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
className='standard'
|
||||
type='text'
|
||||
value={title}
|
||||
disabled={disabled}
|
||||
onChange={this.handleTitleChange}
|
||||
placeholder={intl.formatMessage(messages.title)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
className='standard'
|
||||
type='text'
|
||||
value={description}
|
||||
disabled={disabled}
|
||||
onChange={this.handleDescriptionChange}
|
||||
placeholder={intl.formatMessage(messages.description)}
|
||||
/>
|
||||
</div>
|
||||
if (typeof group === 'undefined') {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
} else if (group === false) {
|
||||
return (
|
||||
<Column>
|
||||
<MissingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
<div>
|
||||
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
|
||||
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
|
||||
</label>
|
||||
|
||||
<input
|
||||
type='file'
|
||||
className='group-form__file'
|
||||
id='group_cover_image'
|
||||
disabled={disabled}
|
||||
onChange={this.handleCoverImageChange}
|
||||
/>
|
||||
return (
|
||||
<form className='group-form' onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
className='standard'
|
||||
type='text'
|
||||
value={title}
|
||||
disabled={disabled}
|
||||
onChange={this.handleTitleChange}
|
||||
placeholder={intl.formatMessage(messages.title)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button>{intl.formatMessage(messages.update)}</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
<div>
|
||||
<textarea
|
||||
className='standard'
|
||||
type='text'
|
||||
value={description}
|
||||
disabled={disabled}
|
||||
onChange={this.handleDescriptionChange}
|
||||
placeholder={intl.formatMessage(messages.description)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
|
||||
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
|
||||
</label>
|
||||
|
||||
<input
|
||||
type='file'
|
||||
className='group-form__file'
|
||||
id='group_cover_image'
|
||||
disabled={disabled}
|
||||
onChange={this.handleCoverImageChange}
|
||||
/>
|
||||
|
||||
<button>{intl.formatMessage(messages.update)}</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,48 +7,50 @@ import { shortNumberFormat } from '../../../utils/numbers';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
const messages = defineMessages({
|
||||
members: { id: 'groups.card.members', defaultMessage: 'Members' },
|
||||
view: { id: 'groups.card.view', defaultMessage: 'View' },
|
||||
join: { id: 'groups.card.join', defaultMessage: 'Join' },
|
||||
role_member: { id: 'groups.card.roles.member', defaultMessage: 'You\'re a member' },
|
||||
role_admin: { id: 'groups.card.roles.admin', defaultMessage: 'You\'re an admin' },
|
||||
members: { id: 'groups.card.members', defaultMessage: 'Members' },
|
||||
view: { id: 'groups.card.view', defaultMessage: 'View' },
|
||||
join: { id: 'groups.card.join', defaultMessage: 'Join' },
|
||||
role_member: { id: 'groups.card.roles.member', defaultMessage: 'You\'re a member' },
|
||||
role_admin: { id: 'groups.card.roles.admin', defaultMessage: 'You\'re an admin' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { id }) => ({
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class GroupCard extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
}
|
||||
|
||||
getRole() {
|
||||
const { intl, relationships } = this.props;
|
||||
const { intl, relationships } = this.props;
|
||||
|
||||
if (!relationships) return null;
|
||||
if (relationships.get('admin')) return intl.formatMessage(messages.role_admin);
|
||||
if (relationships.get('member')) return intl.formatMessage(messages.role_member);
|
||||
if (!relationships) return null;
|
||||
if (relationships.get('admin')) return intl.formatMessage(messages.role_admin);
|
||||
if (relationships.get('member')) return intl.formatMessage(messages.role_member);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, group } = this.props;
|
||||
const coverImageUrl = group.get('cover_image_url');
|
||||
const role = this.getRole();
|
||||
const { intl, group } = this.props;
|
||||
const coverImageUrl = group.get('cover_image_url');
|
||||
const role = this.getRole();
|
||||
|
||||
return (
|
||||
<Link to={`/groups/${group.get('id')}`} className="group-card">
|
||||
<div className="group-card__header">{coverImageUrl && <img alt="" src={coverImageUrl} />}</div>
|
||||
<div className="group-card__content">
|
||||
<div className="group-card__title">{group.get('title')}</div>
|
||||
<div className="group-card__meta"><strong>{shortNumberFormat(group.get('member_count'))}</strong> {intl.formatMessage(messages.members)}{role && <span> · {role}</span>}</div>
|
||||
<div className="group-card__description">{group.get('description')}</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
<Link to={`/groups/${group.get('id')}`} className='group-card'>
|
||||
<div className='group-card__header'>{coverImageUrl && <img alt='' src={coverImageUrl} />}</div>
|
||||
<div className='group-card__content'>
|
||||
<div className='group-card__title'>{group.get('title')}</div>
|
||||
<div className='group-card__meta'><strong>{shortNumberFormat(group.get('member_count'))}</strong> {intl.formatMessage(messages.members)}{role && <span> · {role}</span>}</div>
|
||||
<div className='group-card__description'>{group.get('description')}</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -11,79 +11,81 @@ import GroupCard from './card';
|
|||
import GroupCreate from '../create';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.groups', defaultMessage: 'Groups' },
|
||||
create: { id: 'groups.create', defaultMessage: 'Create group' },
|
||||
tab_featured: { id: 'groups.tab_featured', defaultMessage: 'Featured' },
|
||||
tab_member: { id: 'groups.tab_member', defaultMessage: 'Member' },
|
||||
tab_admin: { id: 'groups.tab_admin', defaultMessage: 'Manage' },
|
||||
heading: { id: 'column.groups', defaultMessage: 'Groups' },
|
||||
create: { id: 'groups.create', defaultMessage: 'Create group' },
|
||||
tab_featured: { id: 'groups.tab_featured', defaultMessage: 'Featured' },
|
||||
tab_member: { id: 'groups.tab_member', defaultMessage: 'Member' },
|
||||
tab_admin: { id: 'groups.tab_admin', defaultMessage: 'Manage' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { activeTab }) => ({
|
||||
groupIds: state.getIn(['group_lists', activeTab]),
|
||||
groupIds: state.getIn(['group_lists', activeTab]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class Groups extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
activeTab: PropTypes.string.isRequired,
|
||||
showCreateForm: PropTypes.bool,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
groups: ImmutablePropTypes.map,
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
intl: PropTypes.object.isRequired,
|
||||
params: PropTypes.object.isRequired,
|
||||
activeTab: PropTypes.string.isRequired,
|
||||
showCreateForm: PropTypes.bool,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
groups: ImmutablePropTypes.map,
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
this.props.dispatch(fetchGroups(this.props.activeTab));
|
||||
this.props.dispatch(fetchGroups(this.props.activeTab));
|
||||
}
|
||||
|
||||
componentDidUpdate(oldProps) {
|
||||
if (this.props.activeTab && this.props.activeTab !== oldProps.activeTab) {
|
||||
this.props.dispatch(fetchGroups(this.props.activeTab));
|
||||
}
|
||||
if (this.props.activeTab && this.props.activeTab !== oldProps.activeTab) {
|
||||
this.props.dispatch(fetchGroups(this.props.activeTab));
|
||||
}
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
const { intl, activeTab } = this.props;
|
||||
const { intl, activeTab } = this.props;
|
||||
|
||||
return (
|
||||
<div className="group-column-header">
|
||||
<div className="group-column-header__cta"><Link to="/groups/create" className="button standard-small">{intl.formatMessage(messages.create)}</Link></div>
|
||||
<div className="group-column-header__title">{intl.formatMessage(messages.heading)}</div>
|
||||
return (
|
||||
<div className='group-column-header'>
|
||||
<div className='group-column-header__cta'><Link to='/groups/create' className='button standard-small'>{intl.formatMessage(messages.create)}</Link></div>
|
||||
<div className='group-column-header__title'>{intl.formatMessage(messages.heading)}</div>
|
||||
|
||||
<div className="column-header__wrapper">
|
||||
<h1 className="column-header">
|
||||
<Link to='/groups' className={classNames('btn grouped', {'active': 'featured' === activeTab})}>
|
||||
{intl.formatMessage(messages.tab_featured)}
|
||||
</Link>
|
||||
<div className='column-header__wrapper'>
|
||||
<h1 className='column-header'>
|
||||
<Link to='/groups' className={classNames('btn grouped', { 'active': 'featured' === activeTab })}>
|
||||
{intl.formatMessage(messages.tab_featured)}
|
||||
</Link>
|
||||
|
||||
<Link to='/groups/browse/member' className={classNames('btn grouped', {'active': 'member' === activeTab})}>
|
||||
{intl.formatMessage(messages.tab_member)}
|
||||
</Link>
|
||||
<Link to='/groups/browse/member' className={classNames('btn grouped', { 'active': 'member' === activeTab })}>
|
||||
{intl.formatMessage(messages.tab_member)}
|
||||
</Link>
|
||||
|
||||
<Link to='/groups/browse/admin' className={classNames('btn grouped', {'active': 'admin' === activeTab})}>
|
||||
{intl.formatMessage(messages.tab_admin)}
|
||||
</Link>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<Link to='/groups/browse/admin' className={classNames('btn grouped', { 'active': 'admin' === activeTab })}>
|
||||
{intl.formatMessage(messages.tab_admin)}
|
||||
</Link>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { groupIds, showCreateForm } = this.props;
|
||||
const { groupIds, showCreateForm } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{!showCreateForm && this.renderHeader()}
|
||||
{showCreateForm && <GroupCreate /> }
|
||||
return (
|
||||
<div>
|
||||
{!showCreateForm && this.renderHeader()}
|
||||
{showCreateForm && <GroupCreate /> }
|
||||
|
||||
<div className="group-card-list">
|
||||
{groupIds.map(id => <GroupCard key={id} id={id} />)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div className='group-card-list'>
|
||||
{groupIds.map(id => <GroupCard key={id} id={id} />)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import { debounce } from 'lodash';
|
||||
import LoadingIndicator from '../../../components/loading_indicator';
|
||||
import {
|
||||
fetchMembers,
|
||||
expandMembers,
|
||||
fetchMembers,
|
||||
expandMembers,
|
||||
} from '../../../actions/groups';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import AccountContainer from '../../../containers/account_container';
|
||||
|
@ -15,59 +15,60 @@ import Column from '../../ui/components/column';
|
|||
import ScrollableList from '../../../components/scrollable_list';
|
||||
|
||||
const mapStateToProps = (state, { params: { id } }) => ({
|
||||
group: state.getIn(['groups', id]),
|
||||
accountIds: state.getIn(['user_lists', 'groups', id, 'items']),
|
||||
hasMore: !!state.getIn(['user_lists', 'groups', id, 'next']),
|
||||
group: state.getIn(['groups', id]),
|
||||
accountIds: state.getIn(['user_lists', 'groups', id, 'items']),
|
||||
hasMore: !!state.getIn(['user_lists', 'groups', id, 'next']),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class GroupMembers extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
accountIds: ImmutablePropTypes.list,
|
||||
hasMore: PropTypes.bool,
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
accountIds: ImmutablePropTypes.list,
|
||||
hasMore: PropTypes.bool,
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { params: { id } } = this.props;
|
||||
const { params: { id } } = this.props;
|
||||
|
||||
this.props.dispatch(fetchMembers(id));
|
||||
this.props.dispatch(fetchMembers(id));
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.props.dispatch(fetchMembers(nextProps.params.id));
|
||||
}
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.props.dispatch(fetchMembers(nextProps.params.id));
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMore = debounce(() => {
|
||||
this.props.dispatch(expandMembers(this.props.params.id));
|
||||
this.props.dispatch(expandMembers(this.props.params.id));
|
||||
}, 300, { leading: true });
|
||||
|
||||
render () {
|
||||
const { accountIds, hasMore, group } = this.props;
|
||||
const { accountIds, hasMore, group } = this.props;
|
||||
|
||||
if (!group || !accountIds) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
if (!group || !accountIds) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Column>
|
||||
<ScrollableList
|
||||
scrollKey='members'
|
||||
hasMore={hasMore}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='group.members.empty' defaultMessage='This group does not has any members.' />}
|
||||
>
|
||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||
</ScrollableList>
|
||||
</Column>
|
||||
);
|
||||
return (
|
||||
<Column>
|
||||
<ScrollableList
|
||||
scrollKey='members'
|
||||
hasMore={hasMore}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='group.members.empty' defaultMessage='This group does not has any members.' />}
|
||||
>
|
||||
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
|
||||
</ScrollableList>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import { debounce } from 'lodash';
|
||||
import LoadingIndicator from '../../../components/loading_indicator';
|
||||
import {
|
||||
fetchRemovedAccounts,
|
||||
expandRemovedAccounts,
|
||||
removeRemovedAccount,
|
||||
fetchRemovedAccounts,
|
||||
expandRemovedAccounts,
|
||||
removeRemovedAccount,
|
||||
} from '../../../actions/groups';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import AccountContainer from '../../../containers/account_container';
|
||||
|
@ -17,13 +17,13 @@ import ScrollableList from '../../../components/scrollable_list';
|
|||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
remove: { id: 'groups.removed_accounts', defaultMessage: 'Allow joining' },
|
||||
remove: { id: 'groups.removed_accounts', defaultMessage: 'Allow joining' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { params: { id } }) => ({
|
||||
group: state.getIn(['groups', id]),
|
||||
accountIds: state.getIn(['user_lists', 'groups_removed_accounts', id, 'items']),
|
||||
hasMore: !!state.getIn(['user_lists', 'groups_removed_accounts', id, 'next']),
|
||||
group: state.getIn(['groups', id]),
|
||||
accountIds: state.getIn(['user_lists', 'groups_removed_accounts', id, 'items']),
|
||||
hasMore: !!state.getIn(['user_lists', 'groups_removed_accounts', id, 'next']),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
|
@ -31,56 +31,57 @@ export default @connect(mapStateToProps)
|
|||
class GroupRemovedAccounts extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
accountIds: ImmutablePropTypes.list,
|
||||
hasMore: PropTypes.bool,
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
accountIds: ImmutablePropTypes.list,
|
||||
hasMore: PropTypes.bool,
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { params: { id } } = this.props;
|
||||
const { params: { id } } = this.props;
|
||||
|
||||
this.props.dispatch(fetchRemovedAccounts(id));
|
||||
this.props.dispatch(fetchRemovedAccounts(id));
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.props.dispatch(fetchRemovedAccounts(nextProps.params.id));
|
||||
}
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.props.dispatch(fetchRemovedAccounts(nextProps.params.id));
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMore = debounce(() => {
|
||||
this.props.dispatch(expandRemovedAccounts(this.props.params.id));
|
||||
this.props.dispatch(expandRemovedAccounts(this.props.params.id));
|
||||
}, 300, { leading: true });
|
||||
|
||||
render () {
|
||||
const { accountIds, hasMore, group, intl } = this.props;
|
||||
const { accountIds, hasMore, group, intl } = this.props;
|
||||
|
||||
if (!group || !accountIds) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
if (!group || !accountIds) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Column>
|
||||
<ScrollableList
|
||||
scrollKey='removed_accounts'
|
||||
hasMore={hasMore}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='group.removed_accounts.empty' defaultMessage='This group does not has any removed accounts.' />}
|
||||
>
|
||||
{accountIds.map(id => <AccountContainer
|
||||
key={id}
|
||||
id={id}
|
||||
actionIcon="remove"
|
||||
onActionClick={() => this.props.dispatch(removeRemovedAccount(group.get('id'), id))}
|
||||
actionTitle={intl.formatMessage(messages.remove)}
|
||||
/>)}
|
||||
</ScrollableList>
|
||||
</Column>
|
||||
);
|
||||
return (
|
||||
<Column>
|
||||
<ScrollableList
|
||||
scrollKey='removed_accounts'
|
||||
hasMore={hasMore}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='group.removed_accounts.empty' defaultMessage='This group does not has any removed accounts.' />}
|
||||
>
|
||||
{accountIds.map(id => (<AccountContainer
|
||||
key={id}
|
||||
id={id}
|
||||
actionIcon='remove'
|
||||
onActionClick={() => this.props.dispatch(removeRemovedAccount(group.get('id'), id))}
|
||||
actionTitle={intl.formatMessage(messages.remove)}
|
||||
/>))}
|
||||
</ScrollableList>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,42 +8,44 @@ import Icon from 'gabsocial/components/icon';
|
|||
import { Link } from 'react-router-dom';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'groups.sidebar-panel.title', defaultMessage: 'Groups You\'re In' },
|
||||
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
|
||||
title: { id: 'groups.sidebar-panel.title', defaultMessage: 'Groups You\'re In' },
|
||||
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { id }) => ({
|
||||
groupIds: state.getIn(['group_lists', 'member']),
|
||||
groupIds: state.getIn(['group_lists', 'member']),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class GroupSidebarPanel extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
groupIds: ImmutablePropTypes.list,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, groupIds } = this.props;
|
||||
const count = groupIds.count();
|
||||
const { intl, groupIds } = this.props;
|
||||
const count = groupIds.count();
|
||||
|
||||
// Only when there are groups to show
|
||||
if (count === 0) return null;
|
||||
// Only when there are groups to show
|
||||
if (count === 0) return null;
|
||||
|
||||
return (
|
||||
<div className='wtf-panel group-sidebar-panel'>
|
||||
<div className='wtf-panel-header'>
|
||||
<Icon id='users' className='wtf-panel-header__icon' />
|
||||
<span className='wtf-panel-header__label'>{intl.formatMessage(messages.title)}</span>
|
||||
</div>
|
||||
return (
|
||||
<div className='wtf-panel group-sidebar-panel'>
|
||||
<div className='wtf-panel-header'>
|
||||
<Icon id='users' className='wtf-panel-header__icon' />
|
||||
<span className='wtf-panel-header__label'>{intl.formatMessage(messages.title)}</span>
|
||||
</div>
|
||||
|
||||
<div className='wtf-panel__content'>
|
||||
<div className="group-sidebar-panel__items">
|
||||
{groupIds.slice(0, 10).map(groupId => <Item key={groupId} id={groupId} />)}
|
||||
{count > 10 && <Link className="group-sidebar-panel__items__show-all" to='/groups/browse/member'>{intl.formatMessage(messages.show_all)}</Link>}
|
||||
</div>
|
||||
</div>
|
||||
<div className='wtf-panel__content'>
|
||||
<div className='group-sidebar-panel__items'>
|
||||
{groupIds.slice(0, 10).map(groupId => <Item key={groupId} id={groupId} />)}
|
||||
{count > 10 && <Link className='group-sidebar-panel__items__show-all' to='/groups/browse/member'>{intl.formatMessage(messages.show_all)}</Link>}
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,39 +7,41 @@ import { shortNumberFormat } from '../../../utils/numbers';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
const messages = defineMessages({
|
||||
new_statuses: { id: 'groups.sidebar-panel.item.view', defaultMessage: 'new posts' },
|
||||
no_recent_activity: { id: 'groups.sidebar-panel.item.no_recent_activity', defaultMessage: 'No recent activity' },
|
||||
new_statuses: { id: 'groups.sidebar-panel.item.view', defaultMessage: 'new posts' },
|
||||
no_recent_activity: { id: 'groups.sidebar-panel.item.no_recent_activity', defaultMessage: 'No recent activity' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { id }) => ({
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class Item extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, group, relationships } = this.props;
|
||||
const { intl, group, relationships } = this.props;
|
||||
|
||||
// Wait for relationships
|
||||
if (!relationships) return null;
|
||||
// Wait for relationships
|
||||
if (!relationships) return null;
|
||||
|
||||
const unreadCount = relationships.get('unread_count');
|
||||
const unreadCount = relationships.get('unread_count');
|
||||
|
||||
return (
|
||||
<Link to={`/groups/${group.get('id')}`} className="group-sidebar-panel__item">
|
||||
<div className="group-sidebar-panel__item__title">{group.get('title')}</div>
|
||||
<div className="group-sidebar-panel__item__meta">
|
||||
{unreadCount > 0 && <span className="group-sidebar-panel__item__meta__unread">{shortNumberFormat(unreadCount)} {intl.formatMessage(messages.new_statuses)}</span>}
|
||||
{unreadCount === 0 && <span>{intl.formatMessage(messages.no_recent_activity)}</span>}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
<Link to={`/groups/${group.get('id')}`} className='group-sidebar-panel__item'>
|
||||
<div className='group-sidebar-panel__item__title'>{group.get('title')}</div>
|
||||
<div className='group-sidebar-panel__item__meta'>
|
||||
{unreadCount > 0 && <span className='group-sidebar-panel__item__meta__unread'>{shortNumberFormat(unreadCount)} {intl.formatMessage(messages.new_statuses)}</span>}
|
||||
{unreadCount === 0 && <span>{intl.formatMessage(messages.no_recent_activity)}</span>}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,70 +8,72 @@ import { NavLink } from 'react-router-dom';
|
|||
import DropdownMenuContainer from '../../../../containers/dropdown_menu_container';
|
||||
|
||||
const messages = defineMessages({
|
||||
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
||||
leave: { id: 'groups.leave', defaultMessage: 'Leave group' },
|
||||
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
||||
edit: { id: 'groups.edit', defaultMessage: 'Edit' }
|
||||
join: { id: 'groups.join', defaultMessage: 'Join group' },
|
||||
leave: { id: 'groups.leave', defaultMessage: 'Leave group' },
|
||||
removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' },
|
||||
edit: { id: 'groups.edit', defaultMessage: 'Edit' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
class Header extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
toggleMembership: PropTypes.func.isRequired,
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
toggleMembership: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
getActionButton() {
|
||||
const { group, relationships, toggleMembership, intl } = this.props;
|
||||
const toggle = () => toggleMembership(group, relationships);
|
||||
const { group, relationships, toggleMembership, intl } = this.props;
|
||||
const toggle = () => toggleMembership(group, relationships);
|
||||
|
||||
if (!relationships) {
|
||||
return '';
|
||||
} else if (!relationships.get('member')) {
|
||||
return <Button className='logo-button' text={intl.formatMessage(messages.join)} onClick={toggle} />;
|
||||
} else if (relationships.get('member')) {
|
||||
return <Button className='logo-button' text={intl.formatMessage(messages.leave, { name: group.get('title') })} onClick={toggle} />;
|
||||
}
|
||||
if (!relationships) {
|
||||
return '';
|
||||
} else if (!relationships.get('member')) {
|
||||
return <Button className='logo-button' text={intl.formatMessage(messages.join)} onClick={toggle} />;
|
||||
} else if (relationships.get('member')) {
|
||||
return <Button className='logo-button' text={intl.formatMessage(messages.leave, { name: group.get('title') })} onClick={toggle} />;
|
||||
}
|
||||
}
|
||||
|
||||
getAdminMenu() {
|
||||
const { group, intl } = this.props;
|
||||
const { group, intl } = this.props;
|
||||
|
||||
const menu = [
|
||||
{ text: intl.formatMessage(messages.edit), to: `/groups/${group.get('id')}/edit` },
|
||||
{ text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed_accounts` },
|
||||
];
|
||||
const menu = [
|
||||
{ text: intl.formatMessage(messages.edit), to: `/groups/${group.get('id')}/edit` },
|
||||
{ text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed_accounts` },
|
||||
];
|
||||
|
||||
return <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
|
||||
return <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
|
||||
}
|
||||
|
||||
render () {
|
||||
const { group, relationships } = this.props;
|
||||
const { group, relationships } = this.props;
|
||||
|
||||
if (!group || !relationships) {
|
||||
return null;
|
||||
}
|
||||
if (!group || !relationships) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='group__header-container'>
|
||||
<div className="group__header">
|
||||
<div className='group__cover'>
|
||||
<img src={group.get('cover_image_url')} alt='' className='parallax' />
|
||||
</div>
|
||||
|
||||
<div className='group__tabs'>
|
||||
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}`}>Posts</NavLink>
|
||||
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}/members`}>Members</NavLink>
|
||||
{this.getActionButton()}
|
||||
{relationships.get('admin') && this.getAdminMenu()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className='group__header-container'>
|
||||
<div className='group__header'>
|
||||
<div className='group__cover'>
|
||||
<img src={group.get('cover_image_url')} alt='' className='parallax' />
|
||||
</div>
|
||||
|
||||
<div className='group__tabs'>
|
||||
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}`}>Posts</NavLink>
|
||||
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}/members`}>Members</NavLink>
|
||||
{this.getActionButton()}
|
||||
{relationships.get('admin') && this.getAdminMenu()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,31 +4,33 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
||||
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' }
|
||||
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },
|
||||
group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
class GroupPanel extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { group, relationships, intl } = this.props;
|
||||
const { group, relationships, intl } = this.props;
|
||||
|
||||
return (
|
||||
<div className="group__panel">
|
||||
<h1 className="group__panel__title">
|
||||
{group.get('title')}
|
||||
{group.get('archived') && <Icon id='lock' title={intl.formatMessage(messages.group_archived)} />}
|
||||
</h1>
|
||||
return (
|
||||
<div className='group__panel'>
|
||||
<h1 className='group__panel__title'>
|
||||
{group.get('title')}
|
||||
{group.get('archived') && <Icon id='lock' title={intl.formatMessage(messages.group_archived)} />}
|
||||
</h1>
|
||||
|
||||
{relationships.get('admin') && <span className="group__panel__label">{intl.formatMessage(messages.group_admin)}</span>}
|
||||
{relationships.get('admin') && <span className='group__panel__label'>{intl.formatMessage(messages.group_admin)}</span>}
|
||||
|
||||
<div className="group__panel__description">{group.get('description')}</div>
|
||||
</div>
|
||||
);
|
||||
<div className='group__panel__description'>{group.get('description')}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,18 +3,18 @@ import Header from '../components/header';
|
|||
import { joinGroup, leaveGroup } from '../../../../actions/groups';
|
||||
|
||||
const mapStateToProps = (state, { groupId }) => ({
|
||||
group: state.getIn(['groups', groupId]),
|
||||
relationships: state.getIn(['group_relationships', groupId]),
|
||||
group: state.getIn(['groups', groupId]),
|
||||
relationships: state.getIn(['group_relationships', groupId]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
toggleMembership (group, relationships) {
|
||||
if (relationships.get('member')) {
|
||||
dispatch(leaveGroup(group.get('id')));
|
||||
} else {
|
||||
dispatch(joinGroup(group.get('id')));
|
||||
}
|
||||
},
|
||||
toggleMembership (group, relationships) {
|
||||
if (relationships.get('member')) {
|
||||
dispatch(leaveGroup(group.get('id')));
|
||||
} else {
|
||||
dispatch(joinGroup(group.get('id')));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Header);
|
||||
|
|
|
@ -13,95 +13,97 @@ import ComposeFormContainer from '../../../../gabsocial/features/compose/contain
|
|||
import Avatar from '../../../components/avatar';
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const me = state.get('me');
|
||||
return {
|
||||
account: state.getIn(['accounts', me]),
|
||||
group: state.getIn(['groups', props.params.id]),
|
||||
relationships: state.getIn(['group_relationships', props.params.id]),
|
||||
hasUnread: state.getIn(['timelines', `group:${props.params.id}`, 'unread']) > 0,
|
||||
}
|
||||
const me = state.get('me');
|
||||
return {
|
||||
account: state.getIn(['accounts', me]),
|
||||
group: state.getIn(['groups', props.params.id]),
|
||||
relationships: state.getIn(['group_relationships', props.params.id]),
|
||||
hasUnread: state.getIn(['timelines', `group:${props.params.id}`, 'unread']) > 0,
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class GroupTimeline extends React.PureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
columnId: PropTypes.string,
|
||||
hasUnread: PropTypes.bool,
|
||||
group: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
|
||||
relationships: ImmutablePropTypes.map,
|
||||
account: ImmutablePropTypes.map,
|
||||
intl: PropTypes.object.isRequired,
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
columnId: PropTypes.string,
|
||||
hasUnread: PropTypes.bool,
|
||||
group: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
|
||||
relationships: ImmutablePropTypes.map,
|
||||
account: ImmutablePropTypes.map,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch } = this.props;
|
||||
const { id } = this.props.params;
|
||||
const { dispatch } = this.props;
|
||||
const { id } = this.props.params;
|
||||
|
||||
dispatch(expandGroupTimeline(id));
|
||||
dispatch(expandGroupTimeline(id));
|
||||
|
||||
this.disconnect = dispatch(connectGroupStream(id));
|
||||
this.disconnect = dispatch(connectGroupStream(id));
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (this.disconnect) {
|
||||
this.disconnect();
|
||||
this.disconnect = null;
|
||||
}
|
||||
if (this.disconnect) {
|
||||
this.disconnect();
|
||||
this.disconnect = null;
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMore = maxId => {
|
||||
const { id } = this.props.params;
|
||||
this.props.dispatch(expandGroupTimeline(id, { maxId }));
|
||||
const { id } = this.props.params;
|
||||
this.props.dispatch(expandGroupTimeline(id, { maxId }));
|
||||
}
|
||||
|
||||
render () {
|
||||
const { columnId, group, relationships, account } = this.props;
|
||||
const { id } = this.props.params;
|
||||
const { columnId, group, relationships, account } = this.props;
|
||||
const { id } = this.props.params;
|
||||
|
||||
if (typeof group === 'undefined' || !relationships) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
} else if (group === false) {
|
||||
return (
|
||||
<Column>
|
||||
<MissingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
if (typeof group === 'undefined' || !relationships) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
} else if (group === false) {
|
||||
return (
|
||||
<Column>
|
||||
<MissingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{relationships.get('member') && (
|
||||
<div className='timeline-compose-block'>
|
||||
<div className='timeline-compose-block__avatar'>
|
||||
<Avatar account={account} size={46} />
|
||||
</div>
|
||||
<ComposeFormContainer group={group} shouldCondense={true} autoFocus={false}/>
|
||||
</div>
|
||||
)}
|
||||
return (
|
||||
<div>
|
||||
{relationships.get('member') && (
|
||||
<div className='timeline-compose-block'>
|
||||
<div className='timeline-compose-block__avatar'>
|
||||
<Avatar account={account} size={46} />
|
||||
</div>
|
||||
<ComposeFormContainer group={group} shouldCondense autoFocus={false} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='group__feed'>
|
||||
<StatusListContainer
|
||||
alwaysPrepend
|
||||
scrollKey={`group_timeline-${columnId}`}
|
||||
timelineId={`group:${id}`}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
group={group}
|
||||
withGroupAdmin={relationships && relationships.get('admin')}
|
||||
emptyMessage={<FormattedMessage id='empty_column.group' defaultMessage='There is nothing in this group yet. When members of this group make new posts, they will appear here.' />}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div className='group__feed'>
|
||||
<StatusListContainer
|
||||
alwaysPrepend
|
||||
scrollKey={`group_timeline-${columnId}`}
|
||||
timelineId={`group:${id}`}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
group={group}
|
||||
withGroupAdmin={relationships && relationships.get('admin')}
|
||||
emptyMessage={<FormattedMessage id='empty_column.group' defaultMessage='There is nothing in this group yet. When members of this group make new posts, they will appear here.' />}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class HomeTimeline extends React.PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { intl, hasUnread, siteTitle} = this.props;
|
||||
const { intl, hasUnread, siteTitle } = this.props;
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.title)}>
|
||||
|
@ -79,7 +79,7 @@ class HomeTimeline extends React.PureComponent {
|
|||
scrollKey='home_timeline'
|
||||
onLoadMore={this.handleLoadMore}
|
||||
timelineId='home'
|
||||
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} to get started and meet other users.' values={{ public: <Link to='/timeline/local'><FormattedMessage id='empty_column.home.local_tab' defaultMessage='the {site_title} tab' values={{site_title: siteTitle}} /></Link> }} />}
|
||||
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} to get started and meet other users.' values={{ public: <Link to='/timeline/local'><FormattedMessage id='empty_column.home.local_tab' defaultMessage='the {site_title} tab' values={{ site_title: siteTitle }} /></Link> }} />}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux'
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { Link } from 'react-router-dom';
|
||||
import LoginForm from 'gabsocial/features/auth_login/components/login_form';
|
||||
|
@ -11,13 +11,14 @@ const mapStateToProps = (state, props) => ({
|
|||
});
|
||||
|
||||
class LandingPage extends ImmutablePureComponent {
|
||||
|
||||
getSiteLogo = () => {
|
||||
const { instance, soapbox } = this.props;
|
||||
const logos = {
|
||||
imgLogo: (<img alt={instance.get('title')} src={soapbox.get('logo')} />),
|
||||
textLogo: (<h1>{instance.get('title')}</h1>),
|
||||
}
|
||||
return soapbox.get('logo') ? logos['imgLogo'] : logos['textLogo'];
|
||||
};
|
||||
return soapbox.get('logo') ? logos.imgLogo : logos.textLogo;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -36,7 +37,7 @@ class LandingPage extends ImmutablePureComponent {
|
|||
<Link className='nav-link optional' to='/'>Home</Link>
|
||||
<Link className='nav-link' to='/about'>About</Link>
|
||||
</div>
|
||||
<div className='nav-center'></div>
|
||||
<div className='nav-center' />
|
||||
<div className='nav-right'>
|
||||
<div className='hidden-sm'>
|
||||
<LoginForm />
|
||||
|
@ -121,8 +122,9 @@ class LandingPage extends ImmutablePureComponent {
|
|||
</div>
|
||||
<NotificationsContainer />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(LandingPage);
|
||||
|
|
|
@ -21,7 +21,7 @@ const getOrderedLists = createSelector([state => state.get('lists')], lists => {
|
|||
return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title')));
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, {accountId}) => ({
|
||||
const mapStateToProps = (state, { accountId }) => ({
|
||||
listIds: getOrderedLists(state).map(list=>list.get('id')),
|
||||
account: state.getIn(['accounts', accountId]),
|
||||
});
|
||||
|
@ -84,12 +84,12 @@ class ListAdder extends ImmutablePureComponent {
|
|||
<Account accountId={accountId} />
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
<ColumnSubheading text={intl.formatMessage(messages.add)} />
|
||||
<NewListForm />
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
<ColumnSubheading text={intl.formatMessage(messages.subheading)} />
|
||||
<div className='list-adder__lists'>
|
||||
|
|
|
@ -75,7 +75,7 @@ class ListEditor extends ImmutablePureComponent {
|
|||
<div className='list-editor'>
|
||||
<ColumnSubheading text={intl.formatMessage(messages.changeTitle)} />
|
||||
<EditListForm />
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
{
|
||||
accountIds.size > 0 &&
|
||||
|
@ -87,7 +87,7 @@ class ListEditor extends ImmutablePureComponent {
|
|||
</div>
|
||||
}
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
<ColumnSubheading text={intl.formatMessage(messages.addToList)} />
|
||||
<Search />
|
||||
<div className='list-editor__accounts'>
|
||||
|
|
|
@ -120,8 +120,8 @@ class ListTimeline extends React.PureComponent {
|
|||
const emptyMessage = (
|
||||
<div>
|
||||
<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet. When members of this list create new posts, they will appear here.' />
|
||||
<br/><br/>
|
||||
<Button onClick={this.handleEditClick}><FormattedMessage id='list.click_to_add' defaultMessage='Click here to add people'/></Button>
|
||||
<br /><br />
|
||||
<Button onClick={this.handleEditClick}><FormattedMessage id='list.click_to_add' defaultMessage='Click here to add people' /></Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -137,7 +137,7 @@ class ListTimeline extends React.PureComponent {
|
|||
<Icon id='trash' /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' />
|
||||
</button>
|
||||
|
||||
<hr/>
|
||||
<hr />
|
||||
|
||||
<Link to='/lists' className='text-btn column-header__setting-btn column-header__setting-btn--link'>
|
||||
<FormattedMessage id='lists.view_all' defaultMessage='View all lists' />
|
||||
|
|
|
@ -61,10 +61,10 @@ class Lists extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column icon='list-ul' heading={intl.formatMessage(messages.heading)} backBtnSlim>
|
||||
<br/>
|
||||
<br />
|
||||
<ColumnSubheading text={intl.formatMessage(messages.add)} />
|
||||
<NewListForm />
|
||||
<br/>
|
||||
<br />
|
||||
<ColumnSubheading text={intl.formatMessage(messages.subheading)} />
|
||||
<ScrollableList
|
||||
scrollKey='lists'
|
||||
|
|
|
@ -51,7 +51,7 @@ class PinnedStatuses extends ImmutablePureComponent {
|
|||
statusIds={statusIds}
|
||||
scrollKey='pinned_statuses'
|
||||
hasMore={hasMore}
|
||||
emptyMessage={<FormattedMessage id='pinned_statuses.none' defaultMessage='No pins to show.'/>}
|
||||
emptyMessage={<FormattedMessage id='pinned_statuses.none' defaultMessage='No pins to show.' />}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
|
|
|
@ -88,7 +88,7 @@ class CommunityTimeline extends React.PureComponent {
|
|||
</HomeColumnHeader>
|
||||
<ExplanationBox
|
||||
title={<FormattedMessage id='fediverse_tab.explanation_box.title' defaultMessage='What is the Fediverse?' />}
|
||||
explanation={<FormattedMessage id='fediverse_tab.explanation_box.explanation' defaultMessage='{site_title} is part of the Fediverse, a social network made up of thousands of independent social media sites (aka "servers"). The posts you see here are from 3rd-party servers. You have the freedom to engage with them, or to block any server you don't like. Pay attention to the full username after the second @ symbol to know which server a post is from. To see only {site_title} posts, visit {local}.' values={{site_title: siteTitle, local: <Link to='/timeline/local'><FormattedMessage id='empty_column.home.local_tab' defaultMessage='the {site_title} tab' values={{site_title: siteTitle}} /></Link>}} />}
|
||||
explanation={<FormattedMessage id='fediverse_tab.explanation_box.explanation' defaultMessage='{site_title} is part of the Fediverse, a social network made up of thousands of independent social media sites (aka "servers"). The posts you see here are from 3rd-party servers. You have the freedom to engage with them, or to block any server you don't like. Pay attention to the full username after the second @ symbol to know which server a post is from. To see only {site_title} posts, visit {local}.' values={{ site_title: siteTitle, local: <Link to='/timeline/local'><FormattedMessage id='empty_column.home.local_tab' defaultMessage='the {site_title} tab' values={{ site_title: siteTitle }} /></Link> }} />}
|
||||
/>
|
||||
<StatusListContainer
|
||||
scrollKey={`${timelineId}_timeline`}
|
||||
|
|
|
@ -17,13 +17,13 @@ const mapStateToProps = (state, props) => {
|
|||
const getStatus = makeGetStatus();
|
||||
const status = getStatus(state, {
|
||||
id: props.params.statusId,
|
||||
username: props.params.username
|
||||
username: props.params.username,
|
||||
});
|
||||
|
||||
return {
|
||||
status,
|
||||
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
|
|
|
@ -25,7 +25,7 @@ class Header extends ImmutablePureComponent {
|
|||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.submitted) {
|
||||
const submittedValue = nextProps.value;
|
||||
this.setState({submittedValue})
|
||||
this.setState({ submittedValue });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ class Header extends ImmutablePureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(Header);
|
||||
|
|
|
@ -234,6 +234,7 @@ class ActionBar extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ActionBar));
|
||||
|
|
|
@ -64,7 +64,7 @@ const makeMapStateToProps = () => {
|
|||
const mapStateToProps = (state, props) => {
|
||||
const status = getStatus(state, {
|
||||
id: props.params.statusId,
|
||||
username: props.params.username
|
||||
username: props.params.username,
|
||||
});
|
||||
|
||||
let ancestorsIds = Immutable.List();
|
||||
|
@ -462,10 +462,11 @@ class Status extends ImmutablePureComponent {
|
|||
aria-label={intl.formatMessage(status.get('hidden') ? messages.revealAll : messages.hideAll)}
|
||||
onClick={this.handleToggleAll}
|
||||
aria-pressed={
|
||||
status.get('hidden') ? 'false' : 'true'}>
|
||||
<Icon id={status.get('hidden') ? 'eye-slash' : 'eye'
|
||||
status.get('hidden') ? 'false' : 'true'}
|
||||
>
|
||||
<Icon id={status.get('hidden') ? 'eye-slash' : 'eye'
|
||||
}
|
||||
/>
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class Column extends React.PureComponent {
|
|||
<ColumnHeader icon={icon} active={active} type={heading} columnHeaderId={columnHeaderId} />
|
||||
);
|
||||
|
||||
const backBtn = backBtnSlim ? (<ColumnBackButtonSlim/>) : (<ColumnBackButton/>);
|
||||
const backBtn = backBtnSlim ? (<ColumnBackButtonSlim />) : (<ColumnBackButton />);
|
||||
|
||||
return (
|
||||
<div role='region' aria-labelledby={columnHeaderId} className='column'>
|
||||
|
|
|
@ -27,7 +27,7 @@ class ColumnsArea extends ImmutablePureComponent {
|
|||
|
||||
render () {
|
||||
const { columns, children, intl } = this.props;
|
||||
const layout = this.props.layout || {LEFT:null,RIGHT:null};
|
||||
const layout = this.props.layout || { LEFT:null, RIGHT:null };
|
||||
|
||||
return (
|
||||
<div className='page'>
|
||||
|
@ -55,6 +55,7 @@ class ColumnsArea extends ImmutablePureComponent {
|
|||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class ComposeModal extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
onClickClose = () => {
|
||||
const {composeText, dispatch, onClose, intl} = this.props;
|
||||
const { composeText, dispatch, onClose, intl } = this.props;
|
||||
|
||||
if (composeText) {
|
||||
dispatch(openModal('CONFIRM', {
|
||||
|
@ -42,8 +42,7 @@ class ComposeModal extends ImmutablePureComponent {
|
|||
onConfirm: () => dispatch(cancelReplyCompose()),
|
||||
onCancel: () => dispatch(openModal('COMPOSE')),
|
||||
}));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
onClose('COMPOSE');
|
||||
}
|
||||
};
|
||||
|
@ -67,6 +66,7 @@ class ComposeModal extends ImmutablePureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(ComposeModal));
|
||||
|
|
|
@ -32,7 +32,7 @@ class ConfirmationModal extends React.PureComponent {
|
|||
}
|
||||
|
||||
handleCancel = () => {
|
||||
const {onClose, onCancel} = this.props;
|
||||
const { onClose, onCancel } = this.props;
|
||||
onClose();
|
||||
if (onCancel) onCancel();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ class ExplanationBox extends React.PureComponent {
|
|||
{dismissable && <span className='explanation-box__dismiss'>Dismiss</span>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ const mapStateToProps = state => {
|
|||
return {
|
||||
locked: state.getIn(['accounts', me, 'locked']),
|
||||
count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default @withRouter
|
||||
|
|
|
@ -34,7 +34,7 @@ class FundingPanel extends ImmutablePureComponent {
|
|||
return (
|
||||
<div className='wtf-panel funding-panel'>
|
||||
<div className='wtf-panel-header'>
|
||||
<i role='img' alt='users' className='fa fa-line-chart wtf-panel-header__icon'></i>
|
||||
<i role='img' alt='users' className='fa fa-line-chart wtf-panel-header__icon' />
|
||||
<span className='wtf-panel-header__label'>
|
||||
<span>Funding Goal</span>
|
||||
</span>
|
||||
|
@ -50,13 +50,14 @@ class FundingPanel extends ImmutablePureComponent {
|
|||
<a className='button' href='/donate'>Donate</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
funding: state.getIn(['patron', 'funding'])
|
||||
funding: state.getIn(['patron', 'funding']),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -64,4 +65,4 @@ export default injectIntl(
|
|||
connect(mapStateToProps, null, null, {
|
||||
forwardRef: true,
|
||||
}
|
||||
)(FundingPanel))
|
||||
)(FundingPanel));
|
||||
|
|
|
@ -13,13 +13,13 @@ const sourceCode = {
|
|||
url: 'https://gitlab.com/soapbox-pub/soapbox-fe',
|
||||
repository: 'soapox-pub/soapbox-fe',
|
||||
version: '0.0.0',
|
||||
}
|
||||
};
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const me = state.get('me');
|
||||
return {
|
||||
account: state.getIn(['accounts', me]),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
|
|
@ -48,7 +48,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
|||
<div className='profile-info-panel__content'>
|
||||
<div className='profile-info-panel-content__name'>
|
||||
<h1>
|
||||
<span/>
|
||||
<span />
|
||||
<small>@{username}</small>
|
||||
</h1>
|
||||
</div>
|
||||
|
@ -72,23 +72,25 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
|||
<div className='profile-info-panel-content__name'>
|
||||
<h1>
|
||||
<span dangerouslySetInnerHTML={displayNameHtml} />
|
||||
{account.get('is_verified') && <VerificationBadge />}
|
||||
{badge}
|
||||
{account.get('is_verified') && <VerificationBadge />}
|
||||
{badge}
|
||||
<small>@{acctFull(account)} {lockedIcon}</small>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className='profile-info-panel-content__badges'>
|
||||
{account.get('is_admin') && <Badge slug="admin" title="Admin" />}
|
||||
{account.get('is_moderator') && <Badge slug="moderator" title="Moderator" />}
|
||||
{account.get('is_admin') && <Badge slug='admin' title='Admin' />}
|
||||
{account.get('is_moderator') && <Badge slug='moderator' title='Moderator' />}
|
||||
{account.get('is_pro') && <ProBadge />}
|
||||
{account.get('is_donor') && <DonorBadge />}
|
||||
{account.get('is_investor') && <InvestorBadge />}
|
||||
{account.get('acct').includes('@') || <div className='profile-info-panel-content__badges__join-date'>
|
||||
<Icon id="calendar"/>
|
||||
<FormattedMessage id='account.member_since' defaultMessage='Member since {date}' values={{
|
||||
date: memberSinceDate
|
||||
}} />
|
||||
<Icon id='calendar' />
|
||||
<FormattedMessage
|
||||
id='account.member_since' defaultMessage='Member since {date}' values={{
|
||||
date: memberSinceDate,
|
||||
}}
|
||||
/>
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
|
@ -131,6 +133,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { account }) => {
|
||||
|
@ -145,4 +148,4 @@ export default injectIntl(
|
|||
connect(mapStateToProps, null, null, {
|
||||
forwardRef: true,
|
||||
}
|
||||
)(ProfileInfoPanel))
|
||||
)(ProfileInfoPanel));
|
||||
|
|
|
@ -7,7 +7,7 @@ import { connect } from 'react-redux';
|
|||
|
||||
const mapStateToProps = state => ({
|
||||
promoItems: state.getIn(['soapbox', 'promoPanel', 'items']),
|
||||
})
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class PromoPanel extends React.PureComponent {
|
||||
|
@ -20,15 +20,16 @@ class PromoPanel extends React.PureComponent {
|
|||
<div className='wtf-panel promo-panel'>
|
||||
<div className='promo-panel__container'>
|
||||
{promoItems.map((item, i) =>
|
||||
<div className='promo-panel-item' key={i}>
|
||||
(<div className='promo-panel-item' key={i}>
|
||||
<a className='promo-panel-item__btn' href={item.get('url')} target='_blank'>
|
||||
<Icon id={item.get('icon')} className='promo-panel-item__icon' fixedWidth />
|
||||
{item.get('text')}
|
||||
</a>
|
||||
</div>
|
||||
</div>)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ const SignUpPanel = ({ siteTitle, me }) => {
|
|||
<div className='wtf-panel'>
|
||||
<div className='wtf-panel-header'>
|
||||
<span className='wtf-panel-header__label'>
|
||||
<FormattedMessage id='signup_panel.title' defaultMessage='New to {site_title}?' values={{site_title: siteTitle}} />
|
||||
<FormattedMessage id='signup_panel.title' defaultMessage='New to {site_title}?' values={{ site_title: siteTitle }} />
|
||||
</span>
|
||||
</div>
|
||||
<div className='wtf-panel__content'>
|
||||
|
@ -25,13 +25,13 @@ const SignUpPanel = ({ siteTitle, me }) => {
|
|||
<FormattedMessage id='signup_panel.subtitle' defaultMessage='Sign up now to discuss.' />
|
||||
</span>
|
||||
<div className='wtf-panel__form'>
|
||||
<a className='button' href="/auth/sign_up">
|
||||
<a className='button' href='/auth/sign_up'>
|
||||
<FormattedMessage id='account.register' defaultMessage='Sign up' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(SignUpPanel));
|
||||
|
|
|
@ -64,33 +64,33 @@ class TabsBar extends React.PureComponent {
|
|||
links.push(
|
||||
<Link key='logo' className='tabs-bar__link--logo' to='/' data-preview-title-id='column.home' style={{ padding: '0', backgroundImage: `url(${logo})` }}>
|
||||
<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />
|
||||
</Link>)
|
||||
</Link>);
|
||||
}
|
||||
links.push(
|
||||
<NavLink key='home' className='tabs-bar__link' exact to='/' data-preview-title-id='column.home'>
|
||||
<i className='tabs-bar__link__icon home'/>
|
||||
<i className='tabs-bar__link__icon home' />
|
||||
<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />
|
||||
</NavLink>)
|
||||
</NavLink>);
|
||||
if (account) {
|
||||
links.push(
|
||||
<NavLink key='notifications' className='tabs-bar__link' to='/notifications' data-preview-title-id='column.notifications'>
|
||||
<i className='tabs-bar__link__icon notifications'/>
|
||||
<i className='tabs-bar__link__icon notifications' />
|
||||
<NotificationsCounterIcon />
|
||||
<FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' />
|
||||
</NavLink>)
|
||||
</NavLink>);
|
||||
}
|
||||
links.push(
|
||||
<NavLink key='search' className='tabs-bar__link tabs-bar__link--search' to='/search' data-preview-title-id='tabs_bar.search'>
|
||||
<i className='tabs-bar__link__icon tabs-bar__link__icon--search'/>
|
||||
<i className='tabs-bar__link__icon tabs-bar__link__icon--search' />
|
||||
<FormattedMessage id='tabs_bar.search' defaultMessage='Search' />
|
||||
</NavLink>
|
||||
);
|
||||
return links.map((link) =>
|
||||
React.cloneElement(link, {
|
||||
'aria-label': formatMessage({
|
||||
id: link.props['data-preview-title-id']
|
||||
})
|
||||
}));
|
||||
id: link.props['data-preview-title-id'],
|
||||
}),
|
||||
}));
|
||||
}
|
||||
|
||||
handleScroll = throttle(() => {
|
||||
|
@ -102,10 +102,10 @@ class TabsBar extends React.PureComponent {
|
|||
let st = pageYOffset || scrollTop;
|
||||
if (st > this.lastScrollTop){
|
||||
let offset = st - this.lastScrollTop;
|
||||
if (offset > 50) this.setState({collapsed: true});
|
||||
if (offset > 50) this.setState({ collapsed: true });
|
||||
} else {
|
||||
let offset = this.lastScrollTop - st;
|
||||
if (offset > 50) this.setState({collapsed: false});
|
||||
if (offset > 50) this.setState({ collapsed: false });
|
||||
}
|
||||
|
||||
this.lastScrollTop = st <= 0 ? 0 : st;
|
||||
|
@ -120,7 +120,7 @@ class TabsBar extends React.PureComponent {
|
|||
|
||||
const classes = classNames('tabs-bar', {
|
||||
'tabs-bar--collapsed': collapsed,
|
||||
})
|
||||
});
|
||||
|
||||
return (
|
||||
<nav className={classes} ref={this.setRef}>
|
||||
|
@ -136,7 +136,7 @@ class TabsBar extends React.PureComponent {
|
|||
<div className='flex'>
|
||||
<div className='tabs-bar__profile'>
|
||||
<Avatar account={account} />
|
||||
<button className='tabs-bar__sidebar-btn' onClick={onOpenSidebar}></button>
|
||||
<button className='tabs-bar__sidebar-btn' onClick={onOpenSidebar} />
|
||||
<ActionBar account={account} size={34} />
|
||||
</div>
|
||||
<button className='tabs-bar__button-compose button' onClick={onOpenCompose} aria-label='Gab'>
|
||||
|
@ -160,6 +160,7 @@ class TabsBar extends React.PureComponent {
|
|||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
|
@ -181,4 +182,4 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
|
||||
export default injectIntl(
|
||||
connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true }
|
||||
)(TabsBar))
|
||||
)(TabsBar));
|
||||
|
|
|
@ -47,9 +47,10 @@ class TrendsPanel extends ImmutablePureComponent {
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -60,11 +61,11 @@ const mapStateToProps = state => ({
|
|||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
fetchTrends: () => dispatch(fetchTrends()),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default injectIntl(
|
||||
connect(mapStateToProps, mapDispatchToProps, null, {
|
||||
forwardRef: true,
|
||||
}
|
||||
)(TrendsPanel))
|
||||
)(TrendsPanel));
|
||||
|
|
|
@ -36,7 +36,7 @@ class UnauthorizedModal extends ImmutablePureComponent {
|
|||
return (
|
||||
<div className='modal-root__modal compose-modal unauthorized-modal'>
|
||||
<div className='compose-modal__header'>
|
||||
<h3 className='compose-modal__header__title'><FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{site_title: siteTitle}} /></h3>
|
||||
<h3 className='compose-modal__header__title'><FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{ site_title: siteTitle }} /></h3>
|
||||
<IconButton className='compose-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={this.onClickClose} size={20} />
|
||||
</div>
|
||||
<div className='compose-modal__content'>
|
||||
|
@ -50,13 +50,16 @@ class UnauthorizedModal extends ImmutablePureComponent {
|
|||
</div>
|
||||
</div>
|
||||
<div className='unauthorized-modal__footer'>
|
||||
<FormattedMessage id='unauthorized_modal.footer' defaultMessage='Already have an account? {login}.' values={{
|
||||
login: <a href='/auth/sign_in'><FormattedMessage id='account.login' defaultMessage='Log in' /></a>
|
||||
}} />
|
||||
<FormattedMessage
|
||||
id='unauthorized_modal.footer' defaultMessage='Already have an account? {login}.' values={{
|
||||
login: <a href='/auth/sign_in'><FormattedMessage id='account.login' defaultMessage='Log in' /></a>,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(UnauthorizedModal));
|
||||
|
|
|
@ -12,6 +12,7 @@ import { shortNumberFormat } from 'gabsocial/utils/numbers';
|
|||
import { acctFull } from 'gabsocial/utils/accounts';
|
||||
|
||||
class UserPanel extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
intl: PropTypes.object.isRequired,
|
||||
|
@ -78,8 +79,9 @@ class UserPanel extends ImmutablePureComponent {
|
|||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -96,4 +98,4 @@ export default injectIntl(
|
|||
connect(mapStateToProps, null, null, {
|
||||
forwardRef: true,
|
||||
}
|
||||
)(UserPanel))
|
||||
)(UserPanel));
|
||||
|
|
|
@ -58,6 +58,7 @@ class WhoToFollowPanel extends ImmutablePureComponent {
|
|||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
|
@ -68,11 +69,11 @@ const mapDispatchToProps = dispatch => {
|
|||
return {
|
||||
fetchSuggestions: () => dispatch(fetchSuggestions()),
|
||||
dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default injectIntl(
|
||||
connect(mapStateToProps, mapDispatchToProps, null, {
|
||||
forwardRef: true,
|
||||
}
|
||||
)(WhoToFollowPanel))
|
||||
)(WhoToFollowPanel));
|
||||
|
|
|
@ -11,7 +11,7 @@ const mapStateToProps = state => ({
|
|||
const mapDispatchToProps = (dispatch) => ({
|
||||
onClose (optionalType) {
|
||||
if (optionalType === 'COMPOSE') {
|
||||
dispatch(cancelReplyCompose());
|
||||
dispatch(cancelReplyCompose());
|
||||
}
|
||||
|
||||
dispatch(closeModal());
|
||||
|
|
|
@ -30,7 +30,7 @@ const makeGetStatusIds = () => createSelector([
|
|||
});
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, {timelineId}) => {
|
||||
const mapStateToProps = (state, { timelineId }) => {
|
||||
const getStatusIds = makeGetStatusIds();
|
||||
|
||||
return {
|
||||
|
|
|
@ -90,7 +90,7 @@ const mapStateToProps = state => {
|
|||
me: state.get('me'),
|
||||
accessToken: state.getIn(['auth', 'user', 'access_token']),
|
||||
streamingUrl: state.getIn(['instance', 'urls', 'streaming_api']),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const keyMap = {
|
||||
|
@ -239,6 +239,7 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
|
@ -486,7 +487,7 @@ class UI extends React.PureComponent {
|
|||
}
|
||||
|
||||
handleHotkeyToggleHelp = () => {
|
||||
this.props.dispatch(openModal("HOTKEYS"));
|
||||
this.props.dispatch(openModal('HOTKEYS'));
|
||||
}
|
||||
|
||||
handleHotkeyGoToHome = () => {
|
||||
|
@ -526,7 +527,7 @@ class UI extends React.PureComponent {
|
|||
}
|
||||
|
||||
handleOpenComposeModal = () => {
|
||||
this.props.dispatch(openModal("COMPOSE"));
|
||||
this.props.dispatch(openModal('COMPOSE'));
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@ -554,7 +555,7 @@ class UI extends React.PureComponent {
|
|||
goToRequests: this.handleHotkeyGoToRequests,
|
||||
} : {};
|
||||
|
||||
const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <button key='floating-action-button' onClick={this.handleOpenComposeModal} className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}></button>;
|
||||
const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <button key='floating-action-button' onClick={this.handleOpenComposeModal} className='floating-action-button' aria-label={intl.formatMessage(messages.publish)} />;
|
||||
|
||||
return (
|
||||
<HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
|
||||
|
|
|
@ -14,6 +14,7 @@ const mapStateToProps = state => {
|
|||
};
|
||||
|
||||
class WrappedRoute extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
component: PropTypes.func.isRequired,
|
||||
page: PropTypes.func,
|
||||
|
@ -35,11 +36,11 @@ class WrappedRoute extends React.Component {
|
|||
<BundleContainer fetchComponent={component} loading={this.renderLoading} error={this.renderError}>
|
||||
{Component =>
|
||||
(
|
||||
<Page params={match.params} {...componentParams}>
|
||||
<Component params={match.params} {...componentParams}>
|
||||
{content}
|
||||
</Component>
|
||||
</Page>
|
||||
<Page params={match.params} {...componentParams}>
|
||||
<Component params={match.params} {...componentParams}>
|
||||
{content}
|
||||
</Component>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
</BundleContainer>
|
||||
|
@ -83,7 +84,8 @@ class WrappedRoute extends React.Component {
|
|||
|
||||
return <Route {...rest} render={this.renderComponent} />;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const wrappedRoute = connect(mapStateToProps)(WrappedRoute);
|
||||
export {wrappedRoute as WrappedRoute};
|
||||
export { wrappedRoute as WrappedRoute };
|
||||
|
|
|
@ -12,62 +12,63 @@ import { fetchGroup } from '../actions/groups';
|
|||
import GroupSidebarPanel from '../features/groups/sidebar_panel';
|
||||
|
||||
const mapStateToProps = (state, { params: { id } }) => ({
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
group: state.getIn(['groups', id]),
|
||||
relationships: state.getIn(['group_relationships', id]),
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class GroupPage extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
};
|
||||
group: ImmutablePropTypes.map,
|
||||
relationships: ImmutablePropTypes.map,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
const { params: { id }, dispatch } = this.props;
|
||||
componentWillMount() {
|
||||
const { params: { id }, dispatch } = this.props;
|
||||
|
||||
dispatch(fetchGroup(id));
|
||||
}
|
||||
dispatch(fetchGroup(id));
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, group, relationships } = this.props;
|
||||
render () {
|
||||
const { children, group, relationships } = this.props;
|
||||
|
||||
return (
|
||||
<div className='page group'>
|
||||
{group && <HeaderContainer groupId={group.get('id')} />}
|
||||
return (
|
||||
<div className='page group'>
|
||||
{group && <HeaderContainer groupId={group.get('id')} />}
|
||||
|
||||
<div className='page__columns'>
|
||||
<div className='columns-area__panels'>
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
{group && relationships &&
|
||||
<GroupPanel
|
||||
group={group}
|
||||
relationships={relationships}
|
||||
/>}
|
||||
<div className='page__columns'>
|
||||
<div className='columns-area__panels'>
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
{group && relationships &&
|
||||
<GroupPanel
|
||||
group={group}
|
||||
relationships={relationships}
|
||||
/>}
|
||||
|
||||
<PromoPanel />
|
||||
<LinkFooter />
|
||||
</div>
|
||||
</div>
|
||||
<PromoPanel />
|
||||
<LinkFooter />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__main'>
|
||||
<div className='columns-area columns-area--mobile'>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<div className='columns-area__panels__main'>
|
||||
<div className='columns-area columns-area--mobile'>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<GroupSidebarPanel />
|
||||
<WhoToFollowPanel />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<GroupSidebarPanel />
|
||||
<WhoToFollowPanel />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,46 +12,48 @@ const mapStateToProps = state => {
|
|||
const me = state.get('me');
|
||||
return {
|
||||
account: state.getIn(['accounts', me]),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class GroupsPage extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map
|
||||
account: ImmutablePropTypes.map,
|
||||
};
|
||||
|
||||
render () {
|
||||
const { children } = this.props;
|
||||
render () {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div className='page'>
|
||||
<div className='page__columns'>
|
||||
<div className='columns-area__panels'>
|
||||
return (
|
||||
<div className='page'>
|
||||
<div className='page__columns'>
|
||||
<div className='columns-area__panels'>
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<UserPanel />
|
||||
<PromoPanel />
|
||||
<LinkFooter />
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--left'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<UserPanel />
|
||||
<PromoPanel />
|
||||
<LinkFooter />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__main'>
|
||||
<div className='columns-area columns-area--mobile'>
|
||||
{children}
|
||||
<div className='columns-area__panels__main'>
|
||||
<div className='columns-area columns-area--mobile'>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<GroupSidebarPanel />
|
||||
<WhoToFollowPanel />
|
||||
<div className='columns-area__panels__pane columns-area__panels__pane--right'>
|
||||
<div className='columns-area__panels__pane__inner'>
|
||||
<GroupSidebarPanel />
|
||||
<WhoToFollowPanel />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,13 +17,14 @@ const mapStateToProps = state => {
|
|||
return {
|
||||
account: state.getIn(['accounts', me]),
|
||||
hasPatron: state.getIn(['soapbox', 'extensions', 'patron']),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
class HomePage extends ImmutablePureComponent {
|
||||
|
||||
render () {
|
||||
const {children, account, hasPatron} = this.props;
|
||||
const { children, account, hasPatron } = this.props;
|
||||
|
||||
return (
|
||||
<div className='page'>
|
||||
|
@ -45,7 +46,7 @@ class HomePage extends ImmutablePureComponent {
|
|||
<div className='timeline-compose-block__avatar'>
|
||||
<Avatar account={account} size={46} />
|
||||
</div>
|
||||
<ComposeFormContainer shouldCondense={true} autoFocus={false}/>
|
||||
<ComposeFormContainer shouldCondense autoFocus={false} />
|
||||
</div>
|
||||
|
||||
{children}
|
||||
|
@ -62,6 +63,7 @@ class HomePage extends ImmutablePureComponent {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,8 +24,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
let accountUsername = username;
|
||||
if (accountFetchError) {
|
||||
accountId = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
|
||||
accountId = account ? account.getIn(['id'], null) : -1;
|
||||
accountUsername = account ? account.getIn(['acct'], '') : '';
|
||||
|
@ -42,19 +41,20 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
|
|||
|
||||
export default @connect(mapStateToProps)
|
||||
class ProfilePage extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
accountUsername: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
render () {
|
||||
const {children, accountId, account, accountUsername} = this.props;
|
||||
const { children, accountId, account, accountUsername } = this.props;
|
||||
const bg = account ? account.getIn(['customizations', 'background']) : undefined;
|
||||
|
||||
return (
|
||||
<div className={bg && `page page--customization page--${bg}` || 'page'}>
|
||||
<div className='page__top'>
|
||||
<HeaderContainer accountId={accountId} username={accountUsername}/>
|
||||
<HeaderContainer accountId={accountId} username={accountUsername} />
|
||||
</div>
|
||||
|
||||
<div className='page__columns'>
|
||||
|
@ -85,6 +85,7 @@ class ProfilePage extends ImmutablePureComponent {
|
|||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import WhoToFollowPanel from '../features/ui/components/who_to_follow_panel';
|
|||
import LinkFooter from '../features/ui/components/link_footer';
|
||||
import SignUpPanel from '../features/ui/components/sign_up_panel';
|
||||
|
||||
const SearchPage = ({children}) => (
|
||||
const SearchPage = ({ children }) => (
|
||||
<div className='page'>
|
||||
<div className='page__top'>
|
||||
<Header />
|
||||
|
|
|
@ -33,7 +33,7 @@ export default function accounts(state = initialState, action) {
|
|||
return normalizeAccounts(state, action.accounts);
|
||||
case ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP:
|
||||
return state.set(-1, ImmutableMap({
|
||||
username: action.username
|
||||
username: action.username,
|
||||
}));
|
||||
default:
|
||||
return state;
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
import { Map as ImmutableMap } from 'immutable';
|
||||
import {
|
||||
GROUP_CREATE_REQUEST,
|
||||
GROUP_CREATE_FAIL,
|
||||
GROUP_CREATE_SUCCESS,
|
||||
GROUP_UPDATE_REQUEST,
|
||||
GROUP_UPDATE_FAIL,
|
||||
GROUP_UPDATE_SUCCESS,
|
||||
GROUP_EDITOR_RESET,
|
||||
GROUP_EDITOR_SETUP,
|
||||
GROUP_EDITOR_VALUE_CHANGE,
|
||||
GROUP_CREATE_REQUEST,
|
||||
GROUP_CREATE_FAIL,
|
||||
GROUP_CREATE_SUCCESS,
|
||||
GROUP_UPDATE_REQUEST,
|
||||
GROUP_UPDATE_FAIL,
|
||||
GROUP_UPDATE_SUCCESS,
|
||||
GROUP_EDITOR_RESET,
|
||||
GROUP_EDITOR_SETUP,
|
||||
GROUP_EDITOR_VALUE_CHANGE,
|
||||
} from '../actions/group_editor';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
groupId: null,
|
||||
isSubmitting: false,
|
||||
isChanged: false,
|
||||
title: '',
|
||||
description: '',
|
||||
coverImage: null,
|
||||
groupId: null,
|
||||
isSubmitting: false,
|
||||
isChanged: false,
|
||||
title: '',
|
||||
description: '',
|
||||
coverImage: null,
|
||||
});
|
||||
|
||||
export default function groupEditorReducer(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case GROUP_EDITOR_RESET:
|
||||
return initialState;
|
||||
case GROUP_EDITOR_SETUP:
|
||||
return state.withMutations(map => {
|
||||
map.set('groupId', action.group.get('id'));
|
||||
map.set('title', action.group.get('title'));
|
||||
map.set('description', action.group.get('description'));
|
||||
map.set('isSubmitting', false);
|
||||
});
|
||||
case GROUP_EDITOR_VALUE_CHANGE:
|
||||
return state.withMutations(map => {
|
||||
map.set(action.field, action.value);
|
||||
map.set('isChanged', true);
|
||||
});
|
||||
case GROUP_CREATE_REQUEST:
|
||||
case GROUP_UPDATE_REQUEST:
|
||||
return state.withMutations(map => {
|
||||
map.set('isSubmitting', true);
|
||||
map.set('isChanged', false);
|
||||
});
|
||||
case GROUP_CREATE_FAIL:
|
||||
case GROUP_UPDATE_FAIL:
|
||||
return state.set('isSubmitting', false);
|
||||
case GROUP_CREATE_SUCCESS:
|
||||
case GROUP_UPDATE_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.set('isSubmitting', false);
|
||||
map.set('groupId', action.group.id);
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch(action.type) {
|
||||
case GROUP_EDITOR_RESET:
|
||||
return initialState;
|
||||
case GROUP_EDITOR_SETUP:
|
||||
return state.withMutations(map => {
|
||||
map.set('groupId', action.group.get('id'));
|
||||
map.set('title', action.group.get('title'));
|
||||
map.set('description', action.group.get('description'));
|
||||
map.set('isSubmitting', false);
|
||||
});
|
||||
case GROUP_EDITOR_VALUE_CHANGE:
|
||||
return state.withMutations(map => {
|
||||
map.set(action.field, action.value);
|
||||
map.set('isChanged', true);
|
||||
});
|
||||
case GROUP_CREATE_REQUEST:
|
||||
case GROUP_UPDATE_REQUEST:
|
||||
return state.withMutations(map => {
|
||||
map.set('isSubmitting', true);
|
||||
map.set('isChanged', false);
|
||||
});
|
||||
case GROUP_CREATE_FAIL:
|
||||
case GROUP_UPDATE_FAIL:
|
||||
return state.set('isSubmitting', false);
|
||||
case GROUP_CREATE_SUCCESS:
|
||||
case GROUP_UPDATE_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.set('isSubmitting', false);
|
||||
map.set('groupId', action.group.id);
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
import { GROUP_RELATIONSHIPS_FETCH_SUCCESS, GROUP_JOIN_SUCCESS, GROUP_LEAVE_SUCCESS } from '../actions/groups';
|
||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||
|
||||
|
||||
const normalizeRelationship = (state, relationship) => state.set(relationship.id, fromJS(relationship));
|
||||
|
||||
|
||||
const normalizeRelationships = (state, relationships) => {
|
||||
relationships.forEach(relationship => {
|
||||
state = normalizeRelationship(state, relationship);
|
||||
});
|
||||
|
||||
return state;
|
||||
relationships.forEach(relationship => {
|
||||
state = normalizeRelationship(state, relationship);
|
||||
});
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
|
||||
const initialState = ImmutableMap();
|
||||
|
||||
|
||||
export default function group_relationships(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case GROUP_JOIN_SUCCESS:
|
||||
case GROUP_LEAVE_SUCCESS:
|
||||
return normalizeRelationship(state, action.relationship);
|
||||
case GROUP_RELATIONSHIPS_FETCH_SUCCESS:
|
||||
return normalizeRelationships(state, action.relationships);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch(action.type) {
|
||||
case GROUP_JOIN_SUCCESS:
|
||||
case GROUP_LEAVE_SUCCESS:
|
||||
return normalizeRelationship(state, action.relationship);
|
||||
case GROUP_RELATIONSHIPS_FETCH_SUCCESS:
|
||||
return normalizeRelationships(state, action.relationships);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
|
@ -146,8 +146,8 @@ export default function notifications(state = initialState, action) {
|
|||
return updateNotificationsQueue(state, action.notification, action.intlMessages, action.intlLocale);
|
||||
case NOTIFICATIONS_DEQUEUE:
|
||||
return state.withMutations(mutable => {
|
||||
mutable.set('queuedNotifications', ImmutableList())
|
||||
mutable.set('totalQueuedNotificationsCount', 0)
|
||||
mutable.set('queuedNotifications', ImmutableList());
|
||||
mutable.set('totalQueuedNotificationsCount', 0);
|
||||
});
|
||||
case NOTIFICATIONS_EXPAND_SUCCESS:
|
||||
return expandNormalizedNotifications(state, action.notifications, action.next);
|
||||
|
|
|
@ -170,8 +170,8 @@ export default function timelines(state = initialState, action) {
|
|||
return updateTimelineQueue(state, action.timeline, fromJS(action.status));
|
||||
case TIMELINE_DEQUEUE:
|
||||
return state.update(action.timeline, initialTimeline, map => map.withMutations(mMap => {
|
||||
mMap.set('queuedItems', ImmutableList())
|
||||
mMap.set('totalQueuedItemsCount', 0)
|
||||
mMap.set('queuedItems', ImmutableList());
|
||||
mMap.set('totalQueuedItemsCount', 0);
|
||||
}));
|
||||
case TIMELINE_DELETE:
|
||||
return deleteStatus(state, action.id, action.accountId, action.references, action.reblogOf);
|
||||
|
@ -193,7 +193,7 @@ export default function timelines(state = initialState, action) {
|
|||
map => map.set('online', false).update('items', items => items.first() ? items.unshift(null) : items)
|
||||
);
|
||||
case GROUP_REMOVE_STATUS_SUCCESS:
|
||||
return removeStatusFromGroup(state, action.groupId, action.id)
|
||||
return removeStatusFromGroup(state, action.groupId, action.id);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -12,16 +12,16 @@ const initialState = ImmutableMap({
|
|||
|
||||
export default function trendsReducer(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case TRENDS_FETCH_REQUEST:
|
||||
return state.set('isLoading', true);
|
||||
case TRENDS_FETCH_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.set('items', fromJS(action.tags.map((x => x))))
|
||||
map.set('isLoading', false);
|
||||
});
|
||||
case TRENDS_FETCH_FAIL:
|
||||
return state.set('isLoading', false);
|
||||
default:
|
||||
return state;
|
||||
case TRENDS_FETCH_REQUEST:
|
||||
return state.set('isLoading', true);
|
||||
case TRENDS_FETCH_SUCCESS:
|
||||
return state.withMutations(map => {
|
||||
map.set('items', fromJS(action.tags.map((x => x))));
|
||||
map.set('isLoading', false);
|
||||
});
|
||||
case TRENDS_FETCH_FAIL:
|
||||
return state.set('isLoading', false);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
MUTES_EXPAND_SUCCESS,
|
||||
} from '../actions/mutes';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import {
|
||||
import {
|
||||
GROUP_MEMBERS_FETCH_SUCCESS,
|
||||
GROUP_MEMBERS_EXPAND_SUCCESS,
|
||||
GROUP_REMOVED_ACCOUNTS_FETCH_SUCCESS,
|
||||
|
|
|
@ -85,9 +85,9 @@ export default function getStream(streamingAPIBaseURL, accessToken, stream, { co
|
|||
received(JSON.parse(e.data));
|
||||
} catch(error) {
|
||||
console.error(e);
|
||||
console.error(`Could not parse the above streaming event.\n${error}`)
|
||||
console.error(`Could not parse the above streaming event.\n${error}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return ws;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const getDomain = account => {
|
||||
let re = /https?:\/\/(.*?)\//i;
|
||||
return re.exec(account.get('url'))[1];
|
||||
}
|
||||
};
|
||||
|
||||
// user@domain even for local users
|
||||
export const acctFull = account => {
|
||||
|
@ -13,4 +13,4 @@ export const acctFull = account => {
|
|||
return account.get('acct');
|
||||
}
|
||||
return [user, domain].join('@');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,14 +4,14 @@ export const maximumAspectRatio = 2.8;
|
|||
export const isPanoramic = ar => {
|
||||
if (isNaN(ar)) return false;
|
||||
return ar >= maximumAspectRatio;
|
||||
}
|
||||
};
|
||||
|
||||
export const isPortrait = ar => {
|
||||
if (isNaN(ar)) return false;
|
||||
return ar <= minimumAspectRatio;
|
||||
}
|
||||
};
|
||||
|
||||
export const isNonConformingRatio = ar => {
|
||||
if (isNaN(ar)) return false;
|
||||
return !isPanoramic(ar) && !isPortrait(ar);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ delegate(document, '.btngroup__btn', 'click', ({ target: btn }) => {
|
|||
if (other_btn_hides) {
|
||||
other_btn_hides.style.display = '';
|
||||
}
|
||||
other_btn.classList.remove('btngroup__btn--active')
|
||||
other_btn.classList.remove('btngroup__btn--active');
|
||||
});
|
||||
|
||||
// Set given input
|
||||
|
@ -73,7 +73,7 @@ delegate(document, '.btngroup__btn', 'click', ({ target: btn }) => {
|
|||
}
|
||||
|
||||
// Highlight current button
|
||||
btn.classList.add('btngroup__btn--active')
|
||||
btn.classList.add('btngroup__btn--active');
|
||||
|
||||
// Set visibility of given elements
|
||||
if (btn_shows) {
|
||||
|
@ -96,26 +96,26 @@ delegate(document, '.btngroup__btn', 'click', ({ target: btn }) => {
|
|||
|
||||
delegate(document, '.payform', 'submit', (e) => {
|
||||
e.preventDefault();
|
||||
document.getElementById("paybtn").disabled = true;
|
||||
document.getElementById('paybtn').disabled = true;
|
||||
|
||||
const stripe_pk = document.querySelector("meta[name='stripe-pk']").content;
|
||||
const csrf_token = document.querySelector("meta[name='csrf-token']").content;
|
||||
const price = Math.floor(document.getElementById("price").value.replace(/[^0-9.]/, "") * 100);
|
||||
const stripe_pk = document.querySelector('meta[name=\'stripe-pk\']').content;
|
||||
const csrf_token = document.querySelector('meta[name=\'csrf-token\']').content;
|
||||
const price = Math.floor(document.getElementById('price').value.replace(/[^0-9.]/, '') * 100);
|
||||
|
||||
const stripe = Stripe(stripe_pk);
|
||||
const req = new XMLHttpRequest();
|
||||
|
||||
function checkout () {
|
||||
stripe.redirectToCheckout({
|
||||
sessionId: this.responseText
|
||||
sessionId: this.responseText,
|
||||
}).then(function (result) {
|
||||
console.log(result.error.message);
|
||||
});
|
||||
}
|
||||
|
||||
req.addEventListener("load", checkout);
|
||||
req.open("POST", "/donate/stripe");
|
||||
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
req.setRequestHeader("X-CSRF-Token", csrf_token);
|
||||
req.send("amount=" + price);
|
||||
req.addEventListener('load', checkout);
|
||||
req.open('POST', '/donate/stripe');
|
||||
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
req.setRequestHeader('X-CSRF-Token', csrf_token);
|
||||
req.send('amount=' + price);
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue