Commiting
This commit is contained in:
@@ -36,14 +36,6 @@ export const ACCOUNT_UNMUTE_REQUEST = 'ACCOUNT_UNMUTE_REQUEST';
|
||||
export const ACCOUNT_UNMUTE_SUCCESS = 'ACCOUNT_UNMUTE_SUCCESS';
|
||||
export const ACCOUNT_UNMUTE_FAIL = 'ACCOUNT_UNMUTE_FAIL';
|
||||
|
||||
export const ACCOUNT_PIN_REQUEST = 'ACCOUNT_PIN_REQUEST';
|
||||
export const ACCOUNT_PIN_SUCCESS = 'ACCOUNT_PIN_SUCCESS';
|
||||
export const ACCOUNT_PIN_FAIL = 'ACCOUNT_PIN_FAIL';
|
||||
|
||||
export const ACCOUNT_UNPIN_REQUEST = 'ACCOUNT_UNPIN_REQUEST';
|
||||
export const ACCOUNT_UNPIN_SUCCESS = 'ACCOUNT_UNPIN_SUCCESS';
|
||||
export const ACCOUNT_UNPIN_FAIL = 'ACCOUNT_UNPIN_FAIL';
|
||||
|
||||
export const FOLLOWERS_FETCH_REQUEST = 'FOLLOWERS_FETCH_REQUEST';
|
||||
export const FOLLOWERS_FETCH_SUCCESS = 'FOLLOWERS_FETCH_SUCCESS';
|
||||
export const FOLLOWERS_FETCH_FAIL = 'FOLLOWERS_FETCH_FAIL';
|
||||
@@ -772,72 +764,3 @@ export function rejectFollowRequestFail(id, error) {
|
||||
};
|
||||
};
|
||||
|
||||
export function pinAccount(id) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(pinAccountRequest(id));
|
||||
|
||||
api(getState).post(`/api/v1/accounts/${id}/pin`).then(response => {
|
||||
dispatch(pinAccountSuccess(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(pinAccountFail(error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinAccount(id) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(unpinAccountRequest(id));
|
||||
|
||||
api(getState).post(`/api/v1/accounts/${id}/unpin`).then(response => {
|
||||
dispatch(unpinAccountSuccess(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(unpinAccountFail(error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function pinAccountRequest(id) {
|
||||
return {
|
||||
type: ACCOUNT_PIN_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function pinAccountSuccess(relationship) {
|
||||
return {
|
||||
type: ACCOUNT_PIN_SUCCESS,
|
||||
relationship,
|
||||
};
|
||||
};
|
||||
|
||||
export function pinAccountFail(error) {
|
||||
return {
|
||||
type: ACCOUNT_PIN_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinAccountRequest(id) {
|
||||
return {
|
||||
type: ACCOUNT_UNPIN_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinAccountSuccess(relationship) {
|
||||
return {
|
||||
type: ACCOUNT_UNPIN_SUCCESS,
|
||||
relationship,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinAccountFail(error) {
|
||||
return {
|
||||
type: ACCOUNT_UNPIN_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,79 +11,69 @@ export const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST'
|
||||
export const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS'
|
||||
export const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL'
|
||||
|
||||
export function fetchBlocks() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchBlocks = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchBlocksRequest())
|
||||
dispatch(fetchBlocksRequest())
|
||||
|
||||
api(getState).get('/api/v1/blocks').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(fetchBlocksFail(error)))
|
||||
}
|
||||
api(getState).get('/api/v1/blocks').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(fetchBlocksFail(error)))
|
||||
}
|
||||
|
||||
export function fetchBlocksRequest() {
|
||||
return {
|
||||
type: BLOCKS_FETCH_REQUEST,
|
||||
}
|
||||
export const fetchBlocksRequest = () => ({
|
||||
type: BLOCKS_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
export const fetchBlocksSuccess = (accounts, next) => ({
|
||||
type: BLOCKS_FETCH_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
})
|
||||
|
||||
export const fetchBlocksFail = (error) => ({
|
||||
type: BLOCKS_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const expandBlocks = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['user_lists', 'blocks', me, 'next'])
|
||||
const isLoading = getState().getIn(['user_lists', 'blocks', me, 'isLoading'])
|
||||
|
||||
if (url === null || isLoading) return
|
||||
|
||||
dispatch(expandBlocksRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(expandBlocksFail(error)))
|
||||
}
|
||||
|
||||
export function fetchBlocksSuccess(accounts, next) {
|
||||
return {
|
||||
type: BLOCKS_FETCH_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
}
|
||||
}
|
||||
export const expandBlocksRequest = () => ({
|
||||
type: BLOCKS_EXPAND_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchBlocksFail(error) {
|
||||
return {
|
||||
type: BLOCKS_FETCH_FAIL,
|
||||
error,
|
||||
}
|
||||
}
|
||||
export const expandBlocksSuccess = (accounts, next) => ({
|
||||
type: BLOCKS_EXPAND_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
})
|
||||
|
||||
export function expandBlocks() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['user_lists', 'blocks', me, 'next'])
|
||||
const isLoading = getState().getIn(['user_lists', 'blocks', me, 'isLoading'])
|
||||
|
||||
if (url === null || isLoading) return
|
||||
|
||||
dispatch(expandBlocksRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(expandBlocksFail(error)))
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBlocksRequest() {
|
||||
return {
|
||||
type: BLOCKS_EXPAND_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBlocksSuccess(accounts, next) {
|
||||
return {
|
||||
type: BLOCKS_EXPAND_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBlocksFail(error) {
|
||||
return {
|
||||
type: BLOCKS_EXPAND_FAIL,
|
||||
error,
|
||||
}
|
||||
}
|
||||
export const expandBlocksFail = (error) => ({
|
||||
type: BLOCKS_EXPAND_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
@@ -10,89 +10,79 @@ export const BOOKMARKED_STATUSES_EXPAND_REQUEST = 'BOOKMARKED_STATUSES_EXPAND_RE
|
||||
export const BOOKMARKED_STATUSES_EXPAND_SUCCESS = 'BOOKMARKED_STATUSES_EXPAND_SUCCESS'
|
||||
export const BOOKMARKED_STATUSES_EXPAND_FAIL = 'BOOKMARKED_STATUSES_EXPAND_FAIL'
|
||||
|
||||
export function fetchBookmarkedStatuses() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchBookmarkedStatuses = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
if (getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(fetchBookmarkedStatusesRequest())
|
||||
|
||||
api(getState).get('/api/v1/bookmarks').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(fetchBookmarkedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(fetchBookmarkedStatusesFail(error))
|
||||
})
|
||||
if (getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(fetchBookmarkedStatusesRequest())
|
||||
|
||||
api(getState).get('/api/v1/bookmarks').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(fetchBookmarkedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(fetchBookmarkedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchBookmarkedStatusesRequest() {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
const fetchBookmarkedStatusesRequest = () => ({
|
||||
type: BOOKMARKED_STATUSES_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchBookmarkedStatusesSuccess = (statuses, next) => ({
|
||||
type: BOOKMARKED_STATUSES_FETCH_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchBookmarkedStatusesFail = (error) => ({
|
||||
type: BOOKMARKED_STATUSES_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const expandBookmarkedStatuses = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['status_lists', 'bookmarks', 'next'], null)
|
||||
|
||||
if (url === null || getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(expandBookmarkedStatusesRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(expandBookmarkedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(expandBookmarkedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchBookmarkedStatusesSuccess(statuses, next) {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_FETCH_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
skipLoading: true,
|
||||
}
|
||||
}
|
||||
const expandBookmarkedStatusesRequest = () => ({
|
||||
type: BOOKMARKED_STATUSES_EXPAND_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchBookmarkedStatusesFail(error) {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
}
|
||||
}
|
||||
const expandBookmarkedStatusesSuccess = (statuses, next) => ({
|
||||
type: BOOKMARKED_STATUSES_EXPAND_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
})
|
||||
|
||||
export function expandBookmarkedStatuses() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['status_lists', 'bookmarks', 'next'], null)
|
||||
|
||||
if (url === null || getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(expandBookmarkedStatusesRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(expandBookmarkedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(expandBookmarkedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBookmarkedStatusesRequest() {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_EXPAND_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBookmarkedStatusesSuccess(statuses, next) {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_EXPAND_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandBookmarkedStatusesFail(error) {
|
||||
return {
|
||||
type: BOOKMARKED_STATUSES_EXPAND_FAIL,
|
||||
error,
|
||||
}
|
||||
}
|
||||
const expandBookmarkedStatusesFail = (error) => ({
|
||||
type: BOOKMARKED_STATUSES_EXPAND_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
export const BUNDLE_FETCH_REQUEST = 'BUNDLE_FETCH_REQUEST';
|
||||
export const BUNDLE_FETCH_SUCCESS = 'BUNDLE_FETCH_SUCCESS';
|
||||
export const BUNDLE_FETCH_FAIL = 'BUNDLE_FETCH_FAIL';
|
||||
export const BUNDLE_FETCH_REQUEST = 'BUNDLE_FETCH_REQUEST'
|
||||
export const BUNDLE_FETCH_SUCCESS = 'BUNDLE_FETCH_SUCCESS'
|
||||
export const BUNDLE_FETCH_FAIL = 'BUNDLE_FETCH_FAIL'
|
||||
|
||||
export function fetchBundleRequest(skipLoading) {
|
||||
return {
|
||||
type: BUNDLE_FETCH_REQUEST,
|
||||
skipLoading,
|
||||
};
|
||||
}
|
||||
export const fetchBundleRequest = (skipLoading) => ({
|
||||
type: BUNDLE_FETCH_REQUEST,
|
||||
skipLoading,
|
||||
})
|
||||
|
||||
export function fetchBundleSuccess(skipLoading) {
|
||||
return {
|
||||
type: BUNDLE_FETCH_SUCCESS,
|
||||
skipLoading,
|
||||
};
|
||||
}
|
||||
export const fetchBundleSuccess = (skipLoading) => ({
|
||||
type: BUNDLE_FETCH_SUCCESS,
|
||||
skipLoading,
|
||||
})
|
||||
|
||||
export function fetchBundleFail(error, skipLoading) {
|
||||
return {
|
||||
type: BUNDLE_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading,
|
||||
};
|
||||
}
|
||||
export const fetchBundleFail = (error, skipLoading) => ({
|
||||
type: BUNDLE_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading,
|
||||
})
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import api from '../api';
|
||||
import api from '../api'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import { CancelToken, isCancel } from 'axios';
|
||||
import { CancelToken, isCancel } from 'axios'
|
||||
import throttle from 'lodash.throttle'
|
||||
import moment from 'moment-mini'
|
||||
import { isMobile } from '../utils/is_mobile'
|
||||
import { search as emojiSearch } from '../components/emoji/emoji_mart_search_light';
|
||||
import { search as emojiSearch } from '../components/emoji/emoji_mart_search_light'
|
||||
import { urlRegex } from '../features/ui/util/url_regex'
|
||||
import { tagHistory } from '../settings';
|
||||
import { tagHistory } from '../settings'
|
||||
import { joinGroup } from './groups'
|
||||
import { useEmoji } from './emojis';
|
||||
import resizeImage from '../utils/resize_image';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { useEmoji } from './emojis'
|
||||
import resizeImage from '../utils/resize_image'
|
||||
import { importFetchedAccounts } from './importer'
|
||||
import {
|
||||
updateTimelineQueue,
|
||||
updateTimeline,
|
||||
} from './timelines'
|
||||
// import { showAlert, showAlertForError } from './alerts';
|
||||
import { defineMessages } from 'react-intl';
|
||||
import { openModal, closeModal } from './modal';
|
||||
// import { showAlert, showAlertForError } from './alerts'
|
||||
import { defineMessages } from 'react-intl'
|
||||
import { openModal, closeModal } from './modal'
|
||||
import {
|
||||
STATUS_EXPIRATION_OPTION_5_MINUTES,
|
||||
STATUS_EXPIRATION_OPTION_60_MINUTES,
|
||||
@@ -26,57 +26,58 @@ import {
|
||||
STATUS_EXPIRATION_OPTION_3_DAYS,
|
||||
STATUS_EXPIRATION_OPTION_7_DAYS,
|
||||
} from '../constants'
|
||||
import { me } from '../initial_state';
|
||||
import { me } from '../initial_state'
|
||||
import { makeGetStatus } from '../selectors'
|
||||
|
||||
let cancelFetchComposeSuggestionsAccounts;
|
||||
let cancelFetchComposeSuggestionsAccounts
|
||||
|
||||
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
||||
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
||||
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
|
||||
export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
|
||||
export const COMPOSE_REPLY = 'COMPOSE_REPLY';
|
||||
export const COMPOSE_QUOTE = 'COMPOSE_QUOTE';
|
||||
export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL';
|
||||
export const COMPOSE_MENTION = 'COMPOSE_MENTION';
|
||||
export const COMPOSE_RESET = 'COMPOSE_RESET';
|
||||
export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
|
||||
export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS';
|
||||
export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL';
|
||||
export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS';
|
||||
export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO';
|
||||
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE'
|
||||
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST'
|
||||
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'
|
||||
export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL'
|
||||
export const COMPOSE_REPLY = 'COMPOSE_REPLY'
|
||||
export const COMPOSE_QUOTE = 'COMPOSE_QUOTE'
|
||||
export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'
|
||||
export const COMPOSE_MENTION = 'COMPOSE_MENTION'
|
||||
export const COMPOSE_RESET = 'COMPOSE_RESET'
|
||||
|
||||
export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
|
||||
export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
|
||||
export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
|
||||
export const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE';
|
||||
export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'
|
||||
export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'
|
||||
export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL'
|
||||
export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS'
|
||||
export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'
|
||||
|
||||
export const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE';
|
||||
export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR'
|
||||
export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY'
|
||||
export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT'
|
||||
export const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE'
|
||||
|
||||
export const COMPOSE_MOUNT = 'COMPOSE_MOUNT';
|
||||
export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
|
||||
export const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE'
|
||||
|
||||
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
|
||||
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
|
||||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
||||
export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
|
||||
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
|
||||
export const COMPOSE_MOUNT = 'COMPOSE_MOUNT'
|
||||
export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT'
|
||||
|
||||
export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
|
||||
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE'
|
||||
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE'
|
||||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE'
|
||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE'
|
||||
export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE'
|
||||
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE'
|
||||
|
||||
export const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST';
|
||||
export const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
|
||||
export const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL';
|
||||
export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT'
|
||||
|
||||
export const COMPOSE_POLL_ADD = 'COMPOSE_POLL_ADD';
|
||||
export const COMPOSE_POLL_REMOVE = 'COMPOSE_POLL_REMOVE';
|
||||
export const COMPOSE_POLL_OPTION_ADD = 'COMPOSE_POLL_OPTION_ADD';
|
||||
export const COMPOSE_POLL_OPTION_CHANGE = 'COMPOSE_POLL_OPTION_CHANGE';
|
||||
export const COMPOSE_POLL_OPTION_REMOVE = 'COMPOSE_POLL_OPTION_REMOVE';
|
||||
export const COMPOSE_POLL_SETTINGS_CHANGE = 'COMPOSE_POLL_SETTINGS_CHANGE';
|
||||
export const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST'
|
||||
export const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS'
|
||||
export const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL'
|
||||
|
||||
export const COMPOSE_SCHEDULED_AT_CHANGE = 'COMPOSE_SCHEDULED_AT_CHANGE';
|
||||
export const COMPOSE_POLL_ADD = 'COMPOSE_POLL_ADD'
|
||||
export const COMPOSE_POLL_REMOVE = 'COMPOSE_POLL_REMOVE'
|
||||
export const COMPOSE_POLL_OPTION_ADD = 'COMPOSE_POLL_OPTION_ADD'
|
||||
export const COMPOSE_POLL_OPTION_CHANGE = 'COMPOSE_POLL_OPTION_CHANGE'
|
||||
export const COMPOSE_POLL_OPTION_REMOVE = 'COMPOSE_POLL_OPTION_REMOVE'
|
||||
export const COMPOSE_POLL_SETTINGS_CHANGE = 'COMPOSE_POLL_SETTINGS_CHANGE'
|
||||
|
||||
export const COMPOSE_SCHEDULED_AT_CHANGE = 'COMPOSE_SCHEDULED_AT_CHANGE'
|
||||
|
||||
export const COMPOSE_EXPIRES_AT_CHANGE = 'COMPOSE_EXPIRES_AT_CHANGE'
|
||||
|
||||
@@ -87,15 +88,15 @@ export const COMPOSE_CLEAR = 'COMPOSE_CLEAR'
|
||||
const messages = defineMessages({
|
||||
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
|
||||
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
|
||||
});
|
||||
})
|
||||
|
||||
const COMPOSE_PANEL_BREAKPOINT = 600 + (285 * 1) + (10 * 1);
|
||||
const COMPOSE_PANEL_BREAKPOINT = 600 + (285 * 1) + (10 * 1)
|
||||
|
||||
export const ensureComposeIsVisible = (getState, routerHistory) => {
|
||||
if (!getState().getIn(['compose', 'mounted']) && window.innerWidth < COMPOSE_PANEL_BREAKPOINT) {
|
||||
routerHistory.push('/posts/new');
|
||||
routerHistory.push('/posts/new')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function changeCompose(text, markdown, replyId, isStandalone, caretPosition) {
|
||||
return function (dispatch, getState) {
|
||||
@@ -566,13 +567,11 @@ export function readyComposeSuggestionsEmojis(token, emojis) {
|
||||
};
|
||||
};
|
||||
|
||||
export function readyComposeSuggestionsAccounts(token, accounts) {
|
||||
return {
|
||||
type: COMPOSE_SUGGESTIONS_READY,
|
||||
token,
|
||||
accounts,
|
||||
};
|
||||
};
|
||||
export const readyComposeSuggestionsAccounts = (token, accounts) => ({
|
||||
type: COMPOSE_SUGGESTIONS_READY,
|
||||
token,
|
||||
accounts,
|
||||
})
|
||||
|
||||
export function selectComposeSuggestion(position, token, suggestion, path) {
|
||||
return (dispatch, getState) => {
|
||||
@@ -730,31 +729,35 @@ export function removePollOption(index) {
|
||||
};
|
||||
};
|
||||
|
||||
export function changePollSettings(expiresIn, isMultiple) {
|
||||
return {
|
||||
type: COMPOSE_POLL_SETTINGS_CHANGE,
|
||||
expiresIn,
|
||||
isMultiple,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changePollSettings = (expiresIn, isMultiple) => ({
|
||||
type: COMPOSE_POLL_SETTINGS_CHANGE,
|
||||
expiresIn,
|
||||
isMultiple,
|
||||
})
|
||||
|
||||
export function changeScheduledAt(date) {
|
||||
return {
|
||||
type: COMPOSE_SCHEDULED_AT_CHANGE,
|
||||
date,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeScheduledAt = (date) => ({
|
||||
type: COMPOSE_SCHEDULED_AT_CHANGE,
|
||||
date,
|
||||
})
|
||||
|
||||
export function changeExpiresAt(value) {
|
||||
return {
|
||||
type: COMPOSE_EXPIRES_AT_CHANGE,
|
||||
value,
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeExpiresAt = (value) => ({
|
||||
type: COMPOSE_EXPIRES_AT_CHANGE,
|
||||
value,
|
||||
})
|
||||
|
||||
export function changeRichTextEditorControlsVisibility(open) {
|
||||
return {
|
||||
type: COMPOSE_RICH_TEXT_EDITOR_CONTROLS_VISIBILITY,
|
||||
open,
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeRichTextEditorControlsVisibility = (open) => ({
|
||||
type: COMPOSE_RICH_TEXT_EDITOR_CONTROLS_VISIBILITY,
|
||||
open,
|
||||
})
|
||||
@@ -1,89 +0,0 @@
|
||||
import api, { getLinks } from '../api';
|
||||
import {
|
||||
importFetchedAccounts,
|
||||
importFetchedStatuses,
|
||||
importFetchedStatus,
|
||||
} from './importer';
|
||||
import { me } from '../initial_state';
|
||||
|
||||
export const CONVERSATIONS_MOUNT = 'CONVERSATIONS_MOUNT';
|
||||
export const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT';
|
||||
|
||||
export const CONVERSATIONS_FETCH_REQUEST = 'CONVERSATIONS_FETCH_REQUEST';
|
||||
export const CONVERSATIONS_FETCH_SUCCESS = 'CONVERSATIONS_FETCH_SUCCESS';
|
||||
export const CONVERSATIONS_FETCH_FAIL = 'CONVERSATIONS_FETCH_FAIL';
|
||||
export const CONVERSATIONS_UPDATE = 'CONVERSATIONS_UPDATE';
|
||||
|
||||
export const CONVERSATIONS_READ = 'CONVERSATIONS_READ';
|
||||
|
||||
export const mountConversations = () => ({
|
||||
type: CONVERSATIONS_MOUNT,
|
||||
});
|
||||
|
||||
export const unmountConversations = () => ({
|
||||
type: CONVERSATIONS_UNMOUNT,
|
||||
});
|
||||
|
||||
export const markConversationRead = conversationId => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch({
|
||||
type: CONVERSATIONS_READ,
|
||||
id: conversationId,
|
||||
});
|
||||
|
||||
api(getState).post(`/api/v1/conversations/${conversationId}/read`);
|
||||
};
|
||||
|
||||
export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(expandConversationsRequest());
|
||||
|
||||
const params = { max_id: maxId };
|
||||
|
||||
if (!maxId) {
|
||||
params.since_id = getState().getIn(['conversations', 'items', 0, 'last_status']);
|
||||
}
|
||||
|
||||
const isLoadingRecent = !!params.since_id;
|
||||
|
||||
api(getState).get('/api/v1/conversations', { params })
|
||||
.then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
|
||||
dispatch(importFetchedAccounts(response.data.reduce((aggr, item) => aggr.concat(item.accounts), [])));
|
||||
dispatch(importFetchedStatuses(response.data.map(item => item.last_status).filter(x => !!x)));
|
||||
dispatch(expandConversationsSuccess(response.data, next ? next.uri : null, isLoadingRecent));
|
||||
})
|
||||
.catch(err => dispatch(expandConversationsFail(err)));
|
||||
};
|
||||
|
||||
export const expandConversationsRequest = () => ({
|
||||
type: CONVERSATIONS_FETCH_REQUEST,
|
||||
});
|
||||
|
||||
export const expandConversationsSuccess = (conversations, next, isLoadingRecent) => ({
|
||||
type: CONVERSATIONS_FETCH_SUCCESS,
|
||||
conversations,
|
||||
next,
|
||||
isLoadingRecent,
|
||||
});
|
||||
|
||||
export const expandConversationsFail = error => ({
|
||||
type: CONVERSATIONS_FETCH_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const updateConversations = conversation => dispatch => {
|
||||
dispatch(importFetchedAccounts(conversation.accounts));
|
||||
|
||||
if (conversation.last_status) {
|
||||
dispatch(importFetchedStatus(conversation.last_status));
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: CONVERSATIONS_UPDATE,
|
||||
conversation,
|
||||
});
|
||||
};
|
||||
@@ -1,40 +1,32 @@
|
||||
import api from '../api';
|
||||
import api from '../api'
|
||||
|
||||
export const CUSTOM_EMOJIS_FETCH_REQUEST = 'CUSTOM_EMOJIS_FETCH_REQUEST';
|
||||
export const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS';
|
||||
export const CUSTOM_EMOJIS_FETCH_FAIL = 'CUSTOM_EMOJIS_FETCH_FAIL';
|
||||
export const CUSTOM_EMOJIS_FETCH_REQUEST = 'CUSTOM_EMOJIS_FETCH_REQUEST'
|
||||
export const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS'
|
||||
export const CUSTOM_EMOJIS_FETCH_FAIL = 'CUSTOM_EMOJIS_FETCH_FAIL'
|
||||
|
||||
export function fetchCustomEmojis() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(fetchCustomEmojisRequest());
|
||||
export const fetchCustomEmojis = () => (dispatch, getState) => {
|
||||
dispatch(fetchCustomEmojisRequest())
|
||||
|
||||
api(getState).get('/api/v1/custom_emojis').then(response => {
|
||||
dispatch(fetchCustomEmojisSuccess(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(fetchCustomEmojisFail(error));
|
||||
});
|
||||
};
|
||||
};
|
||||
api(getState).get('/api/v1/custom_emojis').then((response) => {
|
||||
dispatch(fetchCustomEmojisSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchCustomEmojisFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchCustomEmojisRequest() {
|
||||
return {
|
||||
type: CUSTOM_EMOJIS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
const fetchCustomEmojisRequest = () => ({
|
||||
type: CUSTOM_EMOJIS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export function fetchCustomEmojisSuccess(custom_emojis) {
|
||||
return {
|
||||
type: CUSTOM_EMOJIS_FETCH_SUCCESS,
|
||||
custom_emojis,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
const fetchCustomEmojisSuccess = (custom_emojis) => ({
|
||||
type: CUSTOM_EMOJIS_FETCH_SUCCESS,
|
||||
custom_emojis,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export function fetchCustomEmojisFail(error) {
|
||||
return {
|
||||
type: CUSTOM_EMOJIS_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
const fetchCustomEmojisFail = (error) => ({
|
||||
type: CUSTOM_EMOJIS_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { saveSettings } from './settings';
|
||||
import { saveSettings } from './settings'
|
||||
|
||||
export const EMOJI_USE = 'EMOJI_USE';
|
||||
export const EMOJI_USE = 'EMOJI_USE'
|
||||
|
||||
export function useEmoji(emoji) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: EMOJI_USE,
|
||||
emoji,
|
||||
});
|
||||
export const useEmoji = (emoji) => (dispatch) => {
|
||||
dispatch({
|
||||
type: EMOJI_USE,
|
||||
emoji,
|
||||
});
|
||||
|
||||
dispatch(saveSettings());
|
||||
};
|
||||
};
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
|
||||
@@ -10,89 +10,79 @@ export const FAVORITED_STATUSES_EXPAND_REQUEST = 'FAVORITED_STATUSES_EXPAND_REQU
|
||||
export const FAVORITED_STATUSES_EXPAND_SUCCESS = 'FAVORITED_STATUSES_EXPAND_SUCCESS'
|
||||
export const FAVORITED_STATUSES_EXPAND_FAIL = 'FAVORITED_STATUSES_EXPAND_FAIL'
|
||||
|
||||
export function fetchFavoritedStatuses() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchFavoritedStatuses = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
if (getState().getIn(['status_lists', 'favorites', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(fetchFavoritedStatusesRequest())
|
||||
|
||||
api(getState).get('/api/v1/favourites').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(fetchFavoritedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(fetchFavoritedStatusesFail(error))
|
||||
})
|
||||
if (getState().getIn(['status_lists', 'favorites', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(fetchFavoritedStatusesRequest())
|
||||
|
||||
api(getState).get('/api/v1/favourites').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(fetchFavoritedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(fetchFavoritedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchFavoritedStatusesRequest() {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
const fetchFavoritedStatusesRequest = () => ({
|
||||
type: FAVORITED_STATUSES_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchFavoritedStatusesSuccess = (statuses, next) => ({
|
||||
type: FAVORITED_STATUSES_FETCH_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchFavoritedStatusesFail = (error) => ({
|
||||
type: FAVORITED_STATUSES_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const expandFavoritedStatuses = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['status_lists', 'favorites', 'next'], null)
|
||||
|
||||
if (url === null || getState().getIn(['status_lists', 'favorites', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(expandFavoritedStatusesRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(expandFavoritedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(expandFavoritedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchFavoritedStatusesSuccess(statuses, next) {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_FETCH_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
skipLoading: true,
|
||||
}
|
||||
}
|
||||
const expandFavoritedStatusesRequest = () => ({
|
||||
type: FAVORITED_STATUSES_EXPAND_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchFavoritedStatusesFail(error) {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_FETCH_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
}
|
||||
}
|
||||
const expandFavoritedStatusesSuccess = (statuses, next) => ({
|
||||
type: FAVORITED_STATUSES_EXPAND_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
})
|
||||
|
||||
export function expandFavoritedStatuses() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['status_lists', 'favorites', 'next'], null)
|
||||
|
||||
if (url === null || getState().getIn(['status_lists', 'favorites', 'isLoading'])) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(expandFavoritedStatusesRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(expandFavoritedStatusesSuccess(response.data, next ? next.uri : null))
|
||||
}).catch(error => {
|
||||
dispatch(expandFavoritedStatusesFail(error))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function expandFavoritedStatusesRequest() {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_EXPAND_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandFavoritedStatusesSuccess(statuses, next) {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_EXPAND_SUCCESS,
|
||||
statuses,
|
||||
next,
|
||||
}
|
||||
}
|
||||
|
||||
export function expandFavoritedStatusesFail(error) {
|
||||
return {
|
||||
type: FAVORITED_STATUSES_EXPAND_FAIL,
|
||||
error,
|
||||
}
|
||||
}
|
||||
const expandFavoritedStatusesFail = (error) => ({
|
||||
type: FAVORITED_STATUSES_EXPAND_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
import api from '../api';
|
||||
import { me } from '../initial_state';
|
||||
import api from '../api'
|
||||
import { me } from '../initial_state'
|
||||
|
||||
export const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST';
|
||||
export const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS';
|
||||
export const FILTERS_FETCH_FAIL = 'FILTERS_FETCH_FAIL';
|
||||
export const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST'
|
||||
export const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS'
|
||||
export const FILTERS_FETCH_FAIL = 'FILTERS_FETCH_FAIL'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchFilters = () => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch({
|
||||
type: FILTERS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
});
|
||||
dispatch(fetchFiltersRequest())
|
||||
|
||||
api(getState)
|
||||
.get('/api/v1/filters')
|
||||
.then(({ data }) => dispatch({
|
||||
type: FILTERS_FETCH_SUCCESS,
|
||||
filters: data,
|
||||
skipLoading: true,
|
||||
}))
|
||||
.catch(err => dispatch({
|
||||
type: FILTERS_FETCH_FAIL,
|
||||
err,
|
||||
skipLoading: true,
|
||||
skipAlert: true,
|
||||
}));
|
||||
};
|
||||
api(getState).get('/api/v1/filters').then(({ data }) => {
|
||||
dispatch(fetchFiltersSuccess(data))
|
||||
}).catch((err) => {
|
||||
dispatch(fetchFiltersFail(err))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const fetchFiltersRequest = () => ({
|
||||
type: FILTERS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchFiltersSuccess = (filters) => ({
|
||||
type: FILTERS_FETCH_SUCCESS,
|
||||
filters,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
const fetchFiltersFail = (err) => ({
|
||||
type: FILTERS_FETCH_FAIL,
|
||||
err,
|
||||
skipLoading: true,
|
||||
skipAlert: true,
|
||||
})
|
||||
@@ -4,6 +4,9 @@ export const GROUP_CATEGORIES_FETCH_REQUEST = 'GROUP_CATEGORIES_FETCH_REQUEST'
|
||||
export const GROUP_CATEGORIES_FETCH_SUCCESS = 'GROUP_CATEGORIES_FETCH_SUCCESS'
|
||||
export const GROUP_CATEGORIES_FETCH_FAIL = 'GROUP_CATEGORIES_FETCH_FAIL'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchGroupCategories = () => (dispatch, getState) => {
|
||||
dispatch(fetchGroupCategoriesRequest())
|
||||
|
||||
@@ -12,16 +15,16 @@ export const fetchGroupCategories = () => (dispatch, getState) => {
|
||||
.catch(err => dispatch(fetchGroupCategoriesFail(err)))
|
||||
}
|
||||
|
||||
export const fetchGroupCategoriesRequest = () => ({
|
||||
const fetchGroupCategoriesRequest = () => ({
|
||||
type: GROUP_CATEGORIES_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
export const fetchGroupCategoriesSuccess = (categories) => ({
|
||||
const fetchGroupCategoriesSuccess = (categories) => ({
|
||||
type: GROUP_CATEGORIES_FETCH_SUCCESS,
|
||||
categories,
|
||||
})
|
||||
|
||||
export const fetchGroupCategoriesFail = (error) => ({
|
||||
const fetchGroupCategoriesFail = (error) => ({
|
||||
type: GROUP_CATEGORIES_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
@@ -22,6 +22,9 @@ export const GROUP_EDITOR_IS_VISIBLE_CHANGE = 'GROUP_EDITOR_IS_VISIBLE_CHANGE'
|
||||
export const GROUP_EDITOR_RESET = 'GROUP_EDITOR_RESET'
|
||||
export const GROUP_EDITOR_SETUP = 'GROUP_EDITOR_SETUP'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const submit = (routerHistory) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
@@ -50,16 +53,19 @@ export const submit = (routerHistory) => (dispatch, getState) => {
|
||||
}
|
||||
|
||||
if (groupId === null) {
|
||||
dispatch(create(options, routerHistory))
|
||||
dispatch(createGroup(options, routerHistory))
|
||||
} else {
|
||||
dispatch(update(groupId, options, routerHistory))
|
||||
dispatch(updateGroup(groupId, options, routerHistory))
|
||||
}
|
||||
}
|
||||
|
||||
const create = (options, routerHistory) => (dispatch, getState) => {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const createGroup = (options, routerHistory) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(createRequest())
|
||||
dispatch(createGroupRequest())
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('title', options.title)
|
||||
@@ -81,28 +87,31 @@ const create = (options, routerHistory) => (dispatch, getState) => {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}).then(({ data }) => {
|
||||
dispatch(createSuccess(data))
|
||||
dispatch(createGroupSuccess(data))
|
||||
routerHistory.push(`/groups/${data.id}`)
|
||||
}).catch(err => dispatch(createFail(err)))
|
||||
}).catch((err) => dispatch(createGroupFail(err)))
|
||||
}
|
||||
|
||||
|
||||
export const createRequest = (id) => ({
|
||||
const createGroupRequest = (id) => ({
|
||||
type: GROUP_CREATE_REQUEST,
|
||||
id,
|
||||
})
|
||||
|
||||
export const createSuccess = (group) => ({
|
||||
const createSuccess = (group) => ({
|
||||
type: GROUP_CREATE_SUCCESS,
|
||||
group,
|
||||
})
|
||||
|
||||
export const createFail = (error) => ({
|
||||
const createFail = (error) => ({
|
||||
type: GROUP_CREATE_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
const update = (groupId, options, routerHistory) => (dispatch, getState) => {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const updateGroup = (groupId, options, routerHistory) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(updateRequest())
|
||||
@@ -130,26 +139,29 @@ const update = (groupId, options, routerHistory) => (dispatch, getState) => {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}).then(({ data }) => {
|
||||
dispatch(updateSuccess(data))
|
||||
dispatch(updateGroupSuccess(data))
|
||||
routerHistory.push(`/groups/${data.id}`)
|
||||
}).catch(err => dispatch(updateFail(err)))
|
||||
}).catch((err) => dispatch(updateGroupFail(err)))
|
||||
}
|
||||
|
||||
export const updateRequest = (id) => ({
|
||||
const updateGroupRequest = (id) => ({
|
||||
type: GROUP_UPDATE_REQUEST,
|
||||
id,
|
||||
})
|
||||
|
||||
export const updateSuccess = (group) => ({
|
||||
const updateGroupSuccess = (group) => ({
|
||||
type: GROUP_UPDATE_SUCCESS,
|
||||
group,
|
||||
})
|
||||
|
||||
export const updateFail = (error) => ({
|
||||
const updateGroupFail = (error) => ({
|
||||
type: GROUP_UPDATE_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const resetEditor = () => ({
|
||||
type: GROUP_EDITOR_RESET
|
||||
})
|
||||
|
||||
@@ -107,6 +107,11 @@ export const importGroup = (group) => (dispatch) => {
|
||||
dispatch(fetchGroupSuccess(group))
|
||||
}
|
||||
|
||||
export const importGroups = (groups) => (dispatch) => {
|
||||
if (!Array.isArray(groups)) return
|
||||
groups.map((group) => dispatch(fetchGroupSuccess(group)))
|
||||
}
|
||||
|
||||
export const fetchGroup = (id) => (dispatch, getState) => {
|
||||
dispatch(fetchGroupRelationships([id]));
|
||||
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
export const HEIGHT_CACHE_SET = 'HEIGHT_CACHE_SET';
|
||||
export const HEIGHT_CACHE_CLEAR = 'HEIGHT_CACHE_CLEAR';
|
||||
export const HEIGHT_CACHE_SET = 'HEIGHT_CACHE_SET'
|
||||
export const HEIGHT_CACHE_CLEAR = 'HEIGHT_CACHE_CLEAR'
|
||||
|
||||
export function setHeight (key, id, height) {
|
||||
return {
|
||||
type: HEIGHT_CACHE_SET,
|
||||
key,
|
||||
id,
|
||||
height,
|
||||
};
|
||||
};
|
||||
export const setHeight = (key, id, height) => ({
|
||||
type: HEIGHT_CACHE_SET,
|
||||
key,
|
||||
id,
|
||||
height,
|
||||
})
|
||||
|
||||
export function clearHeight () {
|
||||
return {
|
||||
type: HEIGHT_CACHE_CLEAR,
|
||||
};
|
||||
};
|
||||
export const clearHeight = () => ({
|
||||
type: HEIGHT_CACHE_CLEAR,
|
||||
})
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { normalizeAccount, normalizeStatus, normalizePoll } from './normalizer';
|
||||
import isObject from 'lodash.isobject'
|
||||
import {
|
||||
normalizeAccount,
|
||||
normalizeStatus,
|
||||
normalizePoll,
|
||||
} from './normalizer'
|
||||
import { fetchContext } from '../statuses'
|
||||
import { importGroups } from '../groups'
|
||||
|
||||
export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
|
||||
export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
|
||||
export const STATUS_IMPORT = 'STATUS_IMPORT';
|
||||
export const STATUSES_IMPORT = 'STATUSES_IMPORT';
|
||||
export const POLLS_IMPORT = 'POLLS_IMPORT';
|
||||
export const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP';
|
||||
export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT'
|
||||
export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT'
|
||||
export const STATUS_IMPORT = 'STATUS_IMPORT'
|
||||
export const STATUSES_IMPORT = 'STATUSES_IMPORT'
|
||||
export const POLLS_IMPORT = 'POLLS_IMPORT'
|
||||
export const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP'
|
||||
|
||||
function pushUnique(array, object) {
|
||||
if (array.every(element => element.id !== object.id)) {
|
||||
@@ -14,34 +20,39 @@ function pushUnique(array, object) {
|
||||
}
|
||||
}
|
||||
|
||||
export function importAccount(account) {
|
||||
return { type: ACCOUNT_IMPORT, account };
|
||||
}
|
||||
export const importAccount = (account) => ({
|
||||
type: ACCOUNT_IMPORT,
|
||||
account,
|
||||
})
|
||||
|
||||
export function importAccounts(accounts) {
|
||||
return { type: ACCOUNTS_IMPORT, accounts };
|
||||
}
|
||||
export const importAccounts = (accounts) => ({
|
||||
type: ACCOUNTS_IMPORT,
|
||||
accounts,
|
||||
})
|
||||
|
||||
export function importStatus(status) {
|
||||
return { type: STATUS_IMPORT, status };
|
||||
}
|
||||
export const importStatus = (status) => ({
|
||||
type: STATUS_IMPORT,
|
||||
status,
|
||||
})
|
||||
|
||||
export function importStatuses(statuses) {
|
||||
return { type: STATUSES_IMPORT, statuses };
|
||||
}
|
||||
export const importStatuses = (statuses) => ({
|
||||
type: STATUSES_IMPORT,
|
||||
statuses,
|
||||
})
|
||||
|
||||
export function importPolls(polls) {
|
||||
return { type: POLLS_IMPORT, polls };
|
||||
}
|
||||
export const importPolls = (polls) => ({
|
||||
type: POLLS_IMPORT,
|
||||
polls,
|
||||
})
|
||||
|
||||
export function importFetchedAccount(account) {
|
||||
export const importFetchedAccount = (account) => {
|
||||
return importFetchedAccounts([account]);
|
||||
}
|
||||
|
||||
export function importFetchedAccounts(accounts) {
|
||||
export const importFetchedAccounts = (accounts) => {
|
||||
const normalAccounts = [];
|
||||
|
||||
function processAccount(account) {
|
||||
const processAccount = (account) => {
|
||||
pushUnique(normalAccounts, normalizeAccount(account));
|
||||
|
||||
if (account.moved) {
|
||||
@@ -54,47 +65,48 @@ export function importFetchedAccounts(accounts) {
|
||||
return importAccounts(normalAccounts);
|
||||
}
|
||||
|
||||
export function importFetchedStatus(status) {
|
||||
export const importFetchedStatus = (status) => {
|
||||
return importFetchedStatuses([status]);
|
||||
}
|
||||
|
||||
export function importFetchedStatuses(statuses) {
|
||||
return (dispatch, getState) => {
|
||||
const accounts = [];
|
||||
const normalStatuses = [];
|
||||
const polls = [];
|
||||
export const importFetchedStatuses = (statuses) => (dispatch, getState) => {
|
||||
const accounts = []
|
||||
const normalStatuses = []
|
||||
const polls = []
|
||||
const groups = []
|
||||
|
||||
function processStatus(status) {
|
||||
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
|
||||
pushUnique(accounts, status.account);
|
||||
const processStatus = (status) => {
|
||||
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])))
|
||||
|
||||
if (status.reblog && status.reblog.id) {
|
||||
processStatus(status.reblog);
|
||||
}
|
||||
|
||||
if (status.quote && status.quote.id) {
|
||||
processStatus(status.quote);
|
||||
}
|
||||
|
||||
if (status.poll && status.poll.id) {
|
||||
pushUnique(polls, normalizePoll(status.poll));
|
||||
}
|
||||
if (isObject(status.account)) pushUnique(accounts, status.account)
|
||||
if (isObject(status.group)) pushUnique(groups, status.group)
|
||||
|
||||
if (status.reblog && status.reblog.id) {
|
||||
processStatus(status.reblog)
|
||||
}
|
||||
|
||||
statuses.forEach(processStatus);
|
||||
if (status.quote && status.quote.id) {
|
||||
processStatus(status.quote)
|
||||
}
|
||||
|
||||
dispatch(importPolls(polls));
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importStatuses(normalStatuses));
|
||||
};
|
||||
if (status.poll && status.poll.id) {
|
||||
pushUnique(polls, normalizePoll(status.poll))
|
||||
}
|
||||
}
|
||||
|
||||
statuses.forEach(processStatus)
|
||||
|
||||
dispatch(importPolls(polls))
|
||||
dispatch(importFetchedAccounts(accounts))
|
||||
dispatch(importStatuses(normalStatuses))
|
||||
dispatch(importGroups(groups))
|
||||
}
|
||||
|
||||
export function importFetchedPoll(poll) {
|
||||
return dispatch => {
|
||||
dispatch(importPolls([normalizePoll(poll)]));
|
||||
};
|
||||
export const importFetchedPoll = (poll) => (dispatch) => {
|
||||
dispatch(importPolls([normalizePoll(poll)]))
|
||||
}
|
||||
|
||||
export function importErrorWhileFetchingAccountByUsername(username) {
|
||||
return { type: ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP, username };
|
||||
};
|
||||
export const importErrorWhileFetchingAccountByUsername = (username) => ({
|
||||
type: ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP,
|
||||
username
|
||||
})
|
||||
|
||||
@@ -39,7 +39,7 @@ export function normalizeAccount(account) {
|
||||
|
||||
export function normalizeStatus(status, normalOldStatus) {
|
||||
const normalStatus = { ...status };
|
||||
normalStatus.account = status.account.id;
|
||||
normalStatus.account = status.account_id || status.account.id;
|
||||
|
||||
if (status.reblog && status.reblog.id) {
|
||||
normalStatus.reblog = status.reblog.id;
|
||||
@@ -53,6 +53,10 @@ export function normalizeStatus(status, normalOldStatus) {
|
||||
normalStatus.poll = status.poll.id;
|
||||
}
|
||||
|
||||
if (!!status.group || !!status.group_id) {
|
||||
normalStatus.group = status.group_id || status.group.id;
|
||||
}
|
||||
|
||||
// Only calculate these values when status first encountered
|
||||
// Otherwise keep the ones already in the reducer
|
||||
if (normalOldStatus && normalOldStatus.get('content') === normalStatus.content && normalOldStatus.get('spoiler_text') === normalStatus.spoiler_text) {
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
import api from '../api';
|
||||
import { importFetchedAccounts, importFetchedStatus } from './importer';
|
||||
import { me } from '../initial_state';
|
||||
import api from '../api'
|
||||
import { importFetchedAccounts, importFetchedStatus } from './importer'
|
||||
import { updateStatusStats } from './statuses'
|
||||
import { me } from '../initial_state'
|
||||
|
||||
export const REPOST_REQUEST = 'REPOST_REQUEST';
|
||||
export const REPOST_SUCCESS = 'REPOST_SUCCESS';
|
||||
export const REPOST_FAIL = 'REPOST_FAIL';
|
||||
export const REPOST_REQUEST = 'REPOST_REQUEST'
|
||||
export const REPOST_SUCCESS = 'REPOST_SUCCESS'
|
||||
export const REPOST_FAIL = 'REPOST_FAIL'
|
||||
|
||||
export const FAVORITE_REQUEST = 'FAVORITE_REQUEST';
|
||||
export const FAVORITE_SUCCESS = 'FAVORITE_SUCCESS';
|
||||
export const FAVORITE_FAIL = 'FAVORITE_FAIL';
|
||||
export const FAVORITE_REQUEST = 'FAVORITE_REQUEST'
|
||||
export const FAVORITE_SUCCESS = 'FAVORITE_SUCCESS'
|
||||
export const FAVORITE_FAIL = 'FAVORITE_FAIL'
|
||||
|
||||
export const UNREPOST_REQUEST = 'UNREPOST_REQUEST';
|
||||
export const UNREPOST_SUCCESS = 'UNREPOST_SUCCESS';
|
||||
export const UNREPOST_FAIL = 'UNREPOST_FAIL';
|
||||
export const UNREPOST_REQUEST = 'UNREPOST_REQUEST'
|
||||
export const UNREPOST_SUCCESS = 'UNREPOST_SUCCESS'
|
||||
export const UNREPOST_FAIL = 'UNREPOST_FAIL'
|
||||
|
||||
export const UNFAVORITE_REQUEST = 'UNFAVORITE_REQUEST';
|
||||
export const UNFAVORITE_SUCCESS = 'UNFAVORITE_SUCCESS';
|
||||
export const UNFAVORITE_FAIL = 'UNFAVORITE_FAIL';
|
||||
export const UNFAVORITE_REQUEST = 'UNFAVORITE_REQUEST'
|
||||
export const UNFAVORITE_SUCCESS = 'UNFAVORITE_SUCCESS'
|
||||
export const UNFAVORITE_FAIL = 'UNFAVORITE_FAIL'
|
||||
|
||||
export const REPOSTS_FETCH_REQUEST = 'REPOSTS_FETCH_REQUEST';
|
||||
export const REPOSTS_FETCH_SUCCESS = 'REPOSTS_FETCH_SUCCESS';
|
||||
export const REPOSTS_FETCH_FAIL = 'REPOSTS_FETCH_FAIL';
|
||||
export const REPOSTS_FETCH_REQUEST = 'REPOSTS_FETCH_REQUEST'
|
||||
export const REPOSTS_FETCH_SUCCESS = 'REPOSTS_FETCH_SUCCESS'
|
||||
export const REPOSTS_FETCH_FAIL = 'REPOSTS_FETCH_FAIL'
|
||||
|
||||
export const PIN_REQUEST = 'PIN_REQUEST';
|
||||
export const PIN_SUCCESS = 'PIN_SUCCESS';
|
||||
export const PIN_FAIL = 'PIN_FAIL';
|
||||
export const PIN_REQUEST = 'PIN_REQUEST'
|
||||
export const PIN_SUCCESS = 'PIN_SUCCESS'
|
||||
export const PIN_FAIL = 'PIN_FAIL'
|
||||
|
||||
export const UNPIN_REQUEST = 'UNPIN_REQUEST';
|
||||
export const UNPIN_SUCCESS = 'UNPIN_SUCCESS';
|
||||
export const UNPIN_FAIL = 'UNPIN_FAIL';
|
||||
export const UNPIN_REQUEST = 'UNPIN_REQUEST'
|
||||
export const UNPIN_SUCCESS = 'UNPIN_SUCCESS'
|
||||
export const UNPIN_FAIL = 'UNPIN_FAIL'
|
||||
|
||||
export const BOOKMARK_REQUEST = 'BOOKMARK_REQUEST'
|
||||
export const BOOKMARK_SUCCESS = 'BOOKMARK_SUCCESS'
|
||||
@@ -38,392 +39,342 @@ export const UNBOOKMARK_REQUEST = 'UNBOOKMARK_REQUEST'
|
||||
export const UNBOOKMARK_SUCCESS = 'UNBOOKMARK_SUCCESS'
|
||||
export const UNBOOKMARK_FAIL = 'UNBOOKMARK_FAIL'
|
||||
|
||||
export const LIKES_FETCH_REQUEST = 'LIKES_FETCH_REQUEST';
|
||||
export const LIKES_FETCH_SUCCESS = 'LIKES_FETCH_SUCCESS';
|
||||
export const LIKES_FETCH_FAIL = 'LIKES_FETCH_FAIL';
|
||||
export const LIKES_FETCH_REQUEST = 'LIKES_FETCH_REQUEST'
|
||||
export const LIKES_FETCH_SUCCESS = 'LIKES_FETCH_SUCCESS'
|
||||
export const LIKES_FETCH_FAIL = 'LIKES_FETCH_FAIL'
|
||||
|
||||
export function repost(status) {
|
||||
return function (dispatch, getState) {
|
||||
if (!me) return;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const repost = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(repostRequest(status));
|
||||
dispatch(repostRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`).then(function (response) {
|
||||
// The reblog API method returns a new status wrapped around the original. In this case we are only
|
||||
// interested in how the original is modified, hence passing it skipping the wrapper
|
||||
dispatch(importFetchedStatus(response.data.reblog));
|
||||
dispatch(repostSuccess(status));
|
||||
}).catch(function (error) {
|
||||
dispatch(repostFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function unrepost(status) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(unrepostRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then(response => {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(unrepostSuccess(status));
|
||||
}).catch(error => {
|
||||
dispatch(unrepostFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function repostRequest(status) {
|
||||
return {
|
||||
type: REPOST_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function repostSuccess(status) {
|
||||
return {
|
||||
type: REPOST_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function repostFail(status, error) {
|
||||
return {
|
||||
type: REPOST_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unrepostRequest(status) {
|
||||
return {
|
||||
type: UNREPOST_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unrepostSuccess(status) {
|
||||
return {
|
||||
type: UNREPOST_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unrepostFail(status, error) {
|
||||
return {
|
||||
type: UNREPOST_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function favorite(status) {
|
||||
return function (dispatch, getState) {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(favoriteRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function (response) {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(favoriteSuccess(status));
|
||||
}).catch(function (error) {
|
||||
dispatch(favoriteFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function unfavorite(status) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(unfavoriteRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(response => {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(unfavoriteSuccess(status));
|
||||
}).catch(error => {
|
||||
dispatch(unfavoriteFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function favoriteRequest(status) {
|
||||
return {
|
||||
type: FAVORITE_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function favoriteSuccess(status) {
|
||||
return {
|
||||
type: FAVORITE_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function favoriteFail(status, error) {
|
||||
return {
|
||||
type: FAVORITE_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unfavoriteRequest(status) {
|
||||
return {
|
||||
type: UNFAVORITE_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unfavoriteSuccess(status) {
|
||||
return {
|
||||
type: UNFAVORITE_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unfavoriteFail(status, error) {
|
||||
return {
|
||||
type: UNFAVORITE_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchReposts(id) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(fetchRepostsRequest(id));
|
||||
|
||||
api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => {
|
||||
dispatch(importFetchedAccounts(response.data));
|
||||
dispatch(fetchRepostsSuccess(id, response.data));
|
||||
}).catch(error => {
|
||||
dispatch(fetchRepostsFail(id, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchRepostsRequest(id) {
|
||||
return {
|
||||
type: REPOSTS_FETCH_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchRepostsSuccess(id, accounts) {
|
||||
return {
|
||||
type: REPOSTS_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchRepostsFail(id, error) {
|
||||
return {
|
||||
type: REPOSTS_FETCH_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export function pin(status) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(pinRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(pinSuccess(status));
|
||||
}).catch(error => {
|
||||
dispatch(pinFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function pinRequest(status) {
|
||||
return {
|
||||
type: PIN_REQUEST,
|
||||
status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function pinSuccess(status) {
|
||||
return {
|
||||
type: PIN_SUCCESS,
|
||||
status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function pinFail(status, error) {
|
||||
return {
|
||||
type: PIN_FAIL,
|
||||
status,
|
||||
error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpin (status) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(unpinRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(unpinSuccess(status));
|
||||
}).catch(error => {
|
||||
dispatch(unpinFail(status, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinRequest(status) {
|
||||
return {
|
||||
type: UNPIN_REQUEST,
|
||||
status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinSuccess(status) {
|
||||
return {
|
||||
type: UNPIN_SUCCESS,
|
||||
status,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function unpinFail(status, error) {
|
||||
return {
|
||||
type: UNPIN_FAIL,
|
||||
status,
|
||||
error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchLikes(id) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(fetchLikesRequest(id));
|
||||
|
||||
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => {
|
||||
dispatch(importFetchedAccounts(response.data));
|
||||
dispatch(fetchLikesSuccess(id, response.data));
|
||||
}).catch(error => {
|
||||
dispatch(fetchLikesFail(id, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchLikesRequest(id) {
|
||||
return {
|
||||
type: LIKES_FETCH_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchLikesSuccess(id, accounts) {
|
||||
return {
|
||||
type: LIKES_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchLikesFail(id, error) {
|
||||
return {
|
||||
type: LIKES_FETCH_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export function bookmark(status) {
|
||||
return function (dispatch, getState) {
|
||||
dispatch(bookmarkRequest(status));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function (response) {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(bookmarkSuccess(status, response.data));
|
||||
}).catch(function (error) {
|
||||
dispatch(bookmarkFail(status, error))
|
||||
})
|
||||
}
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`).then((response) => {
|
||||
// The reblog API method returns a new status wrapped around the original. In this case we are only
|
||||
// interested in how the original is modified, hence passing it skipping the wrapper
|
||||
dispatch(importFetchedStatus(response.data.reblog))
|
||||
dispatch(repostSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(repostFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function unbookmark(status) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(unbookmarkRequest(status))
|
||||
export const repostRequest = (status) => ({
|
||||
type: REPOST_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(unbookmarkSuccess(status, response.data))
|
||||
}).catch(error => {
|
||||
dispatch(unbookmarkFail(status, error))
|
||||
})
|
||||
}
|
||||
export const repostSuccess = (status) => ({
|
||||
type: REPOST_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const repostFail = (status, error) => ({
|
||||
type: REPOST_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const unrepost = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(unrepostRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(unrepostSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(unrepostFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function bookmarkRequest(status) {
|
||||
return {
|
||||
type: BOOKMARK_REQUEST,
|
||||
status: status,
|
||||
}
|
||||
export const unrepostRequest = (status) => ({
|
||||
type: UNREPOST_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unrepostSuccess = (status) => ({
|
||||
type: UNREPOST_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unrepostFail = (status, error) => ({
|
||||
type: UNREPOST_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const favorite = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(favoriteRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then((response) => {
|
||||
dispatch(updateStatusStats(response.data))
|
||||
dispatch(favoriteSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(favoriteFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function bookmarkSuccess(status, response) {
|
||||
return {
|
||||
type: BOOKMARK_SUCCESS,
|
||||
status: status,
|
||||
response: response,
|
||||
}
|
||||
export const favoriteRequest = (status) => ({
|
||||
type: FAVORITE_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const favoriteSuccess = (status) => ({
|
||||
type: FAVORITE_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const favoriteFail = (status, error) => ({
|
||||
type: FAVORITE_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const unfavorite = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(unfavoriteRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(unfavoriteSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(unfavoriteFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function bookmarkFail(status, error) {
|
||||
return {
|
||||
type: BOOKMARK_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
}
|
||||
export const unfavoriteRequest = (status) => ({
|
||||
type: UNFAVORITE_REQUEST,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unfavoriteSuccess = (status) => ({
|
||||
type: UNFAVORITE_SUCCESS,
|
||||
status: status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unfavoriteFail = (status, error) => ({
|
||||
type: UNFAVORITE_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchReposts = (id) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchRepostsRequest(id))
|
||||
|
||||
api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then((response) => {
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchRepostsSuccess(id, response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchRepostsFail(id, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function unbookmarkRequest(status) {
|
||||
return {
|
||||
type: UNBOOKMARK_REQUEST,
|
||||
status: status,
|
||||
}
|
||||
export const fetchRepostsRequest = (id) => ({
|
||||
type: REPOSTS_FETCH_REQUEST,
|
||||
id,
|
||||
})
|
||||
|
||||
export const fetchRepostsSuccess = (id, accounts) => ({
|
||||
type: REPOSTS_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
})
|
||||
|
||||
export const fetchRepostsFail = (id, error) => ({
|
||||
type: REPOSTS_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const pin = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(pinRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(pinSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(pinFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function unbookmarkSuccess(status, response) {
|
||||
return {
|
||||
type: UNBOOKMARK_SUCCESS,
|
||||
status: status,
|
||||
response: response,
|
||||
}
|
||||
export const pinRequest = (status) => ({
|
||||
type: PIN_REQUEST,
|
||||
status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const pinSuccess = (status) => ({
|
||||
type: PIN_SUCCESS,
|
||||
status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const pinFail = (status, error) => ({
|
||||
type: PIN_FAIL,
|
||||
status,
|
||||
error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const unpin = (status) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(unpinRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(unpinSuccess(status))
|
||||
}).catch((error) => {
|
||||
dispatch(unpinFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export function unbookmarkFail(status, error) {
|
||||
return {
|
||||
type: UNBOOKMARK_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
}
|
||||
}
|
||||
export const unpinRequest = (status) => ({
|
||||
type: UNPIN_REQUEST,
|
||||
status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unpinSuccess = (status) => ({
|
||||
type: UNPIN_SUCCESS,
|
||||
status,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
export const unpinFail = (status, error) => ({
|
||||
type: UNPIN_FAIL,
|
||||
status,
|
||||
error,
|
||||
skipLoading: true,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchLikes = (id) => (dispatch, getState) => {
|
||||
dispatch(fetchLikesRequest(id))
|
||||
|
||||
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then((response) => {
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchLikesSuccess(id, response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchLikesFail(id, error))
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchLikesRequest = (id) => ({
|
||||
type: LIKES_FETCH_REQUEST,
|
||||
id,
|
||||
})
|
||||
|
||||
export const fetchLikesSuccess = (id, accounts) => ({
|
||||
type: LIKES_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
})
|
||||
|
||||
export const fetchLikesFail = (id, error) => ({
|
||||
type: LIKES_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const bookmark = (status) => (dispatch, getState) => {
|
||||
dispatch(bookmarkRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(bookmarkSuccess(status, response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(bookmarkFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export const bookmarkRequest = (status) => ({
|
||||
type: BOOKMARK_REQUEST,
|
||||
status: status,
|
||||
})
|
||||
|
||||
export const bookmarkSuccess = (status, response) => ({
|
||||
type: BOOKMARK_SUCCESS,
|
||||
status: status,
|
||||
response: response,
|
||||
})
|
||||
|
||||
export const bookmarkFail = (status, error) => ({
|
||||
type: BOOKMARK_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const unbookmark = (status) => (dispatch, getState) => {
|
||||
dispatch(unbookmarkRequest(status))
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then((response) => {
|
||||
dispatch(importFetchedStatus(response.data))
|
||||
dispatch(unbookmarkSuccess(status, response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(unbookmarkFail(status, error))
|
||||
})
|
||||
}
|
||||
|
||||
export const unbookmarkRequest = (status) => ({
|
||||
type: UNBOOKMARK_REQUEST,
|
||||
status: status,
|
||||
})
|
||||
|
||||
export const unbookmarkSuccess = (status, response) => ({
|
||||
type: UNBOOKMARK_SUCCESS,
|
||||
status: status,
|
||||
response: response,
|
||||
})
|
||||
|
||||
export const unbookmarkFail = (status, error) => ({
|
||||
type: UNBOOKMARK_FAIL,
|
||||
status: status,
|
||||
error: error,
|
||||
})
|
||||
@@ -10,6 +10,17 @@ export const POPULAR_LINKS_FETCH_FAIL = 'POPULAR_LINKS_FETCH_FAIL'
|
||||
|
||||
export const IMPORT_LINK_CARDS = 'IMPORT_LINK_CARDS'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const importLinkCards = (cards) => ({
|
||||
type: IMPORT_LINK_CARDS,
|
||||
cards,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchLinkCard = (cardId) => (dispatch, getState) => {
|
||||
//If card exists, don't refetch
|
||||
const card = getState().getIn(['links', 'items', `${cardId}`])
|
||||
@@ -39,11 +50,9 @@ export const fetchLinkCardFail = (error, cardId) => ({
|
||||
cardId,
|
||||
})
|
||||
|
||||
export const importLinkCards = (cards) => ({
|
||||
type: IMPORT_LINK_CARDS,
|
||||
cards,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchPopularLinks = () => (dispatch, getState) => {
|
||||
const isFetched = getState().getIn(['links', 'popular', 'isFetched'], false)
|
||||
if (isFetched) return
|
||||
@@ -56,16 +65,16 @@ export const fetchPopularLinks = () => (dispatch, getState) => {
|
||||
.catch((err) => dispatch(fetchPopularLinksFail(err)))
|
||||
}
|
||||
|
||||
export const fetchPopularLinksRequest = () => ({
|
||||
const fetchPopularLinksRequest = () => ({
|
||||
type: POPULAR_LINKS_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
export const fetchPopularLinksSuccess = (cards) => ({
|
||||
const fetchPopularLinksSuccess = (cards) => ({
|
||||
type: POPULAR_LINKS_FETCH_SUCCESS,
|
||||
cards,
|
||||
})
|
||||
|
||||
export const fetchPopularLinksFail = (error) => ({
|
||||
const fetchPopularLinksFail = (error) => ({
|
||||
type: POPULAR_LINKS_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
@@ -1,88 +1,92 @@
|
||||
import api from '../api';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
// import { showAlertForError } from './alerts';
|
||||
import api from '../api'
|
||||
import { importFetchedAccounts } from './importer'
|
||||
// import { showAlertForError } from './alerts'
|
||||
import { me } from '../initial_state'
|
||||
|
||||
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
|
||||
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS';
|
||||
export const LIST_FETCH_FAIL = 'LIST_FETCH_FAIL';
|
||||
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST'
|
||||
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS'
|
||||
export const LIST_FETCH_FAIL = 'LIST_FETCH_FAIL'
|
||||
|
||||
export const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST';
|
||||
export const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS';
|
||||
export const LISTS_FETCH_FAIL = 'LISTS_FETCH_FAIL';
|
||||
export const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST'
|
||||
export const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS'
|
||||
export const LISTS_FETCH_FAIL = 'LISTS_FETCH_FAIL'
|
||||
|
||||
export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE';
|
||||
export const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET';
|
||||
export const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP';
|
||||
export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE'
|
||||
export const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET'
|
||||
export const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP'
|
||||
|
||||
export const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST';
|
||||
export const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS';
|
||||
export const LIST_CREATE_FAIL = 'LIST_CREATE_FAIL';
|
||||
export const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST'
|
||||
export const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS'
|
||||
export const LIST_CREATE_FAIL = 'LIST_CREATE_FAIL'
|
||||
|
||||
export const LIST_UPDATE_REQUEST = 'LIST_UPDATE_REQUEST';
|
||||
export const LIST_UPDATE_SUCCESS = 'LIST_UPDATE_SUCCESS';
|
||||
export const LIST_UPDATE_FAIL = 'LIST_UPDATE_FAIL';
|
||||
export const LIST_UPDATE_REQUEST = 'LIST_UPDATE_REQUEST'
|
||||
export const LIST_UPDATE_SUCCESS = 'LIST_UPDATE_SUCCESS'
|
||||
export const LIST_UPDATE_FAIL = 'LIST_UPDATE_FAIL'
|
||||
|
||||
export const LIST_DELETE_REQUEST = 'LIST_DELETE_REQUEST';
|
||||
export const LIST_DELETE_SUCCESS = 'LIST_DELETE_SUCCESS';
|
||||
export const LIST_DELETE_FAIL = 'LIST_DELETE_FAIL';
|
||||
export const LIST_DELETE_REQUEST = 'LIST_DELETE_REQUEST'
|
||||
export const LIST_DELETE_SUCCESS = 'LIST_DELETE_SUCCESS'
|
||||
export const LIST_DELETE_FAIL = 'LIST_DELETE_FAIL'
|
||||
|
||||
export const LIST_ACCOUNTS_FETCH_REQUEST = 'LIST_ACCOUNTS_FETCH_REQUEST';
|
||||
export const LIST_ACCOUNTS_FETCH_SUCCESS = 'LIST_ACCOUNTS_FETCH_SUCCESS';
|
||||
export const LIST_ACCOUNTS_FETCH_FAIL = 'LIST_ACCOUNTS_FETCH_FAIL';
|
||||
export const LIST_ACCOUNTS_FETCH_REQUEST = 'LIST_ACCOUNTS_FETCH_REQUEST'
|
||||
export const LIST_ACCOUNTS_FETCH_SUCCESS = 'LIST_ACCOUNTS_FETCH_SUCCESS'
|
||||
export const LIST_ACCOUNTS_FETCH_FAIL = 'LIST_ACCOUNTS_FETCH_FAIL'
|
||||
|
||||
export const LIST_EDITOR_SUGGESTIONS_CHANGE = 'LIST_EDITOR_SUGGESTIONS_CHANGE';
|
||||
export const LIST_EDITOR_SUGGESTIONS_READY = 'LIST_EDITOR_SUGGESTIONS_READY';
|
||||
export const LIST_EDITOR_SUGGESTIONS_CLEAR = 'LIST_EDITOR_SUGGESTIONS_CLEAR';
|
||||
export const LIST_EDITOR_SUGGESTIONS_CHANGE = 'LIST_EDITOR_SUGGESTIONS_CHANGE'
|
||||
export const LIST_EDITOR_SUGGESTIONS_READY = 'LIST_EDITOR_SUGGESTIONS_READY'
|
||||
export const LIST_EDITOR_SUGGESTIONS_CLEAR = 'LIST_EDITOR_SUGGESTIONS_CLEAR'
|
||||
|
||||
export const LIST_EDITOR_ADD_REQUEST = 'LIST_EDITOR_ADD_REQUEST';
|
||||
export const LIST_EDITOR_ADD_SUCCESS = 'LIST_EDITOR_ADD_SUCCESS';
|
||||
export const LIST_EDITOR_ADD_FAIL = 'LIST_EDITOR_ADD_FAIL';
|
||||
export const LIST_EDITOR_ADD_REQUEST = 'LIST_EDITOR_ADD_REQUEST'
|
||||
export const LIST_EDITOR_ADD_SUCCESS = 'LIST_EDITOR_ADD_SUCCESS'
|
||||
export const LIST_EDITOR_ADD_FAIL = 'LIST_EDITOR_ADD_FAIL'
|
||||
|
||||
export const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST';
|
||||
export const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS';
|
||||
export const LIST_EDITOR_REMOVE_FAIL = 'LIST_EDITOR_REMOVE_FAIL';
|
||||
export const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST'
|
||||
export const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS'
|
||||
export const LIST_EDITOR_REMOVE_FAIL = 'LIST_EDITOR_REMOVE_FAIL'
|
||||
|
||||
export const LIST_ADDER_RESET = 'LIST_ADDER_RESET';
|
||||
export const LIST_ADDER_SETUP = 'LIST_ADDER_SETUP';
|
||||
export const LIST_ADDER_RESET = 'LIST_ADDER_RESET'
|
||||
export const LIST_ADDER_SETUP = 'LIST_ADDER_SETUP'
|
||||
|
||||
export const LIST_ADDER_LISTS_FETCH_REQUEST = 'LIST_ADDER_LISTS_FETCH_REQUEST';
|
||||
export const LIST_ADDER_LISTS_FETCH_SUCCESS = 'LIST_ADDER_LISTS_FETCH_SUCCESS';
|
||||
export const LIST_ADDER_LISTS_FETCH_FAIL = 'LIST_ADDER_LISTS_FETCH_FAIL';
|
||||
export const LIST_ADDER_LISTS_FETCH_REQUEST = 'LIST_ADDER_LISTS_FETCH_REQUEST'
|
||||
export const LIST_ADDER_LISTS_FETCH_SUCCESS = 'LIST_ADDER_LISTS_FETCH_SUCCESS'
|
||||
export const LIST_ADDER_LISTS_FETCH_FAIL = 'LIST_ADDER_LISTS_FETCH_FAIL'
|
||||
|
||||
export const fetchList = id => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchList = (id) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
if (getState().getIn(['lists', id])) {
|
||||
return;
|
||||
}
|
||||
if (getState().getIn(['lists', id])) return
|
||||
|
||||
dispatch(fetchListRequest(id));
|
||||
dispatch(fetchListRequest(id))
|
||||
|
||||
api(getState).get(`/api/v1/lists/${id}`)
|
||||
.then(({ data }) => dispatch(fetchListSuccess(data)))
|
||||
.catch(err => dispatch(fetchListFail(id, err)));
|
||||
};
|
||||
.catch((err) => dispatch(fetchListFail(id, err)))
|
||||
}
|
||||
|
||||
export const fetchListRequest = id => ({
|
||||
const fetchListRequest = id => ({
|
||||
type: LIST_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListSuccess = list => ({
|
||||
const fetchListSuccess = list => ({
|
||||
type: LIST_FETCH_SUCCESS,
|
||||
list,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListFail = (id, error) => ({
|
||||
const fetchListFail = (id, error) => ({
|
||||
type: LIST_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchLists = () => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
dispatch(fetchListsRequest());
|
||||
dispatch(fetchListsRequest())
|
||||
if (!me) return reject()
|
||||
api(getState).get('/api/v1/lists').then(({ data }) => {
|
||||
dispatch(fetchListsSuccess(data))
|
||||
@@ -90,307 +94,367 @@ export const fetchLists = () => (dispatch, getState) => {
|
||||
}).catch((err) => {
|
||||
dispatch(fetchListsFail(err))
|
||||
return reject()
|
||||
});
|
||||
})
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
export const fetchListsRequest = () => ({
|
||||
const fetchListsRequest = () => ({
|
||||
type: LISTS_FETCH_REQUEST,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListsSuccess = (lists) => ({
|
||||
const fetchListsSuccess = (lists) => ({
|
||||
type: LISTS_FETCH_SUCCESS,
|
||||
lists,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListsFail = (error) => ({
|
||||
const fetchListsFail = (error) => ({
|
||||
type: LISTS_FETCH_FAIL,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const submitListEditor = (shouldReset) => (dispatch, getState) => {
|
||||
const listId = getState().getIn(['listEditor', 'listId']);
|
||||
const title = getState().getIn(['listEditor', 'title']);
|
||||
const listId = getState().getIn(['listEditor', 'listId'])
|
||||
const title = getState().getIn(['listEditor', 'title'])
|
||||
|
||||
if (listId === null) {
|
||||
dispatch(createList(title, shouldReset));
|
||||
dispatch(createList(title, shouldReset))
|
||||
} else {
|
||||
dispatch(updateList(listId, title, shouldReset));
|
||||
dispatch(updateList(listId, title, shouldReset))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const setupListEditor = (listId) => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: LIST_EDITOR_SETUP,
|
||||
list: getState().getIn(['lists', listId]),
|
||||
});
|
||||
})
|
||||
|
||||
dispatch(fetchListAccounts(listId));
|
||||
};
|
||||
dispatch(fetchListAccounts(listId))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeListEditorTitle = (value) => ({
|
||||
type: LIST_EDITOR_TITLE_CHANGE,
|
||||
value,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const createList = (title, shouldReset) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(createListRequest());
|
||||
dispatch(createListRequest())
|
||||
|
||||
api(getState).post('/api/v1/lists', { title }).then(({ data }) => {
|
||||
dispatch(createListSuccess(data));
|
||||
dispatch(createListSuccess(data))
|
||||
|
||||
if (shouldReset) {
|
||||
dispatch(resetListEditor());
|
||||
dispatch(resetListEditor())
|
||||
}
|
||||
}).catch(err => dispatch(createListFail(err)));
|
||||
};
|
||||
}).catch((err) => dispatch(createListFail(err)))
|
||||
}
|
||||
|
||||
export const createListRequest = () => ({
|
||||
type: LIST_CREATE_REQUEST,
|
||||
});
|
||||
})
|
||||
|
||||
export const createListSuccess = (list) => ({
|
||||
type: LIST_CREATE_SUCCESS,
|
||||
list,
|
||||
});
|
||||
})
|
||||
|
||||
export const createListFail = (error) => ({
|
||||
type: LIST_CREATE_FAIL,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const updateList = (id, title, shouldReset) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(updateListRequest(id));
|
||||
dispatch(updateListRequest(id))
|
||||
|
||||
api(getState).put(`/api/v1/lists/${id}`, { title }).then(({ data }) => {
|
||||
dispatch(updateListSuccess(data));
|
||||
dispatch(updateListSuccess(data))
|
||||
|
||||
if (shouldReset) {
|
||||
dispatch(resetListEditor());
|
||||
dispatch(resetListEditor())
|
||||
}
|
||||
}).catch(err => dispatch(updateListFail(id, err)));
|
||||
};
|
||||
}).catch((err) => dispatch(updateListFail(id, err)))
|
||||
}
|
||||
|
||||
export const updateListRequest = id => ({
|
||||
type: LIST_UPDATE_REQUEST,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const updateListSuccess = list => ({
|
||||
type: LIST_UPDATE_SUCCESS,
|
||||
list,
|
||||
});
|
||||
})
|
||||
|
||||
export const updateListFail = (id, error) => ({
|
||||
type: LIST_UPDATE_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
export const resetListEditor = () => ({
|
||||
type: LIST_EDITOR_RESET,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const deleteList = (id) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(deleteListRequest(id));
|
||||
dispatch(deleteListRequest(id))
|
||||
|
||||
api(getState).delete(`/api/v1/lists/${id}`)
|
||||
.then(() => dispatch(deleteListSuccess(id)))
|
||||
.catch(err => dispatch(deleteListFail(id, err)));
|
||||
};
|
||||
.catch((err) => dispatch(deleteListFail(id, err)))
|
||||
}
|
||||
|
||||
export const deleteListRequest = (id) => ({
|
||||
type: LIST_DELETE_REQUEST,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const deleteListSuccess = (id) => ({
|
||||
type: LIST_DELETE_SUCCESS,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const deleteListFail = (id, error) => ({
|
||||
type: LIST_DELETE_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchListAccounts = (listId) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchListAccountsRequest(listId));
|
||||
dispatch(fetchListAccountsRequest(listId))
|
||||
|
||||
api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(fetchListAccountsSuccess(listId, data));
|
||||
}).catch(err => dispatch(fetchListAccountsFail(listId, err)));
|
||||
};
|
||||
dispatch(importFetchedAccounts(data))
|
||||
dispatch(fetchListAccountsSuccess(listId, data))
|
||||
}).catch((err) => dispatch(fetchListAccountsFail(listId, err)))
|
||||
}
|
||||
|
||||
export const fetchListAccountsRequest = (id) => ({
|
||||
type: LIST_ACCOUNTS_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListAccountsSuccess = (id, accounts, next) => ({
|
||||
type: LIST_ACCOUNTS_FETCH_SUCCESS,
|
||||
id,
|
||||
accounts,
|
||||
next,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchListAccountsFail = (id, error) => ({
|
||||
type: LIST_ACCOUNTS_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchListSuggestions = (q) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
const params = {
|
||||
q,
|
||||
resolve: false,
|
||||
limit: 25,
|
||||
};
|
||||
}
|
||||
|
||||
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(fetchListSuggestionsReady(q, data));
|
||||
dispatch(importFetchedAccounts(data))
|
||||
dispatch(fetchListSuggestionsReady(q, data))
|
||||
})
|
||||
// }).catch(error => dispatch(showAlertForError(error)));
|
||||
};
|
||||
// }).catch(error => dispatch(showAlertForError(error)))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchListSuggestionsReady = (query, accounts) => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_READY,
|
||||
query,
|
||||
accounts,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const clearListSuggestions = () => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_CLEAR,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeListSuggestions = (value) => ({
|
||||
type: LIST_EDITOR_SUGGESTIONS_CHANGE,
|
||||
value,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const addToListEditor = accountId => (dispatch, getState) => {
|
||||
dispatch(addToList(getState().getIn(['listEditor', 'listId']), accountId));
|
||||
};
|
||||
dispatch(addToList(getState().getIn(['listEditor', 'listId']), accountId))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const addToList = (listId, accountId) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(addToListRequest(listId, accountId));
|
||||
dispatch(addToListRequest(listId, accountId))
|
||||
|
||||
api(getState).post(`/api/v1/lists/${listId}/accounts`, { account_ids: [accountId] })
|
||||
.then(() => dispatch(addToListSuccess(listId, accountId)))
|
||||
.catch(err => dispatch(addToListFail(listId, accountId, err)));
|
||||
};
|
||||
.catch((err) => dispatch(addToListFail(listId, accountId, err)))
|
||||
}
|
||||
|
||||
export const addToListRequest = (listId, accountId) => ({
|
||||
const addToListRequest = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_ADD_REQUEST,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
})
|
||||
|
||||
export const addToListSuccess = (listId, accountId) => ({
|
||||
const addToListSuccess = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_ADD_SUCCESS,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
})
|
||||
|
||||
export const addToListFail = (listId, accountId, error) => ({
|
||||
const addToListFail = (listId, accountId, error) => ({
|
||||
type: LIST_EDITOR_ADD_FAIL,
|
||||
listId,
|
||||
accountId,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const removeFromListEditor = accountId => (dispatch, getState) => {
|
||||
dispatch(removeFromList(getState().getIn(['listEditor', 'listId']), accountId));
|
||||
};
|
||||
dispatch(removeFromList(getState().getIn(['listEditor', 'listId']), accountId))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const removeFromList = (listId, accountId) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(removeFromListRequest(listId, accountId));
|
||||
dispatch(removeFromListRequest(listId, accountId))
|
||||
|
||||
api(getState).delete(`/api/v1/lists/${listId}/accounts`, { params: { account_ids: [accountId] } })
|
||||
.then(() => dispatch(removeFromListSuccess(listId, accountId)))
|
||||
.catch(err => dispatch(removeFromListFail(listId, accountId, err)));
|
||||
};
|
||||
.catch((err) => dispatch(removeFromListFail(listId, accountId, err)))
|
||||
}
|
||||
|
||||
export const removeFromListRequest = (listId, accountId) => ({
|
||||
const removeFromListRequest = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_REMOVE_REQUEST,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
})
|
||||
|
||||
export const removeFromListSuccess = (listId, accountId) => ({
|
||||
const removeFromListSuccess = (listId, accountId) => ({
|
||||
type: LIST_EDITOR_REMOVE_SUCCESS,
|
||||
listId,
|
||||
accountId,
|
||||
});
|
||||
})
|
||||
|
||||
export const removeFromListFail = (listId, accountId, error) => ({
|
||||
const removeFromListFail = (listId, accountId, error) => ({
|
||||
type: LIST_EDITOR_REMOVE_FAIL,
|
||||
listId,
|
||||
accountId,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const resetListAdder = () => ({
|
||||
type: LIST_ADDER_RESET,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const setupListAdder = accountId => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: LIST_ADDER_SETUP,
|
||||
account: getState().getIn(['accounts', accountId]),
|
||||
});
|
||||
dispatch(fetchLists());
|
||||
dispatch(fetchAccountLists(accountId));
|
||||
};
|
||||
})
|
||||
dispatch(fetchLists())
|
||||
dispatch(fetchAccountLists(accountId))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchAccountLists = (accountId) => (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchAccountListsRequest(accountId));
|
||||
dispatch(fetchAccountListsRequest(accountId))
|
||||
|
||||
api(getState).get(`/api/v1/accounts/${accountId}/lists`)
|
||||
.then(({ data }) => dispatch(fetchAccountListsSuccess(accountId, data)))
|
||||
.catch(err => dispatch(fetchAccountListsFail(accountId, err)));
|
||||
};
|
||||
.catch((err) => dispatch(fetchAccountListsFail(accountId, err)))
|
||||
}
|
||||
|
||||
export const fetchAccountListsRequest = (id) => ({
|
||||
const fetchAccountListsRequest = (id) => ({
|
||||
type:LIST_ADDER_LISTS_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchAccountListsSuccess = (id, lists) => ({
|
||||
const fetchAccountListsSuccess = (id, lists) => ({
|
||||
type: LIST_ADDER_LISTS_FETCH_SUCCESS,
|
||||
id,
|
||||
lists,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchAccountListsFail = (id, err) => ({
|
||||
const fetchAccountListsFail = (id, err) => ({
|
||||
type: LIST_ADDER_LISTS_FETCH_FAIL,
|
||||
id,
|
||||
err,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const addToListAdder = (listId) => (dispatch, getState) => {
|
||||
dispatch(addToList(listId, getState().getIn(['listAdder', 'accountId'])));
|
||||
};
|
||||
dispatch(addToList(listId, getState().getIn(['listAdder', 'accountId'])))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const removeFromListAdder = (listId) => (dispatch, getState) => {
|
||||
dispatch(removeFromList(listId, getState().getIn(['listAdder', 'accountId'])));
|
||||
};
|
||||
dispatch(removeFromList(listId, getState().getIn(['listAdder', 'accountId'])))
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
export const MODAL_OPEN = 'MODAL_OPEN'
|
||||
export const MODAL_CLOSE = 'MODAL_CLOSE'
|
||||
|
||||
export function openModal(type, props) {
|
||||
return {
|
||||
type: MODAL_OPEN,
|
||||
modalType: type,
|
||||
modalProps: props,
|
||||
}
|
||||
}
|
||||
export const openModal = (type, props) => ({
|
||||
type: MODAL_OPEN,
|
||||
modalType: type,
|
||||
modalProps: props,
|
||||
})
|
||||
|
||||
export function closeModal() {
|
||||
return {
|
||||
type: MODAL_CLOSE,
|
||||
}
|
||||
}
|
||||
export const closeModal = () => ({
|
||||
type: MODAL_CLOSE,
|
||||
})
|
||||
|
||||
@@ -1,103 +1,95 @@
|
||||
import api, { getLinks } from '../api';
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { openModal } from './modal';
|
||||
import { me } from '../initial_state';
|
||||
import api, { getLinks } from '../api'
|
||||
import { fetchRelationships } from './accounts'
|
||||
import { importFetchedAccounts } from './importer'
|
||||
import { openModal } from './modal'
|
||||
import { me } from '../initial_state'
|
||||
import { MODAL_MUTE } from '../constants'
|
||||
|
||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
|
||||
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';
|
||||
export const MUTES_FETCH_FAIL = 'MUTES_FETCH_FAIL';
|
||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST'
|
||||
export const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS'
|
||||
export const MUTES_FETCH_FAIL = 'MUTES_FETCH_FAIL'
|
||||
|
||||
export const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST';
|
||||
export const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS';
|
||||
export const MUTES_EXPAND_FAIL = 'MUTES_EXPAND_FAIL';
|
||||
export const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST'
|
||||
export const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS'
|
||||
export const MUTES_EXPAND_FAIL = 'MUTES_EXPAND_FAIL'
|
||||
|
||||
export const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL';
|
||||
export const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL'
|
||||
|
||||
export function fetchMutes() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchMutes = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchMutesRequest());
|
||||
dispatch(fetchMutesRequest())
|
||||
|
||||
api(getState).get('/api/v1/mutes').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
dispatch(importFetchedAccounts(response.data));
|
||||
dispatch(fetchMutesSuccess(response.data, next ? next.uri : null));
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)));
|
||||
}).catch(error => dispatch(fetchMutesFail(error)));
|
||||
};
|
||||
};
|
||||
api(getState).get('/api/v1/mutes').then((response) => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchMutesSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch((error) => dispatch(fetchMutesFail(error)))
|
||||
}
|
||||
|
||||
export function fetchMutesRequest() {
|
||||
return {
|
||||
type: MUTES_FETCH_REQUEST,
|
||||
};
|
||||
};
|
||||
const fetchMutesRequest = () => ({
|
||||
type: MUTES_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchMutesSuccess(accounts, next) {
|
||||
return {
|
||||
type: MUTES_FETCH_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
};
|
||||
};
|
||||
const fetchMutesSuccess = (accounts, next) => ({
|
||||
type: MUTES_FETCH_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
})
|
||||
|
||||
export function fetchMutesFail(error) {
|
||||
return {
|
||||
type: MUTES_FETCH_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
const fetchMutesFail = (error) => ({
|
||||
type: MUTES_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
export function expandMutes() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
const url = getState().getIn(['user_lists', 'mutes', me, 'next']);
|
||||
const isLoading = getState().getIn(['user_lists', 'mutes', me, 'isLoading']);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const expandMutes = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const url = getState().getIn(['user_lists', 'mutes', me, 'next'])
|
||||
const isLoading = getState().getIn(['user_lists', 'mutes', me, 'isLoading'])
|
||||
|
||||
if (url === null || isLoading) return
|
||||
if (url === null || isLoading) return
|
||||
|
||||
dispatch(expandMutesRequest());
|
||||
dispatch(expandMutesRequest())
|
||||
|
||||
api(getState).get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
dispatch(importFetchedAccounts(response.data));
|
||||
dispatch(expandMutesSuccess(response.data, next ? next.uri : null));
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)));
|
||||
}).catch(error => dispatch(expandMutesFail(error)));
|
||||
};
|
||||
};
|
||||
api(getState).get(url).then((response) => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(expandMutesSuccess(response.data, next ? next.uri : null))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch((error) => dispatch(expandMutesFail(error)))
|
||||
}
|
||||
|
||||
export function expandMutesRequest() {
|
||||
return {
|
||||
type: MUTES_EXPAND_REQUEST,
|
||||
};
|
||||
};
|
||||
const expandMutesRequest = () => ({
|
||||
type: MUTES_EXPAND_REQUEST,
|
||||
})
|
||||
|
||||
export function expandMutesSuccess(accounts, next) {
|
||||
return {
|
||||
type: MUTES_EXPAND_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
};
|
||||
};
|
||||
const expandMutesSuccess = (accounts, next) => ({
|
||||
type: MUTES_EXPAND_SUCCESS,
|
||||
accounts,
|
||||
next,
|
||||
})
|
||||
|
||||
export function expandMutesFail(error) {
|
||||
return {
|
||||
type: MUTES_EXPAND_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
export const expandMutesFail = (error) => ({
|
||||
type: MUTES_EXPAND_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
export function initMuteModal(account) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: MUTES_INIT_MODAL,
|
||||
account,
|
||||
});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const initMuteModal = (account) => (dispatch) => {
|
||||
dispatch({
|
||||
type: MUTES_INIT_MODAL,
|
||||
account,
|
||||
})
|
||||
|
||||
dispatch(openModal('MUTE'));
|
||||
};
|
||||
dispatch(openModal(MODAL_MUTE))
|
||||
}
|
||||
@@ -30,7 +30,6 @@ export const fetchGabTrends = () => (dispatch, getState) => {
|
||||
dispatch(fetchGabTrendsRequest())
|
||||
|
||||
const url = 'https://trends.gab.com/partner'
|
||||
// api(getState).get(`/api/v1/gab_trends?type=partner`).then((response) => {
|
||||
axios.get(url).then((response) => {
|
||||
dispatch(fetchGabTrendsSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
@@ -65,7 +64,6 @@ export const expandGabTrendsFeed = (feedId) => (dispatch, getState) => {
|
||||
dispatch(expandGabTrendsFeedRequest(feedId))
|
||||
|
||||
const url = `https://trends.gab.com/feed/${feedId}?fmt=json&p=${page}`
|
||||
// api(getState).get(`/api/v1/gab_trends?type=rss&page=${page}&feedId=${feedId}`).then((response) => {
|
||||
axios.get(url).then((response) => {
|
||||
dispatch(expandGabTrendsFeedSuccess(response.data.rssFeedItems, feedId, response.data.pagination.p))
|
||||
}).catch((error) => {
|
||||
@@ -102,8 +100,7 @@ export const fetchGabNews = () => (dispatch, getState) => {
|
||||
dispatch(fetchGabNewsRequest())
|
||||
|
||||
const url = 'https://news.gab.com/feed/?feed=json'
|
||||
// api(getState).get(`/api/v1/gab_trends?type=news`).then((response) => {
|
||||
axios.get(url).then((response) => {
|
||||
axios.get(url).then((response) => {
|
||||
dispatch(fetchGabNewsSuccess(response.data.items))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchGabNewsFail(error))
|
||||
|
||||
@@ -1,278 +1,283 @@
|
||||
import api, { getLinks } from '../api';
|
||||
import IntlMessageFormat from 'intl-messageformat';
|
||||
import { fetchRelationships } from './accounts';
|
||||
import api, { getLinks } from '../api'
|
||||
import IntlMessageFormat from 'intl-messageformat'
|
||||
import { fetchRelationships } from './accounts'
|
||||
import {
|
||||
importFetchedAccount,
|
||||
importFetchedAccounts,
|
||||
importFetchedStatus,
|
||||
importFetchedStatuses,
|
||||
} from './importer';
|
||||
import { defineMessages } from 'react-intl';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { unescapeHTML } from '../utils/html';
|
||||
import { getFilters, regexFromFilters } from '../selectors';
|
||||
import { me } from '../initial_state';
|
||||
} from './importer'
|
||||
import { defineMessages } from 'react-intl'
|
||||
import { List as ImmutableList } from 'immutable'
|
||||
import { unescapeHTML } from '../utils/html'
|
||||
import { getFilters, regexFromFilters } from '../selectors'
|
||||
import { me } from '../initial_state'
|
||||
import { NOTIFICATION_FILTERS } from '../constants'
|
||||
|
||||
export const NOTIFICATIONS_INITIALIZE = 'NOTIFICATIONS_INITIALIZE';
|
||||
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
|
||||
export const NOTIFICATIONS_UPDATE_QUEUE = 'NOTIFICATIONS_UPDATE_QUEUE';
|
||||
export const NOTIFICATIONS_DEQUEUE = 'NOTIFICATIONS_DEQUEUE';
|
||||
export const NOTIFICATIONS_INITIALIZE = 'NOTIFICATIONS_INITIALIZE'
|
||||
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE'
|
||||
export const NOTIFICATIONS_UPDATE_QUEUE = 'NOTIFICATIONS_UPDATE_QUEUE'
|
||||
export const NOTIFICATIONS_DEQUEUE = 'NOTIFICATIONS_DEQUEUE'
|
||||
|
||||
export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
|
||||
export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
|
||||
export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL';
|
||||
export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST'
|
||||
export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS'
|
||||
export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL'
|
||||
|
||||
export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET';
|
||||
export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET'
|
||||
|
||||
export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
|
||||
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
|
||||
export const NOTIFICATIONS_MARK_READ = 'NOTIFICATIONS_MARK_READ';
|
||||
export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR'
|
||||
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP'
|
||||
export const NOTIFICATIONS_MARK_READ = 'NOTIFICATIONS_MARK_READ'
|
||||
|
||||
export const MAX_QUEUED_NOTIFICATIONS = 40
|
||||
|
||||
defineMessages({
|
||||
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
||||
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
|
||||
});
|
||||
})
|
||||
|
||||
const fetchRelatedRelationships = (dispatch, notifications) => {
|
||||
const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id);
|
||||
const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id)
|
||||
|
||||
if (accountIds.length > 0) {
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
dispatch(fetchRelationships(accountIds))
|
||||
}
|
||||
}
|
||||
|
||||
export function initializeNotifications() {
|
||||
return {
|
||||
type: NOTIFICATIONS_INITIALIZE,
|
||||
}
|
||||
}
|
||||
|
||||
export function updateNotifications(notification, intlMessages, intlLocale) {
|
||||
return (dispatch, getState) => {
|
||||
const showInColumn = getState().getIn(['notifications', 'filter', notification.type], true);
|
||||
|
||||
if (showInColumn) {
|
||||
dispatch(importFetchedAccount(notification.account));
|
||||
|
||||
if (notification.status) {
|
||||
dispatch(importFetchedStatus(notification.status));
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE,
|
||||
notification,
|
||||
});
|
||||
|
||||
fetchRelatedRelationships(dispatch, [notification]);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export function updateNotificationsQueue(notification, intlMessages, intlLocale, curPath) {
|
||||
return (dispatch, getState) => {
|
||||
// : todo :
|
||||
// const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
|
||||
const filters = getFilters(getState(), { contextType: 'notifications' });
|
||||
|
||||
let filtered = false;
|
||||
|
||||
const isOnNotificationsPage = curPath === '/notifications';
|
||||
|
||||
if (notification.type === 'mention') {
|
||||
const regex = regexFromFilters(filters);
|
||||
const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content);
|
||||
filtered = regex && regex.test(searchIndex);
|
||||
}
|
||||
|
||||
// Desktop notifications
|
||||
// : todo :
|
||||
// if (typeof window.Notification !== 'undefined' && showAlert && !filtered) {
|
||||
// const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
|
||||
// const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
|
||||
|
||||
// const notify = new Notification(title, { body, icon: notification.account.avatar, tag: notification.id });
|
||||
|
||||
// notify.addEventListener('click', () => {
|
||||
// window.focus();
|
||||
// notify.close();
|
||||
// });
|
||||
// }
|
||||
|
||||
if (isOnNotificationsPage) {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE_QUEUE,
|
||||
notification,
|
||||
intlMessages,
|
||||
intlLocale,
|
||||
});
|
||||
} else {
|
||||
dispatch(updateNotifications(notification, intlMessages, intlLocale));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function forceDequeueNotifications() {
|
||||
return (dispatch,) => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_DEQUEUE,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function dequeueNotifications() {
|
||||
return (dispatch, getState) => {
|
||||
const queuedNotifications = getState().getIn(['notifications', 'queuedNotifications'], ImmutableList());
|
||||
const totalQueuedNotificationsCount = getState().getIn(['notifications', 'totalQueuedNotificationsCount'], 0);
|
||||
|
||||
if (totalQueuedNotificationsCount === 0) {
|
||||
return;
|
||||
} else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) {
|
||||
queuedNotifications.forEach(block => {
|
||||
dispatch(updateNotifications(block.notification, block.intlMessages, block.intlLocale));
|
||||
});
|
||||
} else {
|
||||
dispatch(expandNotifications());
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_DEQUEUE,
|
||||
});
|
||||
dispatch(markReadNotifications());
|
||||
}
|
||||
};
|
||||
|
||||
const excludeTypesFromFilter = filter => {
|
||||
const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention', 'poll']);
|
||||
return allTypes.filterNot(item => item === filter).toJS();
|
||||
};
|
||||
const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention', 'poll'])
|
||||
return allTypes.filterNot(item => item === filter).toJS()
|
||||
}
|
||||
|
||||
const noOp = () => {}
|
||||
|
||||
export function expandNotifications({ maxId } = {}, done = noOp) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const initializeNotifications = () => ({
|
||||
type: NOTIFICATIONS_INITIALIZE,
|
||||
})
|
||||
|
||||
const onlyVerified = getState().getIn(['notifications', 'filter', 'onlyVerified'])
|
||||
const onlyFollowing = getState().getIn(['notifications', 'filter', 'onlyFollowing'])
|
||||
const activeFilter = getState().getIn(['notifications', 'filter', 'active'])
|
||||
const notifications = getState().get('notifications')
|
||||
const isLoadingMore = !!maxId
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const updateNotifications = (notification, intlMessages, intlLocale) => (dispatch, getState) => {
|
||||
const showInColumn = getState().getIn(['notifications', 'filter', notification.type], true)
|
||||
|
||||
if (notifications.get('isLoading') || activeFilter === 'follow_requests') {
|
||||
done();
|
||||
return;
|
||||
if (showInColumn) {
|
||||
dispatch(importFetchedAccount(notification.account))
|
||||
|
||||
if (notification.status) {
|
||||
dispatch(importFetchedStatus(notification.status))
|
||||
}
|
||||
|
||||
const params = {
|
||||
max_id: maxId,
|
||||
exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter),
|
||||
}
|
||||
|
||||
if (!!onlyVerified) params.only_verified = onlyVerified
|
||||
if (!!onlyFollowing) params.only_following = onlyFollowing
|
||||
|
||||
if (!maxId && notifications.get('items').size > 0) {
|
||||
params.since_id = notifications.getIn(['items', 0, 'id']);
|
||||
}
|
||||
|
||||
dispatch(expandNotificationsRequest(isLoadingMore));
|
||||
|
||||
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
|
||||
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
|
||||
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
|
||||
|
||||
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore));
|
||||
|
||||
fetchRelatedRelationships(dispatch, response.data);
|
||||
|
||||
done();
|
||||
}).catch(error => {
|
||||
dispatch(expandNotificationsFail(error, isLoadingMore));
|
||||
done();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function expandNotificationsRequest(isLoadingMore) {
|
||||
return {
|
||||
type: NOTIFICATIONS_EXPAND_REQUEST,
|
||||
skipLoading: !isLoadingMore,
|
||||
};
|
||||
};
|
||||
|
||||
export function expandNotificationsSuccess(notifications, next, isLoadingMore) {
|
||||
return {
|
||||
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||
notifications,
|
||||
next,
|
||||
skipLoading: !isLoadingMore,
|
||||
};
|
||||
};
|
||||
|
||||
export function expandNotificationsFail(error, isLoadingMore) {
|
||||
return {
|
||||
type: NOTIFICATIONS_EXPAND_FAIL,
|
||||
error,
|
||||
skipLoading: !isLoadingMore,
|
||||
};
|
||||
};
|
||||
|
||||
export function clearNotifications() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_CLEAR,
|
||||
});
|
||||
|
||||
api(getState).post('/api/v1/notifications/clear');
|
||||
};
|
||||
};
|
||||
|
||||
export function scrollTopNotifications(top) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_SCROLL_TOP,
|
||||
top,
|
||||
});
|
||||
dispatch(markReadNotifications());
|
||||
}
|
||||
};
|
||||
|
||||
export function setFilter(path, value) {
|
||||
return (dispatch) => {
|
||||
if (path === 'active' && NOTIFICATION_FILTERS.indexOf(value) === -1) return
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_FILTER_SET,
|
||||
path: path,
|
||||
value: value,
|
||||
type: NOTIFICATIONS_UPDATE,
|
||||
notification,
|
||||
})
|
||||
dispatch(expandNotifications())
|
||||
|
||||
fetchRelatedRelationships(dispatch, [notification])
|
||||
}
|
||||
}
|
||||
|
||||
export function markReadNotifications() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const topNotification = parseInt(getState().getIn(['notifications', 'items', 0, 'id']))
|
||||
const lastReadId = getState().getIn(['notifications', 'lastReadId'])
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const updateNotificationsQueue = (notification, intlMessages, intlLocale, curPath) => (dispatch, getState) => {
|
||||
// : todo :
|
||||
// const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true)
|
||||
const filters = getFilters(getState(), { contextType: 'notifications' })
|
||||
|
||||
if (topNotification && topNotification > lastReadId && lastReadId !== -1) {
|
||||
api(getState).post('/api/v1/notifications/mark_read', {
|
||||
id: topNotification
|
||||
}).then(() => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_MARK_READ,
|
||||
notification: topNotification,
|
||||
})
|
||||
let filtered = false
|
||||
|
||||
const isOnNotificationsPage = curPath === '/notifications'
|
||||
|
||||
if (notification.type === 'mention') {
|
||||
const regex = regexFromFilters(filters)
|
||||
const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content)
|
||||
filtered = regex && regex.test(searchIndex)
|
||||
}
|
||||
|
||||
// Desktop notifications
|
||||
// : todo :
|
||||
// if (typeof window.Notification !== 'undefined' && showAlert && !filtered) {
|
||||
// const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username })
|
||||
// const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '')
|
||||
|
||||
// const notify = new Notification(title, { body, icon: notification.account.avatar, tag: notification.id })
|
||||
|
||||
// notify.addEventListener('click', () => {
|
||||
// window.focus()
|
||||
// notify.close()
|
||||
// })
|
||||
// }
|
||||
|
||||
if (isOnNotificationsPage) {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE_QUEUE,
|
||||
notification,
|
||||
intlMessages,
|
||||
intlLocale,
|
||||
})
|
||||
} else {
|
||||
dispatch(updateNotifications(notification, intlMessages, intlLocale))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const forceDequeueNotifications = () => (dispatch) => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_DEQUEUE,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const dequeueNotifications = () => (dispatch, getState) => {
|
||||
const queuedNotifications = getState().getIn(['notifications', 'queuedNotifications'], ImmutableList())
|
||||
const totalQueuedNotificationsCount = getState().getIn(['notifications', 'totalQueuedNotificationsCount'], 0)
|
||||
|
||||
if (totalQueuedNotificationsCount === 0) {
|
||||
return
|
||||
} else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) {
|
||||
queuedNotifications.forEach((block) => {
|
||||
dispatch(updateNotifications(block.notification, block.intlMessages, block.intlLocale))
|
||||
})
|
||||
} else {
|
||||
dispatch(expandNotifications())
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_DEQUEUE,
|
||||
})
|
||||
dispatch(markReadNotifications())
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const expandNotifications = ({ maxId } = {}, done = noOp) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const onlyVerified = getState().getIn(['notifications', 'filter', 'onlyVerified'])
|
||||
const onlyFollowing = getState().getIn(['notifications', 'filter', 'onlyFollowing'])
|
||||
const activeFilter = getState().getIn(['notifications', 'filter', 'active'])
|
||||
const notifications = getState().get('notifications')
|
||||
const isLoadingMore = !!maxId
|
||||
|
||||
if (notifications.get('isLoading') || notifications.get('isError')|| activeFilter === 'follow_requests') {
|
||||
done()
|
||||
return
|
||||
}
|
||||
|
||||
const params = {
|
||||
max_id: maxId,
|
||||
exclude_types: activeFilter === 'all' ? null : excludeTypesFromFilter(activeFilter),
|
||||
}
|
||||
|
||||
if (!!onlyVerified) params.only_verified = onlyVerified
|
||||
if (!!onlyFollowing) params.only_following = onlyFollowing
|
||||
|
||||
if (!maxId && notifications.get('items').size > 0) {
|
||||
params.since_id = notifications.getIn(['items', 0, 'id'])
|
||||
}
|
||||
|
||||
dispatch(expandNotificationsRequest(isLoadingMore))
|
||||
|
||||
api(getState).get('/api/v1/notifications', { params }).then((response) => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
|
||||
dispatch(importFetchedAccounts(response.data.map(item => item.account)))
|
||||
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)))
|
||||
|
||||
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore))
|
||||
|
||||
fetchRelatedRelationships(dispatch, response.data)
|
||||
|
||||
done()
|
||||
}).catch((error) => {
|
||||
dispatch(expandNotificationsFail(error, isLoadingMore))
|
||||
done()
|
||||
})
|
||||
}
|
||||
|
||||
export const expandNotificationsRequest = (isLoadingMore) => ({
|
||||
type: NOTIFICATIONS_EXPAND_REQUEST,
|
||||
skipLoading: !isLoadingMore,
|
||||
})
|
||||
|
||||
export const expandNotificationsSuccess = (notifications, next, isLoadingMore) => ({
|
||||
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||
notifications,
|
||||
next,
|
||||
skipLoading: !isLoadingMore,
|
||||
})
|
||||
|
||||
export const expandNotificationsFail = (error, isLoadingMore) => ({
|
||||
type: NOTIFICATIONS_EXPAND_FAIL,
|
||||
error,
|
||||
skipLoading: !isLoadingMore,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// : todo : implement with alert/warning
|
||||
export const clearNotifications = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_CLEAR,
|
||||
})
|
||||
|
||||
api(getState).post('/api/v1/notifications/clear')
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const scrollTopNotifications = (top) => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_SCROLL_TOP,
|
||||
top,
|
||||
})
|
||||
dispatch(markReadNotifications())
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const setFilter = (path, value) => (dispatch) => {
|
||||
if (path === 'active' && NOTIFICATION_FILTERS.indexOf(value) === -1) return
|
||||
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_FILTER_SET,
|
||||
path: path,
|
||||
value: value,
|
||||
})
|
||||
dispatch(expandNotifications())
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const markReadNotifications = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const topNotification = parseInt(getState().getIn(['notifications', 'items', 0, 'id']))
|
||||
const lastReadId = getState().getIn(['notifications', 'lastReadId'])
|
||||
|
||||
if (topNotification && topNotification > lastReadId && lastReadId !== -1) {
|
||||
api(getState).post('/api/v1/notifications/mark_read', {
|
||||
id: topNotification
|
||||
}).then(() => {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_MARK_READ,
|
||||
notification: topNotification,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { changeSetting, saveSettings } from './settings'
|
||||
|
||||
export const saveShownOnboarding = () => (dispatch) => {
|
||||
dispatch(changeSetting(['shownOnboarding'], true))
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
@@ -1,60 +1,66 @@
|
||||
import api from '../api';
|
||||
import { importFetchedPoll } from './importer';
|
||||
import api from '../api'
|
||||
import { importFetchedPoll } from './importer'
|
||||
|
||||
export const POLL_VOTE_REQUEST = 'POLL_VOTE_REQUEST';
|
||||
export const POLL_VOTE_SUCCESS = 'POLL_VOTE_SUCCESS';
|
||||
export const POLL_VOTE_FAIL = 'POLL_VOTE_FAIL';
|
||||
export const POLL_VOTE_REQUEST = 'POLL_VOTE_REQUEST'
|
||||
export const POLL_VOTE_SUCCESS = 'POLL_VOTE_SUCCESS'
|
||||
export const POLL_VOTE_FAIL = 'POLL_VOTE_FAIL'
|
||||
|
||||
export const POLL_FETCH_REQUEST = 'POLL_FETCH_REQUEST';
|
||||
export const POLL_FETCH_SUCCESS = 'POLL_FETCH_SUCCESS';
|
||||
export const POLL_FETCH_FAIL = 'POLL_FETCH_FAIL';
|
||||
export const POLL_FETCH_REQUEST = 'POLL_FETCH_REQUEST'
|
||||
export const POLL_FETCH_SUCCESS = 'POLL_FETCH_SUCCESS'
|
||||
export const POLL_FETCH_FAIL = 'POLL_FETCH_FAIL'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const vote = (pollId, choices) => (dispatch, getState) => {
|
||||
dispatch(voteRequest());
|
||||
dispatch(voteRequest())
|
||||
|
||||
api(getState).post(`/api/v1/polls/${pollId}/votes`, { choices })
|
||||
.then(({ data }) => {
|
||||
dispatch(importFetchedPoll(data));
|
||||
dispatch(voteSuccess(data));
|
||||
dispatch(importFetchedPoll(data))
|
||||
dispatch(voteSuccess(data))
|
||||
})
|
||||
.catch(err => dispatch(voteFail(err)));
|
||||
};
|
||||
.catch(err => dispatch(voteFail(err)))
|
||||
}
|
||||
|
||||
const voteRequest = () => ({
|
||||
type: POLL_VOTE_REQUEST,
|
||||
})
|
||||
|
||||
const voteSuccess = (poll) => ({
|
||||
type: POLL_VOTE_SUCCESS,
|
||||
poll,
|
||||
})
|
||||
|
||||
const voteFail = (error) => ({
|
||||
type: POLL_VOTE_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchPoll = pollId => (dispatch, getState) => {
|
||||
dispatch(fetchPollRequest());
|
||||
dispatch(fetchPollRequest())
|
||||
|
||||
api(getState).get(`/api/v1/polls/${pollId}`)
|
||||
.then(({ data }) => {
|
||||
dispatch(importFetchedPoll(data));
|
||||
dispatch(fetchPollSuccess(data));
|
||||
dispatch(importFetchedPoll(data))
|
||||
dispatch(fetchPollSuccess(data))
|
||||
})
|
||||
.catch(err => dispatch(fetchPollFail(err)));
|
||||
};
|
||||
.catch(err => dispatch(fetchPollFail(err)))
|
||||
}
|
||||
|
||||
export const voteRequest = () => ({
|
||||
type: POLL_VOTE_REQUEST,
|
||||
});
|
||||
|
||||
export const voteSuccess = poll => ({
|
||||
type: POLL_VOTE_SUCCESS,
|
||||
poll,
|
||||
});
|
||||
|
||||
export const voteFail = error => ({
|
||||
type: POLL_VOTE_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const fetchPollRequest = () => ({
|
||||
const fetchPollRequest = () => ({
|
||||
type: POLL_FETCH_REQUEST,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchPollSuccess = poll => ({
|
||||
const fetchPollSuccess = (poll) => ({
|
||||
type: POLL_FETCH_SUCCESS,
|
||||
poll,
|
||||
});
|
||||
})
|
||||
|
||||
export const fetchPollFail = error => ({
|
||||
const fetchPollFail = (error) => ({
|
||||
type: POLL_FETCH_FAIL,
|
||||
error,
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
export const POPOVER_OPEN = 'POPOVER_OPEN'
|
||||
export const POPOVER_CLOSE = 'POPOVER_CLOSE'
|
||||
|
||||
export function openPopover(type, props) {
|
||||
return function (dispatch, getState) {
|
||||
const currentlyOpenPopover = getState().getIn(['popover', 'popoverType'])
|
||||
export const openPopover = (type, props) => (dispatch, getState) => {
|
||||
const currentlyOpenPopover = getState().getIn(['popover', 'popoverType'])
|
||||
|
||||
if (currentlyOpenPopover === type) {
|
||||
dispatch(closePopover(type))
|
||||
} else {
|
||||
dispatch(handleOpenPopover(type, props))
|
||||
}
|
||||
if (currentlyOpenPopover === type) {
|
||||
dispatch(closePopover(type))
|
||||
} else {
|
||||
dispatch(handleOpenPopover(type, props))
|
||||
}
|
||||
}
|
||||
|
||||
export function closePopover(type) {
|
||||
return {
|
||||
type: POPOVER_CLOSE,
|
||||
popoverType: type,
|
||||
}
|
||||
}
|
||||
export const closePopover = (type) => ({
|
||||
type: POPOVER_CLOSE,
|
||||
popoverType: type,
|
||||
})
|
||||
|
||||
const handleOpenPopover = (type, props) => {
|
||||
return {
|
||||
type: POPOVER_OPEN,
|
||||
popoverType: type,
|
||||
popoverProps: props,
|
||||
}
|
||||
}
|
||||
const handleOpenPopover = (type, props) => ({
|
||||
type: POPOVER_OPEN,
|
||||
popoverType: type,
|
||||
popoverProps: props,
|
||||
})
|
||||
@@ -5,18 +5,19 @@ export const PROMOTIONS_FETCH_REQUEST = 'PROMOTIONS_FETCH_REQUEST'
|
||||
export const PROMOTIONS_FETCH_SUCCESS = 'PROMOTIONS_FETCH_SUCCESS'
|
||||
export const PROMOTIONS_FETCH_FAIL = 'PROMOTIONS_FETCH_FAIL'
|
||||
|
||||
export const fetchPromotions = () => {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchPromotions = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchPromotionsRequest())
|
||||
dispatch(fetchPromotionsRequest())
|
||||
|
||||
api(getState).get('/api/v1/promotions').then((response) => {
|
||||
dispatch(fetchPromotionsSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchPromotionsFail(error))
|
||||
})
|
||||
}
|
||||
api(getState).get('/api/v1/promotions').then((response) => {
|
||||
dispatch(fetchPromotionsSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchPromotionsFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
const fetchPromotionsRequest = () => ({
|
||||
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
CLEAR_SUBSCRIPTION,
|
||||
SET_ALERTS,
|
||||
setAlerts,
|
||||
} from './setter';
|
||||
import { register, saveSettings } from './registerer';
|
||||
} from './setter'
|
||||
import { register, saveSettings } from './registerer'
|
||||
|
||||
export {
|
||||
SET_BROWSER_SUPPORT,
|
||||
@@ -13,11 +13,9 @@ export {
|
||||
CLEAR_SUBSCRIPTION,
|
||||
SET_ALERTS,
|
||||
register,
|
||||
};
|
||||
|
||||
export function changeAlerts(path, value) {
|
||||
return dispatch => {
|
||||
dispatch(setAlerts(path, value));
|
||||
dispatch(saveSettings());
|
||||
};
|
||||
}
|
||||
|
||||
export const changeAlerts = (path, value) => (dispatch) => {
|
||||
dispatch(setAlerts(path, value))
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
|
||||
@@ -1,34 +1,26 @@
|
||||
export const SET_BROWSER_SUPPORT = 'PUSH_NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||
export const SET_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_SET_SUBSCRIPTION';
|
||||
export const CLEAR_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_CLEAR_SUBSCRIPTION';
|
||||
export const SET_ALERTS = 'PUSH_NOTIFICATIONS_SET_ALERTS';
|
||||
export const SET_BROWSER_SUPPORT = 'PUSH_NOTIFICATIONS_SET_BROWSER_SUPPORT'
|
||||
export const SET_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_SET_SUBSCRIPTION'
|
||||
export const CLEAR_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_CLEAR_SUBSCRIPTION'
|
||||
export const SET_ALERTS = 'PUSH_NOTIFICATIONS_SET_ALERTS'
|
||||
|
||||
export function setBrowserSupport (value) {
|
||||
return {
|
||||
type: SET_BROWSER_SUPPORT,
|
||||
export const setBrowserSupport = (value) => ({
|
||||
type: SET_BROWSER_SUPPORT,
|
||||
value,
|
||||
})
|
||||
|
||||
export const setSubscription = (subscription) => ({
|
||||
type: SET_SUBSCRIPTION,
|
||||
subscription,
|
||||
})
|
||||
|
||||
export const clearSubscription = () => ({
|
||||
type: CLEAR_SUBSCRIPTION,
|
||||
})
|
||||
|
||||
export const setAlerts = (path, value) => (dispatch) => {
|
||||
dispatch({
|
||||
type: SET_ALERTS,
|
||||
path,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSubscription (subscription) {
|
||||
return {
|
||||
type: SET_SUBSCRIPTION,
|
||||
subscription,
|
||||
};
|
||||
}
|
||||
|
||||
export function clearSubscription () {
|
||||
return {
|
||||
type: CLEAR_SUBSCRIPTION,
|
||||
};
|
||||
}
|
||||
|
||||
export function setAlerts (path, value) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: SET_ALERTS,
|
||||
path,
|
||||
value,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,89 +1,82 @@
|
||||
import api from '../api';
|
||||
import { openModal, closeModal } from './modal';
|
||||
import api from '../api'
|
||||
import { openModal, closeModal } from './modal'
|
||||
import { MODAL_REPORT } from '../constants'
|
||||
|
||||
export const REPORT_INIT = 'REPORT_INIT';
|
||||
export const REPORT_CANCEL = 'REPORT_CANCEL';
|
||||
export const REPORT_INIT = 'REPORT_INIT'
|
||||
export const REPORT_CANCEL = 'REPORT_CANCEL'
|
||||
|
||||
export const REPORT_SUBMIT_REQUEST = 'REPORT_SUBMIT_REQUEST';
|
||||
export const REPORT_SUBMIT_SUCCESS = 'REPORT_SUBMIT_SUCCESS';
|
||||
export const REPORT_SUBMIT_FAIL = 'REPORT_SUBMIT_FAIL';
|
||||
export const REPORT_SUBMIT_REQUEST = 'REPORT_SUBMIT_REQUEST'
|
||||
export const REPORT_SUBMIT_SUCCESS = 'REPORT_SUBMIT_SUCCESS'
|
||||
export const REPORT_SUBMIT_FAIL = 'REPORT_SUBMIT_FAIL'
|
||||
|
||||
export const REPORT_STATUS_TOGGLE = 'REPORT_STATUS_TOGGLE';
|
||||
export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE';
|
||||
export const REPORT_FORWARD_CHANGE = 'REPORT_FORWARD_CHANGE';
|
||||
export const REPORT_STATUS_TOGGLE = 'REPORT_STATUS_TOGGLE'
|
||||
export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE'
|
||||
export const REPORT_FORWARD_CHANGE = 'REPORT_FORWARD_CHANGE'
|
||||
|
||||
export function initReport(account, status) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: REPORT_INIT,
|
||||
account,
|
||||
status,
|
||||
});
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const initReport = (account, status) => (dispatch) => {
|
||||
dispatch({
|
||||
type: REPORT_INIT,
|
||||
account,
|
||||
status,
|
||||
})
|
||||
|
||||
dispatch(openModal('REPORT'));
|
||||
};
|
||||
};
|
||||
dispatch(openModal(MODAL_REPORT))
|
||||
}
|
||||
|
||||
export function cancelReport() {
|
||||
return {
|
||||
type: REPORT_CANCEL,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const cancelReport = () => ({
|
||||
type: REPORT_CANCEL,
|
||||
})
|
||||
|
||||
export function toggleStatusReport(statusId, checked) {
|
||||
return {
|
||||
type: REPORT_STATUS_TOGGLE,
|
||||
statusId,
|
||||
checked,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const toggleStatusReport = (statusId, checked) => ({
|
||||
type: REPORT_STATUS_TOGGLE,
|
||||
statusId,
|
||||
checked,
|
||||
})
|
||||
|
||||
export function submitReport() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(submitReportRequest());
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const submitReport = () => (dispatch, getState) => {
|
||||
dispatch(submitReportRequest())
|
||||
|
||||
api(getState).post('/api/v1/reports', {
|
||||
account_id: getState().getIn(['reports', 'new', 'account_id']),
|
||||
status_ids: getState().getIn(['reports', 'new', 'status_ids']),
|
||||
comment: getState().getIn(['reports', 'new', 'comment']),
|
||||
forward: getState().getIn(['reports', 'new', 'forward']),
|
||||
}).then(response => {
|
||||
dispatch(closeModal());
|
||||
dispatch(submitReportSuccess(response.data));
|
||||
}).catch(error => dispatch(submitReportFail(error)));
|
||||
};
|
||||
};
|
||||
api(getState).post('/api/v1/reports', {
|
||||
account_id: getState().getIn(['reports', 'new', 'account_id']),
|
||||
status_ids: getState().getIn(['reports', 'new', 'status_ids']),
|
||||
comment: getState().getIn(['reports', 'new', 'comment']),
|
||||
forward: getState().getIn(['reports', 'new', 'forward']),
|
||||
}).then((response) => {
|
||||
dispatch(closeModal());
|
||||
dispatch(submitReportSuccess(response.data))
|
||||
}).catch((error) => dispatch(submitReportFail(error)))
|
||||
}
|
||||
|
||||
export function submitReportRequest() {
|
||||
return {
|
||||
type: REPORT_SUBMIT_REQUEST,
|
||||
};
|
||||
};
|
||||
const submitReportRequest = () => ({
|
||||
type: REPORT_SUBMIT_REQUEST,
|
||||
})
|
||||
|
||||
export function submitReportSuccess(report) {
|
||||
return {
|
||||
type: REPORT_SUBMIT_SUCCESS,
|
||||
report,
|
||||
};
|
||||
};
|
||||
const submitReportSuccess = (report) => ({
|
||||
type: REPORT_SUBMIT_SUCCESS,
|
||||
report,
|
||||
})
|
||||
|
||||
export function submitReportFail(error) {
|
||||
return {
|
||||
type: REPORT_SUBMIT_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
const submitReportFail = (error) => ({
|
||||
type: REPORT_SUBMIT_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
export function changeReportComment(comment) {
|
||||
return {
|
||||
type: REPORT_COMMENT_CHANGE,
|
||||
comment,
|
||||
};
|
||||
};
|
||||
|
||||
export function changeReportForward(forward) {
|
||||
return {
|
||||
type: REPORT_FORWARD_CHANGE,
|
||||
forward,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeReportComment = (comment) => ({
|
||||
type: REPORT_COMMENT_CHANGE,
|
||||
comment,
|
||||
})
|
||||
|
||||
@@ -18,93 +18,92 @@ export const SEARCH_FETCH_FAIL = 'SEARCH_FETCH_FAIL';
|
||||
|
||||
export const SEARCH_FILTER_SET = 'SEARCH_FILTER_SET'
|
||||
|
||||
export function changeSearch(value) {
|
||||
return {
|
||||
type: SEARCH_CHANGE,
|
||||
value,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const changeSearch = (value) => ({
|
||||
type: SEARCH_CHANGE,
|
||||
value,
|
||||
})
|
||||
|
||||
export function clearSearch() {
|
||||
return {
|
||||
type: SEARCH_CLEAR,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const clearSearch = () => ({
|
||||
type: SEARCH_CLEAR,
|
||||
})
|
||||
|
||||
export function submitSearch() {
|
||||
return (dispatch, getState) => {
|
||||
const value = getState().getIn(['search', 'value']);
|
||||
const onlyVerified = getState().getIn(['search', 'filter', 'onlyVerified'])
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const submitSearch = () => (dispatch, getState) => {
|
||||
const value = getState().getIn(['search', 'value'])
|
||||
const onlyVerified = getState().getIn(['search', 'filter', 'onlyVerified'])
|
||||
|
||||
if (value.length === 0) return
|
||||
if (value.length === 0) return
|
||||
|
||||
dispatch(fetchSearchRequest());
|
||||
dispatch(fetchSearchRequest())
|
||||
|
||||
api(getState).get('/api/v2/search', {
|
||||
params: {
|
||||
onlyVerified,
|
||||
q: value,
|
||||
resolve: true,
|
||||
},
|
||||
}).then(response => {
|
||||
if (response.data.accounts) {
|
||||
dispatch(importFetchedAccounts(response.data.accounts));
|
||||
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
|
||||
}
|
||||
api(getState).get('/api/v2/search', {
|
||||
params: {
|
||||
onlyVerified,
|
||||
q: value,
|
||||
resolve: true,
|
||||
},
|
||||
}).then((response) => {
|
||||
if (response.data.accounts) {
|
||||
dispatch(importFetchedAccounts(response.data.accounts))
|
||||
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)))
|
||||
}
|
||||
|
||||
if (response.data.statuses) {
|
||||
dispatch(importFetchedStatuses(response.data.statuses));
|
||||
}
|
||||
if (response.data.statuses) {
|
||||
dispatch(importFetchedStatuses(response.data.statuses))
|
||||
}
|
||||
|
||||
if (response.data.links) {
|
||||
dispatch(importLinkCards(response.data.links));
|
||||
}
|
||||
if (response.data.links) {
|
||||
dispatch(importLinkCards(response.data.links))
|
||||
}
|
||||
|
||||
if (response.data.groups) {
|
||||
dispatch(fetchGroupsSuccess(response.data.groups))
|
||||
dispatch(fetchGroupRelationships(response.data.groups.map(item => item.id)))
|
||||
}
|
||||
if (response.data.groups) {
|
||||
dispatch(fetchGroupsSuccess(response.data.groups))
|
||||
dispatch(fetchGroupRelationships(response.data.groups.map(item => item.id)))
|
||||
}
|
||||
|
||||
dispatch(fetchSearchSuccess(response.data));
|
||||
}).catch(error => {
|
||||
dispatch(fetchSearchFail(error));
|
||||
});
|
||||
};
|
||||
};
|
||||
dispatch(fetchSearchSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(fetchSearchFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchSearchRequest() {
|
||||
return {
|
||||
type: SEARCH_FETCH_REQUEST,
|
||||
};
|
||||
};
|
||||
const fetchSearchRequest = () => ({
|
||||
type: SEARCH_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchSearchSuccess(results) {
|
||||
return {
|
||||
type: SEARCH_FETCH_SUCCESS,
|
||||
results,
|
||||
};
|
||||
};
|
||||
const fetchSearchSuccess = (results) => ({
|
||||
type: SEARCH_FETCH_SUCCESS,
|
||||
results,
|
||||
})
|
||||
|
||||
export function fetchSearchFail(error) {
|
||||
return {
|
||||
type: SEARCH_FETCH_FAIL,
|
||||
error,
|
||||
};
|
||||
};
|
||||
const fetchSearchFail = (error) => ({
|
||||
type: SEARCH_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
export function showSearch() {
|
||||
return {
|
||||
type: SEARCH_SHOW,
|
||||
};
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const showSearch = () => ({
|
||||
type: SEARCH_SHOW,
|
||||
})
|
||||
|
||||
export function setFilter(path, value, shouldSubmit) {
|
||||
return (dispatch) => {
|
||||
dispatch({
|
||||
type: SEARCH_FILTER_SET,
|
||||
path: path,
|
||||
value: value,
|
||||
})
|
||||
if (shouldSubmit) dispatch(submitSearch())
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const setFilter = (path, value, shouldSubmit) => (dispatch) => {
|
||||
dispatch({
|
||||
type: SEARCH_FILTER_SET,
|
||||
path: path,
|
||||
value: value,
|
||||
})
|
||||
if (shouldSubmit) dispatch(submitSearch())
|
||||
}
|
||||
@@ -5,16 +5,26 @@ import { me } from '../initial_state'
|
||||
export const SETTING_CHANGE = 'SETTING_CHANGE'
|
||||
export const SETTING_SAVE = 'SETTING_SAVE'
|
||||
|
||||
export function changeSetting(path, value) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: SETTING_CHANGE,
|
||||
path,
|
||||
value,
|
||||
})
|
||||
export const saveShownOnboarding = () => (dispatch) => {
|
||||
dispatch(changeSetting(['shownOnboarding'], true))
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
export const changeSetting = (path, value) => (dispatch) => {
|
||||
dispatch({
|
||||
type: SETTING_CHANGE,
|
||||
path,
|
||||
value,
|
||||
})
|
||||
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const saveSettings = () => (dispatch, getState) => {
|
||||
debouncedSave(dispatch, getState)
|
||||
}
|
||||
|
||||
const debouncedSave = debounce((dispatch, getState) => {
|
||||
@@ -28,7 +38,3 @@ const debouncedSave = debounce((dispatch, getState) => {
|
||||
.then(() => dispatch({ type: SETTING_SAVE }))
|
||||
.catch(() => { /* */ })
|
||||
}, 350, { trailing: true })
|
||||
|
||||
export function saveSettings() {
|
||||
return (dispatch, getState) => debouncedSave(dispatch, getState)
|
||||
}
|
||||
|
||||
@@ -1,47 +1,44 @@
|
||||
|
||||
import axios from 'axios'
|
||||
import api from '../api'
|
||||
import { me } from '../initial_state'
|
||||
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_REQUEST = 'SHOP_FEATURED_PRODUCTS_FETCH_REQUEST'
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS = 'SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS'
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_FAIL = 'SHOP_FEATURED_PRODUCTS_FETCH_FAIL'
|
||||
|
||||
export const fetchFeaturedProducts = () => {
|
||||
return function (dispatch, getState) {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchFeaturedProducts = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchFeaturedProductsRequest('featured'))
|
||||
dispatch(fetchFeaturedProductsRequest('featured'))
|
||||
|
||||
axios.get('https://dissenter-shop.gab.com/product/group/json').then((response) => {
|
||||
try {
|
||||
dispatch(fetchFeaturedProductsSuccess(response.data.data, 'featured'))
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}).catch(function (error) {
|
||||
dispatch(fetchFeaturedProductsFail(error, 'featured'))
|
||||
})
|
||||
}
|
||||
axios.get('https://dissenter-shop.gab.com/product/group/json').then((response) => {
|
||||
try {
|
||||
dispatch(fetchFeaturedProductsSuccess(response.data.data, 'featured'))
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}).catch((error) => {
|
||||
dispatch(fetchFeaturedProductsFail(error, 'featured'))
|
||||
})
|
||||
}
|
||||
|
||||
function fetchFeaturedProductsRequest(listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_REQUEST,
|
||||
listType,
|
||||
}
|
||||
}
|
||||
const fetchFeaturedProductsRequest = (listType) => ({
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_REQUEST,
|
||||
listType,
|
||||
})
|
||||
|
||||
function fetchFeaturedProductsSuccess(items, listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS,
|
||||
items,
|
||||
listType,
|
||||
}
|
||||
}
|
||||
const fetchFeaturedProductsSuccess = (items, listType) => ({
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS,
|
||||
items,
|
||||
listType,
|
||||
})
|
||||
|
||||
function fetchFeaturedProductsFail(error, listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_FAIL,
|
||||
error,
|
||||
listType,
|
||||
}
|
||||
}
|
||||
const fetchFeaturedProductsFail = (error, listType) => ({
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_FAIL,
|
||||
error,
|
||||
listType,
|
||||
})
|
||||
@@ -13,116 +13,104 @@ export const SHORTCUTS_REMOVE_REQUEST = 'SHORTCUTS_REMOVE_REQUEST'
|
||||
export const SHORTCUTS_REMOVE_SUCCESS = 'SHORTCUTS_REMOVE_SUCCESS'
|
||||
export const SHORTCUTS_REMOVE_FAIL = 'SHORTCUTS_REMOVE_FAIL'
|
||||
|
||||
export function fetchShortcuts() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchShortcuts = () => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
const isFetched = getState().getIn(['shortcuts', 'isFetched'], false)
|
||||
if (isFetched) return
|
||||
|
||||
dispatch(fetchShortcutsRequest())
|
||||
dispatch(fetchShortcutsRequest())
|
||||
|
||||
api(getState).get('/api/v1/shortcuts').then(response => {
|
||||
dispatch(fetchShortcutsSuccess(response.data))
|
||||
}).catch(error => dispatch(fetchShortcutsFail(error)))
|
||||
}
|
||||
api(getState).get('/api/v1/shortcuts').then(response => {
|
||||
dispatch(fetchShortcutsSuccess(response.data))
|
||||
}).catch(error => dispatch(fetchShortcutsFail(error)))
|
||||
}
|
||||
|
||||
export function fetchShortcutsRequest() {
|
||||
return {
|
||||
type: SHORTCUTS_FETCH_REQUEST,
|
||||
}
|
||||
const fetchShortcutsRequest = () => ({
|
||||
type: SHORTCUTS_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
const fetchShortcutsSuccess = (shortcuts) => ({
|
||||
type: SHORTCUTS_FETCH_SUCCESS,
|
||||
shortcuts,
|
||||
})
|
||||
|
||||
const fetchShortcutsFail = (error) => ({
|
||||
type: SHORTCUTS_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const addShortcut = (shortcutType, shortcutId) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
dispatch(addShortcutsRequest())
|
||||
|
||||
api(getState).post('/api/v1/shortcuts', {
|
||||
shortcut_type: shortcutType,
|
||||
shortcut_id: shortcutId,
|
||||
}).then(response => {
|
||||
dispatch(addShortcutsSuccess(response.data))
|
||||
}).catch(error => dispatch(addShortcutsFail(error)))
|
||||
}
|
||||
|
||||
export function fetchShortcutsSuccess(shortcuts) {
|
||||
return {
|
||||
shortcuts,
|
||||
type: SHORTCUTS_FETCH_SUCCESS,
|
||||
}
|
||||
}
|
||||
const addShortcutsRequest = () => ({
|
||||
type: SHORTCUTS_ADD_REQUEST,
|
||||
})
|
||||
|
||||
export function fetchShortcutsFail(error) {
|
||||
return {
|
||||
error,
|
||||
type: SHORTCUTS_FETCH_FAIL,
|
||||
}
|
||||
}
|
||||
const addShortcutsSuccess = (shortcut) => ({
|
||||
type: SHORTCUTS_ADD_SUCCESS,
|
||||
shortcut,
|
||||
})
|
||||
|
||||
export function addShortcut(shortcutType, shortcutId) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
const addShortcutsFail = (error) => ({
|
||||
type: SHORTCUTS_ADD_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
dispatch(addShortcutsRequest())
|
||||
|
||||
api(getState).post('/api/v1/shortcuts', {
|
||||
shortcut_type: shortcutType,
|
||||
shortcut_id: shortcutId,
|
||||
}).then(response => {
|
||||
dispatch(addShortcutsSuccess(response.data))
|
||||
}).catch(error => dispatch(addShortcutsFail(error)))
|
||||
}
|
||||
}
|
||||
|
||||
export function addShortcutsRequest() {
|
||||
return {
|
||||
type: SHORTCUTS_ADD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
export function addShortcutsSuccess(shortcut) {
|
||||
return {
|
||||
shortcut,
|
||||
type: SHORTCUTS_ADD_SUCCESS,
|
||||
}
|
||||
}
|
||||
|
||||
export function addShortcutsFail(error) {
|
||||
return {
|
||||
error,
|
||||
type: SHORTCUTS_ADD_FAIL,
|
||||
}
|
||||
}
|
||||
|
||||
export function removeShortcut(shortcutObjectId, shortcutType, shortcutId) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
let id
|
||||
if (shortcutObjectId) {
|
||||
id = shortcutObjectId
|
||||
} else if (shortcutType && shortcutId) {
|
||||
const shortcuts = getState().getIn(['shortcuts', 'items'])
|
||||
const shortcut = shortcuts.find((s) => {
|
||||
return s.get('shortcut_id') == shortcutId && s.get('shortcut_type') === shortcutType
|
||||
})
|
||||
if (!!shortcut) {
|
||||
id = shortcut.get('id')
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const removeShortcut = (shortcutObjectId, shortcutType, shortcutId) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
let id
|
||||
if (shortcutObjectId) {
|
||||
id = shortcutObjectId
|
||||
} else if (shortcutType && shortcutId) {
|
||||
const shortcuts = getState().getIn(['shortcuts', 'items'])
|
||||
const shortcut = shortcuts.find((s) => {
|
||||
return s.get('shortcut_id') == shortcutId && s.get('shortcut_type') === shortcutType
|
||||
})
|
||||
if (!!shortcut) {
|
||||
id = shortcut.get('id')
|
||||
}
|
||||
|
||||
if (!id) return
|
||||
|
||||
dispatch(removeShortcutsRequest())
|
||||
|
||||
api(getState).delete(`/api/v1/shortcuts/${id}`).then(response => {
|
||||
dispatch(removeShortcutsSuccess(response.data.id))
|
||||
}).catch(error => dispatch(removeShortcutsFail(error)))
|
||||
}
|
||||
|
||||
if (!id) return
|
||||
|
||||
dispatch(removeShortcutsRequest())
|
||||
|
||||
api(getState).delete(`/api/v1/shortcuts/${id}`).then(response => {
|
||||
dispatch(removeShortcutsSuccess(response.data.id))
|
||||
}).catch(error => dispatch(removeShortcutsFail(error)))
|
||||
}
|
||||
|
||||
export function removeShortcutsRequest() {
|
||||
return {
|
||||
type: SHORTCUTS_REMOVE_REQUEST,
|
||||
}
|
||||
}
|
||||
const removeShortcutsRequest = () => ({
|
||||
type: SHORTCUTS_REMOVE_REQUEST,
|
||||
})
|
||||
|
||||
export function removeShortcutsSuccess(shortcutId) {
|
||||
return {
|
||||
shortcutId,
|
||||
type: SHORTCUTS_REMOVE_SUCCESS,
|
||||
}
|
||||
}
|
||||
const removeShortcutsSuccess = (shortcutId) => ({
|
||||
type: SHORTCUTS_REMOVE_SUCCESS,
|
||||
shortcutId,
|
||||
})
|
||||
|
||||
export function removeShortcutsFail(error) {
|
||||
return {
|
||||
error,
|
||||
type: SHORTCUTS_REMOVE_FAIL,
|
||||
}
|
||||
}
|
||||
const removeShortcutsFail = (error) => ({
|
||||
type: SHORTCUTS_REMOVE_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
export const SIDEBAR_OPEN = 'SIDEBAR_OPEN'
|
||||
export const SIDEBAR_CLOSE = 'SIDEBAR_CLOSE'
|
||||
|
||||
export function openSidebar() {
|
||||
return {
|
||||
type: SIDEBAR_OPEN,
|
||||
}
|
||||
}
|
||||
export const openSidebar = () => ({
|
||||
type: SIDEBAR_OPEN,
|
||||
})
|
||||
|
||||
export function closeSidebar() {
|
||||
return {
|
||||
type: SIDEBAR_CLOSE,
|
||||
}
|
||||
}
|
||||
export const closeSidebar = () => ({
|
||||
type: SIDEBAR_CLOSE,
|
||||
})
|
||||
|
||||
@@ -4,6 +4,12 @@ export const STATUS_REVISIONS_LOAD = 'STATUS_REVISIONS_LOAD'
|
||||
export const STATUS_REVISIONS_LOAD_SUCCESS = 'STATUS_REVISIONS_SUCCESS'
|
||||
export const STATUS_REVISIONS_LOAD_FAIL = 'STATUS_REVISIONS_FAIL'
|
||||
|
||||
export const loadStatusRevisions = (statusId) => (dispatch, getState) => {
|
||||
api(getState).get(`/api/v1/statuses/${statusId}/revisions`)
|
||||
.then(res => dispatch(loadStatusRevisionsSuccess(res.data)))
|
||||
.catch(() => dispatch(loadStatusRevisionsFail()))
|
||||
}
|
||||
|
||||
const loadStatusRevisionsSuccess = (data) => ({
|
||||
type: STATUS_REVISIONS_LOAD_SUCCESS,
|
||||
revisions: data,
|
||||
@@ -12,12 +18,4 @@ const loadStatusRevisionsSuccess = (data) => ({
|
||||
const loadStatusRevisionsFail = () => ({
|
||||
type: STATUS_REVISIONS_LOAD_FAIL,
|
||||
error: true,
|
||||
})
|
||||
|
||||
export function loadStatusRevisions(statusId) {
|
||||
return (dispatch, getState) => {
|
||||
api(getState).get(`/api/v1/statuses/${statusId}/revisions`)
|
||||
.then(res => dispatch(loadStatusRevisionsSuccess(res.data)))
|
||||
.catch(() => dispatch(loadStatusRevisionsFail()))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -22,19 +22,13 @@ export const COMMENTS_FETCH_REQUEST = 'COMMENTS_FETCH_REQUEST';
|
||||
export const COMMENTS_FETCH_SUCCESS = 'COMMENTS_FETCH_SUCCESS';
|
||||
export const COMMENTS_FETCH_FAIL = 'COMMENTS_FETCH_FAIL';
|
||||
|
||||
export const STATUS_MUTE_REQUEST = 'STATUS_MUTE_REQUEST';
|
||||
export const STATUS_MUTE_SUCCESS = 'STATUS_MUTE_SUCCESS';
|
||||
export const STATUS_MUTE_FAIL = 'STATUS_MUTE_FAIL';
|
||||
|
||||
export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST';
|
||||
export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS';
|
||||
export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
|
||||
|
||||
export const STATUS_REVEAL = 'STATUS_REVEAL';
|
||||
export const STATUS_HIDE = 'STATUS_HIDE';
|
||||
|
||||
export const STATUS_EDIT = 'STATUS_EDIT';
|
||||
|
||||
export const UPDATE_STATUS_STATS = 'UPDATE_STATUS_STATS'
|
||||
|
||||
export function fetchStatusRequest(id, skipLoading) {
|
||||
return {
|
||||
type: STATUS_FETCH_REQUEST,
|
||||
@@ -280,78 +274,6 @@ export function fetchCommentsFail(id, error) {
|
||||
};
|
||||
};
|
||||
|
||||
export function muteStatus(id) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(muteStatusRequest(id));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${id}/mute`).then(() => {
|
||||
dispatch(muteStatusSuccess(id));
|
||||
}).catch(error => {
|
||||
dispatch(muteStatusFail(id, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function muteStatusRequest(id) {
|
||||
return {
|
||||
type: STATUS_MUTE_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function muteStatusSuccess(id) {
|
||||
return {
|
||||
type: STATUS_MUTE_SUCCESS,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function muteStatusFail(id, error) {
|
||||
return {
|
||||
type: STATUS_MUTE_FAIL,
|
||||
id,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export function unmuteStatus(id) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return;
|
||||
|
||||
dispatch(unmuteStatusRequest(id));
|
||||
|
||||
api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => {
|
||||
dispatch(unmuteStatusSuccess(id));
|
||||
}).catch(error => {
|
||||
dispatch(unmuteStatusFail(id, error));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function unmuteStatusRequest(id) {
|
||||
return {
|
||||
type: STATUS_UNMUTE_REQUEST,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function unmuteStatusSuccess(id) {
|
||||
return {
|
||||
type: STATUS_UNMUTE_SUCCESS,
|
||||
id,
|
||||
};
|
||||
};
|
||||
|
||||
export function unmuteStatusFail(id, error) {
|
||||
return {
|
||||
type: STATUS_UNMUTE_FAIL,
|
||||
id,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export function hideStatus(ids) {
|
||||
if (!Array.isArray(ids)) {
|
||||
ids = [ids];
|
||||
@@ -373,3 +295,10 @@ export function revealStatus(ids) {
|
||||
ids,
|
||||
};
|
||||
};
|
||||
|
||||
export function updateStatusStats(data) {
|
||||
return {
|
||||
type: UPDATE_STATUS_STATS,
|
||||
data,
|
||||
};
|
||||
};
|
||||
@@ -1,24 +1,22 @@
|
||||
import { Iterable, fromJS } from 'immutable';
|
||||
import { hydrateCompose } from './compose';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { Iterable, fromJS } from 'immutable'
|
||||
import { hydrateCompose } from './compose'
|
||||
import { importFetchedAccounts } from './importer'
|
||||
|
||||
export const STORE_HYDRATE = 'STORE_HYDRATE';
|
||||
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY';
|
||||
export const STORE_HYDRATE = 'STORE_HYDRATE'
|
||||
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY'
|
||||
|
||||
const convertState = rawState =>
|
||||
fromJS(rawState, (k, v) =>
|
||||
Iterable.isIndexed(v) ? v.toList() : v.toMap());
|
||||
const convertState = (rawState) => {
|
||||
return fromJS(rawState, (k, v) => Iterable.isIndexed(v) ? v.toList() : v.toMap())
|
||||
}
|
||||
|
||||
export function hydrateStore(rawState) {
|
||||
return (dispatch) => {
|
||||
const state = convertState(rawState);
|
||||
export const hydrateStore = (rawState) => (dispatch) => {
|
||||
const state = convertState(rawState)
|
||||
|
||||
dispatch({
|
||||
type: STORE_HYDRATE,
|
||||
state,
|
||||
});
|
||||
dispatch({
|
||||
type: STORE_HYDRATE,
|
||||
state,
|
||||
})
|
||||
|
||||
dispatch(hydrateCompose());
|
||||
if (rawState.accounts) dispatch(importFetchedAccounts(Object.values(rawState.accounts)));
|
||||
};
|
||||
};
|
||||
dispatch(hydrateCompose())
|
||||
if (rawState.accounts) dispatch(importFetchedAccounts(Object.values(rawState.accounts)))
|
||||
}
|
||||
@@ -1,70 +1,73 @@
|
||||
import { connectStream } from '../stream';
|
||||
import { connectStream } from '../stream'
|
||||
import {
|
||||
deleteFromTimelines,
|
||||
connectTimeline,
|
||||
disconnectTimeline,
|
||||
updateTimelineQueue,
|
||||
} from './timelines';
|
||||
import { updateNotificationsQueue } from './notifications';
|
||||
import { updateConversations } from './conversations';
|
||||
import { fetchFilters } from './filters';
|
||||
import { getLocale } from '../locales';
|
||||
import { handleComposeSubmit } from './compose';
|
||||
} from './timelines'
|
||||
import { updateNotificationsQueue } from './notifications'
|
||||
import { fetchFilters } from './filters'
|
||||
import { getLocale } from '../locales'
|
||||
import { handleComposeSubmit } from './compose'
|
||||
|
||||
const { messages } = getLocale();
|
||||
const { messages } = getLocale()
|
||||
|
||||
export function connectTimelineStream (timelineId, path, pollingRefresh = null, accept = null) {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const connectTimelineStream = (timelineId, path, pollingRefresh = null, accept = null) => {
|
||||
|
||||
return connectStream (path, pollingRefresh, (dispatch, getState) => {
|
||||
const locale = getState().getIn(['meta', 'locale']);
|
||||
const locale = getState().getIn(['meta', 'locale'])
|
||||
|
||||
return {
|
||||
onConnect() {
|
||||
dispatch(connectTimeline(timelineId));
|
||||
dispatch(connectTimeline(timelineId))
|
||||
},
|
||||
|
||||
onDisconnect() {
|
||||
dispatch(disconnectTimeline(timelineId));
|
||||
dispatch(disconnectTimeline(timelineId))
|
||||
},
|
||||
|
||||
onReceive (data) {
|
||||
switch(data.event) {
|
||||
case 'update':
|
||||
dispatch(updateTimelineQueue(timelineId, JSON.parse(data.payload), accept));
|
||||
break;
|
||||
dispatch(updateTimelineQueue(timelineId, JSON.parse(data.payload), accept))
|
||||
break
|
||||
case 'delete':
|
||||
dispatch(deleteFromTimelines(data.payload));
|
||||
break;
|
||||
dispatch(deleteFromTimelines(data.payload))
|
||||
break
|
||||
case 'notification':
|
||||
dispatch(updateNotificationsQueue(JSON.parse(data.payload), messages, locale, window.location.pathname));
|
||||
break;
|
||||
case 'conversation':
|
||||
dispatch(updateConversations(JSON.parse(data.payload)));
|
||||
break;
|
||||
dispatch(updateNotificationsQueue(JSON.parse(data.payload), messages, locale, window.location.pathname))
|
||||
break
|
||||
case 'filters_changed':
|
||||
dispatch(fetchFilters());
|
||||
break;
|
||||
dispatch(fetchFilters())
|
||||
break
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const connectUserStream = () => connectTimelineStream('home', 'user');
|
||||
export const connectProStream = () => connectTimelineStream('pro', 'pro');
|
||||
export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const connectStatusUpdateStream = () => {
|
||||
|
||||
return connectStream('statuscard', null, (dispatch, getState) => {
|
||||
|
||||
return {
|
||||
onConnect() {},
|
||||
onDisconnect() {},
|
||||
onReceive (data) {
|
||||
if (!data['event'] || !data['payload']) return;
|
||||
if (!data['event'] || !data['payload']) return
|
||||
if (data.event === 'update') {
|
||||
handleComposeSubmit(dispatch, getState, {data: JSON.parse(data.payload)}, null)
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const connectUserStream = () => connectTimelineStream('home', 'user')
|
||||
|
||||
@@ -13,61 +13,59 @@ export const SUGGESTIONS_FETCH_FAIL = 'SUGGESTIONS_FETCH_FAIL'
|
||||
|
||||
export const SUGGESTIONS_DISMISS = 'SUGGESTIONS_DISMISS'
|
||||
|
||||
export function fetchPopularSuggestions() {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return false
|
||||
|
||||
dispatch(fetchSuggestionsRequest(SUGGESTION_TYPE_VERIFIED))
|
||||
|
||||
api(getState).get(`/api/v1/suggestions?type=${SUGGESTION_TYPE_VERIFIED}`).then(response => {
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchSuggestionsSuccess(response.data, SUGGESTION_TYPE_VERIFIED))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(fetchSuggestionsFail(error, SUGGESTION_TYPE_VERIFIED)))
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchPopularSuggestions = () => (dispatch, getState) => {
|
||||
if (!me) return false
|
||||
fetchSuggestions(SUGGESTION_TYPE_VERIFIED, dispatch, getState)
|
||||
}
|
||||
|
||||
export function fetchRelatedSuggestions(unlimited = false) {
|
||||
return (dispatch, getState) => {
|
||||
if (!me) return false
|
||||
|
||||
dispatch(fetchSuggestionsRequest(SUGGESTION_TYPE_RELATED))
|
||||
|
||||
api(getState).get(`/api/v1/suggestions?type=${SUGGESTION_TYPE_RELATED}&unlimited=${!!unlimited}`).then(response => {
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchSuggestionsSuccess(response.data, SUGGESTION_TYPE_RELATED))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(fetchSuggestionsFail(error, SUGGESTION_TYPE_RELATED)))
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const fetchRelatedSuggestions = (unlimited = false) => (dispatch, getState) => {
|
||||
if (!me) return false
|
||||
fetchSuggestions(SUGGESTION_TYPE_RELATED, dispatch, getState, unlimited)
|
||||
}
|
||||
|
||||
export function fetchSuggestionsRequest(suggestionType) {
|
||||
return {
|
||||
type: SUGGESTIONS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
suggestionType,
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const fetchSuggestions = (suggestionType, dispatch, getState, unlimited = false) => {
|
||||
dispatch(fetchSuggestionsRequest(suggestionType))
|
||||
|
||||
api(getState).get(`/api/v1/suggestions?type=${suggestionType}&unlimited=${!!unlimited}`).then((response) => {
|
||||
dispatch(importFetchedAccounts(response.data))
|
||||
dispatch(fetchSuggestionsSuccess(response.data, suggestionType))
|
||||
dispatch(fetchRelationships(response.data.map(item => item.id)))
|
||||
}).catch(error => dispatch(fetchSuggestionsFail(error, suggestionType)))
|
||||
}
|
||||
|
||||
export function fetchSuggestionsSuccess(accounts, suggestionType) {
|
||||
return {
|
||||
type: SUGGESTIONS_FETCH_SUCCESS,
|
||||
skipLoading: true,
|
||||
accounts,
|
||||
suggestionType
|
||||
}
|
||||
}
|
||||
const fetchSuggestionsRequest = (suggestionType) => ({
|
||||
type: SUGGESTIONS_FETCH_REQUEST,
|
||||
skipLoading: true,
|
||||
suggestionType,
|
||||
})
|
||||
|
||||
export function fetchSuggestionsFail(error, suggestionType) {
|
||||
return {
|
||||
type: SUGGESTIONS_FETCH_FAIL,
|
||||
skipLoading: true,
|
||||
skipAlert: true,
|
||||
error,
|
||||
suggestionType,
|
||||
}
|
||||
}
|
||||
const fetchSuggestionsSuccess = (accounts, suggestionType) => ({
|
||||
type: SUGGESTIONS_FETCH_SUCCESS,
|
||||
skipLoading: true,
|
||||
accounts,
|
||||
suggestionType
|
||||
})
|
||||
|
||||
const fetchSuggestionsFail = (error, suggestionType) => ({
|
||||
type: SUGGESTIONS_FETCH_FAIL,
|
||||
skipLoading: true,
|
||||
skipAlert: true,
|
||||
error,
|
||||
suggestionType,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const dismissRelatedSuggestion = (accountId) => (dispatch, getState) => {
|
||||
if (!me) return
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export const showTimelineInjection = (injectionId) => (dispatch) => {
|
||||
export const hideTimelineInjection = (injectionId) => (dispatch, getState) => {
|
||||
const existingInjectionWeight = getState().getIn(['settings', 'injections', injectionId], null)
|
||||
|
||||
if (!existingInjectionWeight) return false
|
||||
if (!existingInjectionWeight) return
|
||||
|
||||
const newInjectionWeight = Math.max(existingInjectionWeight - 0.005, 0.01)
|
||||
|
||||
|
||||
@@ -19,13 +19,6 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
||||
|
||||
export const MAX_QUEUED_ITEMS = 40;
|
||||
|
||||
const fetchStatusesAccountsRelationships = (dispatch, statuses) => {
|
||||
const accountIds = statuses.map(item => item.account.id)
|
||||
if (accountIds.length > 0) {
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
}
|
||||
}
|
||||
|
||||
export function updateTimeline(timeline, status, accept) {
|
||||
return dispatch => {
|
||||
if (typeof accept === 'function' && !accept(status)) {
|
||||
@@ -134,36 +127,34 @@ const parseTags = (tags = {}, mode) => {
|
||||
});
|
||||
};
|
||||
|
||||
export function expandTimeline(timelineId, path, params = {}, done = noOp) {
|
||||
return (dispatch, getState) => {
|
||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
||||
const isLoadingMore = !!params.max_id;
|
||||
export const expandTimeline = (timelineId, path, params = {}, done = noOp) => (dispatch, getState) => {
|
||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap())
|
||||
const isLoadingMore = !!params.max_id
|
||||
|
||||
if (timeline.get('isLoading')) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
if (!!timeline && (timeline.get('isLoading') || timeline.get('isError'))) {
|
||||
done()
|
||||
return
|
||||
}
|
||||
|
||||
if (!params.max_id && !params.pinned && timeline.get('items', ImmutableList()).size > 0) {
|
||||
params.since_id = timeline.getIn(['items', 0]);
|
||||
}
|
||||
if (!params.max_id && !params.pinned && timeline.get('items', ImmutableList()).size > 0) {
|
||||
params.since_id = timeline.getIn(['items', 0])
|
||||
}
|
||||
|
||||
const isLoadingRecent = !!params.since_id;
|
||||
const isLoadingRecent = !!params.since_id
|
||||
|
||||
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
|
||||
dispatch(expandTimelineRequest(timelineId, isLoadingMore))
|
||||
|
||||
api(getState).get(path, { params }).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
dispatch(importFetchedStatuses(response.data));
|
||||
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));
|
||||
fetchStatusesAccountsRelationships(dispatch, response.data)
|
||||
done();
|
||||
}).catch(error => {
|
||||
dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
|
||||
done();
|
||||
});
|
||||
};
|
||||
};
|
||||
api(getState).get(path, { params }).then((response) => {
|
||||
console.log("response:", response)
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(importFetchedStatuses(response.data))
|
||||
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore))
|
||||
done()
|
||||
}).catch((error) => {
|
||||
dispatch(expandTimelineFail(timelineId, error, isLoadingMore))
|
||||
done()
|
||||
})
|
||||
}
|
||||
|
||||
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
|
||||
export const expandExploreTimeline = ({ maxId, sortBy } = {}, done = noOp) => expandTimeline('explore', '/api/v1/timelines/explore', { max_id: maxId, sort_by: sortBy }, done);
|
||||
|
||||
@@ -7,26 +7,29 @@ export const TOAST_SHOW = 'TOAST_SHOW'
|
||||
export const TOAST_DISMISS = 'TOAST_DISMISS'
|
||||
export const TOAST_CLEAR = 'TOAST_CLEAR'
|
||||
|
||||
export function dismissToast(alert) {
|
||||
return {
|
||||
type: TOAST_DISMISS,
|
||||
alert,
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const dismissToast = (alert) => ({
|
||||
type: TOAST_DISMISS,
|
||||
alert,
|
||||
})
|
||||
|
||||
export function clearToast() {
|
||||
return {
|
||||
type: TOAST_CLEAR,
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const clearToast = () => ({
|
||||
type: TOAST_CLEAR,
|
||||
})
|
||||
|
||||
function showToast(type, message) {
|
||||
return {
|
||||
type: TOAST_SHOW,
|
||||
toastType: type,
|
||||
message,
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const showToast = (type, message) => ({
|
||||
type: TOAST_SHOW,
|
||||
toastType: type,
|
||||
message,
|
||||
})
|
||||
|
||||
export const showToastError = (message) => {
|
||||
return showToast(TOAST_TYPE_ERROR, message)
|
||||
|
||||
@@ -11,52 +11,50 @@ export const SAVE_USER_PROFILE_INFORMATION_FETCH_SUCCESS = 'SAVE_USER_PROFILE_IN
|
||||
export const SAVE_USER_PROFILE_INFORMATION_FETCH_FAIL = 'SAVE_USER_PROFILE_INFORMATION_FETCH_FAIL'
|
||||
export const RESEND_USER_CONFIRMATION_EMAIL_SUCCESS = 'RESEND_USER_CONFIRMATION_EMAIL_SUCCESS'
|
||||
|
||||
export const saveUserProfileInformation = (data) => {
|
||||
return function (dispatch, getState) {
|
||||
if (!isObject(data) || !me) return
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const saveUserProfileInformation = (data) => (dispatch, getState) => {
|
||||
if (!isObject(data) || !me) return
|
||||
|
||||
dispatch(saveUserProfileInformationRequest())
|
||||
dispatch(saveUserProfileInformationRequest())
|
||||
|
||||
const formData = new FormData()
|
||||
if (!!data.displayName) formData.append('display_name', data.displayName)
|
||||
if (data.note !== undefined) formData.append('note', data.note)
|
||||
if (data.avatar !== undefined) formData.append('avatar', data.avatar)
|
||||
if (data.header !== undefined) formData.append('header', data.header)
|
||||
if (data.locked !== undefined) formData.append('locked', data.locked)
|
||||
const formData = new FormData()
|
||||
if (!!data.displayName) formData.append('display_name', data.displayName)
|
||||
if (data.note !== undefined) formData.append('note', data.note)
|
||||
if (data.avatar !== undefined) formData.append('avatar', data.avatar)
|
||||
if (data.header !== undefined) formData.append('header', data.header)
|
||||
if (data.locked !== undefined) formData.append('locked', data.locked)
|
||||
|
||||
api(getState).patch('/api/v1/accounts/update_credentials', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}).then((response) => {
|
||||
dispatch(importFetchedAccount(response.data))
|
||||
dispatch(saveUserProfileInformationSuccess(response.data))
|
||||
}).catch(error => {
|
||||
dispatch(saveUserProfileInformationFail(error))
|
||||
})
|
||||
}
|
||||
api(getState).patch('/api/v1/accounts/update_credentials', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}).then((response) => {
|
||||
dispatch(importFetchedAccount(response.data))
|
||||
dispatch(saveUserProfileInformationSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
dispatch(saveUserProfileInformationFail(error))
|
||||
})
|
||||
}
|
||||
|
||||
function saveUserProfileInformationRequest() {
|
||||
return {
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_REQUEST,
|
||||
}
|
||||
}
|
||||
const saveUserProfileInformationRequest = () => ({
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_REQUEST,
|
||||
})
|
||||
|
||||
function saveUserProfileInformationSuccess(userProfileData) {
|
||||
return {
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_SUCCESS,
|
||||
userProfileData,
|
||||
}
|
||||
}
|
||||
const saveUserProfileInformationSuccess = (userProfileData) => ({
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_SUCCESS,
|
||||
userProfileData,
|
||||
})
|
||||
|
||||
function saveUserProfileInformationFail(error) {
|
||||
return {
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_FAIL,
|
||||
error,
|
||||
}
|
||||
}
|
||||
const saveUserProfileInformationFail = (error) => ({
|
||||
type: SAVE_USER_PROFILE_INFORMATION_FETCH_FAIL,
|
||||
error,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const resendUserConfirmationEmail = () => (dispatch, getState) => {
|
||||
if (!me || emailConfirmed) return
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
import emojify from '../emoji';
|
||||
|
||||
describe('emoji', () => {
|
||||
describe('.emojify', () => {
|
||||
it('ignores unknown shortcodes', () => {
|
||||
expect(emojify(':foobarbazfake:')).toEqual(':foobarbazfake:');
|
||||
});
|
||||
|
||||
it('ignores shortcodes inside of tags', () => {
|
||||
expect(emojify('<p data-foo=":smile:"></p>')).toEqual('<p data-foo=":smile:"></p>');
|
||||
});
|
||||
|
||||
it('works with unclosed tags', () => {
|
||||
expect(emojify('hello>')).toEqual('hello>');
|
||||
expect(emojify('<hello')).toEqual('<hello');
|
||||
});
|
||||
|
||||
it('works with unclosed shortcodes', () => {
|
||||
expect(emojify('smile:')).toEqual('smile:');
|
||||
expect(emojify(':smile')).toEqual(':smile');
|
||||
});
|
||||
|
||||
it('does unicode', () => {
|
||||
expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="👩👩👦👦" title=":woman-woman-boy-boy:" src="/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg" />');
|
||||
expect(emojify('👨👩👧👧')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="👨👩👧👧" title=":man-woman-girl-girl:" src="/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg" />');
|
||||
expect(emojify('👩👩👦')).toEqual('<img draggable="false" class="emojione" alt="👩👩👦" title=":woman-woman-boy:" src="/emoji/1f469-200d-1f469-200d-1f466.svg" />');
|
||||
expect(emojify('\u2757')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />');
|
||||
});
|
||||
|
||||
it('does multiple unicode', () => {
|
||||
expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />');
|
||||
expect(emojify('\u2757#\uFE0F\u20E3')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /><img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />');
|
||||
expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual(
|
||||
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />');
|
||||
expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual(
|
||||
'foo <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> bar');
|
||||
});
|
||||
|
||||
it('ignores unicode inside of tags', () => {
|
||||
expect(emojify('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>')).toEqual('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>');
|
||||
});
|
||||
|
||||
it('does multiple emoji properly (issue 5188)', () => {
|
||||
expect(emojify('👌🌈💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /><img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />');
|
||||
expect(emojify('👌 🌈 💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /> <img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /> <img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />');
|
||||
});
|
||||
|
||||
it('does an emoji that has no shortcode', () => {
|
||||
expect(emojify('👁🗨')).toEqual('<img draggable="false" class="emojione" alt="👁🗨" title="" src="/emoji/1f441-200d-1f5e8.svg" />');
|
||||
});
|
||||
|
||||
it('does an emoji whose filename is irregular', () => {
|
||||
expect(emojify('↙️')).toEqual('<img draggable="false" class="emojione" alt="↙️" title=":arrow_lower_left:" src="/emoji/2199.svg" />');
|
||||
});
|
||||
|
||||
it('avoid emojifying on invisible text', () => {
|
||||
expect(emojify('<a href="http://example.com/test%F0%9F%98%84"><span class="invisible">http://</span><span class="ellipsis">example.com/te</span><span class="invisible">st😄</span></a>'))
|
||||
.toEqual('<a href="http://example.com/test%F0%9F%98%84"><span class="invisible">http://</span><span class="ellipsis">example.com/te</span><span class="invisible">st😄</span></a>');
|
||||
expect(emojify('<span class="invisible">:luigi:</span>', { ':luigi:': { static_url: 'luigi.exe' } }))
|
||||
.toEqual('<span class="invisible">:luigi:</span>');
|
||||
});
|
||||
|
||||
it('avoid emojifying on invisible text with nested tags', () => {
|
||||
expect(emojify('<span class="invisible">😄<span class="foo">bar</span>😴</span>😇'))
|
||||
.toEqual('<span class="invisible">😄<span class="foo">bar</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />');
|
||||
expect(emojify('<span class="invisible">😄<span class="invisible">😕</span>😴</span>😇'))
|
||||
.toEqual('<span class="invisible">😄<span class="invisible">😕</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />');
|
||||
expect(emojify('<span class="invisible">😄<br/>😴</span>😇'))
|
||||
.toEqual('<span class="invisible">😄<br/>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />');
|
||||
});
|
||||
|
||||
it('skips the textual presentation VS15 character', () => {
|
||||
expect(emojify('✴︎')) // This is U+2734 EIGHT POINTED BLACK STAR then U+FE0E VARIATION SELECTOR-15
|
||||
.toEqual('<img draggable="false" class="emojione" alt="✴" title=":eight_pointed_black_star:" src="/emoji/2734.svg" />');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,176 +0,0 @@
|
||||
import pick from 'lodash.pick'
|
||||
import { emojiIndex } from 'emoji-mart';
|
||||
import { search } from '../emoji_mart_search_light';
|
||||
|
||||
const trimEmojis = emoji => pick(emoji, ['id', 'unified', 'native', 'custom']);
|
||||
|
||||
describe('emoji_index', () => {
|
||||
it('should give same result for emoji_index_light and emoji-mart', () => {
|
||||
const expected = [
|
||||
{
|
||||
id: 'pineapple',
|
||||
unified: '1f34d',
|
||||
native: '🍍',
|
||||
},
|
||||
];
|
||||
expect(search('pineapple').map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('pineapple').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('orders search results correctly', () => {
|
||||
const expected = [
|
||||
{
|
||||
id: 'apple',
|
||||
unified: '1f34e',
|
||||
native: '🍎',
|
||||
},
|
||||
{
|
||||
id: 'pineapple',
|
||||
unified: '1f34d',
|
||||
native: '🍍',
|
||||
},
|
||||
{
|
||||
id: 'green_apple',
|
||||
unified: '1f34f',
|
||||
native: '🍏',
|
||||
},
|
||||
{
|
||||
id: 'iphone',
|
||||
unified: '1f4f1',
|
||||
native: '📱',
|
||||
},
|
||||
];
|
||||
expect(search('apple').map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('apple').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('can include/exclude categories', () => {
|
||||
expect(search('flag', { include: ['people'] })).toEqual([]);
|
||||
expect(emojiIndex.search('flag', { include: ['people'] })).toEqual([]);
|
||||
});
|
||||
|
||||
it('(different behavior from emoji-mart) do not erases custom emoji if not passed again', () => {
|
||||
const custom = [
|
||||
{
|
||||
id: 'gabsocial',
|
||||
name: 'gabsocial',
|
||||
short_names: ['gabsocial'],
|
||||
text: '',
|
||||
emoticons: [],
|
||||
keywords: ['gabsocial'],
|
||||
imageUrl: 'http://example.com',
|
||||
custom: true,
|
||||
},
|
||||
];
|
||||
search('', { custom });
|
||||
emojiIndex.search('', { custom });
|
||||
const expected = [];
|
||||
const lightExpected = [
|
||||
{
|
||||
id: 'gabsocial',
|
||||
custom: true,
|
||||
},
|
||||
];
|
||||
expect(search('masto').map(trimEmojis)).toEqual(lightExpected);
|
||||
expect(emojiIndex.search('masto').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('(different behavior from emoji-mart) erases custom emoji if another is passed', () => {
|
||||
const custom = [
|
||||
{
|
||||
id: 'gabsocial',
|
||||
name: 'gabsocial',
|
||||
short_names: ['gabsocial'],
|
||||
text: '',
|
||||
emoticons: [],
|
||||
keywords: ['gabsocial'],
|
||||
imageUrl: 'http://example.com',
|
||||
custom: true,
|
||||
},
|
||||
];
|
||||
search('', { custom });
|
||||
emojiIndex.search('', { custom });
|
||||
const expected = [];
|
||||
expect(search('masto', { custom: [] }).map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('masto').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('handles custom emoji', () => {
|
||||
const custom = [
|
||||
{
|
||||
id: 'gabsocial',
|
||||
name: 'gabsocial',
|
||||
short_names: ['gabsocial'],
|
||||
text: '',
|
||||
emoticons: [],
|
||||
keywords: ['gabsocial'],
|
||||
imageUrl: 'http://example.com',
|
||||
custom: true,
|
||||
},
|
||||
];
|
||||
search('', { custom });
|
||||
emojiIndex.search('', { custom });
|
||||
const expected = [
|
||||
{
|
||||
id: 'gabsocial',
|
||||
custom: true,
|
||||
},
|
||||
];
|
||||
expect(search('masto', { custom }).map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('masto', { custom }).map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should filter only emojis we care about, exclude pineapple', () => {
|
||||
const emojisToShowFilter = emoji => emoji.unified !== '1F34D';
|
||||
expect(search('apple', { emojisToShowFilter }).map((obj) => obj.id))
|
||||
.not.toContain('pineapple');
|
||||
expect(emojiIndex.search('apple', { emojisToShowFilter }).map((obj) => obj.id))
|
||||
.not.toContain('pineapple');
|
||||
});
|
||||
|
||||
it('does an emoji whose unified name is irregular', () => {
|
||||
const expected = [
|
||||
{
|
||||
'id': 'water_polo',
|
||||
'unified': '1f93d',
|
||||
'native': '🤽',
|
||||
},
|
||||
{
|
||||
'id': 'man-playing-water-polo',
|
||||
'unified': '1f93d-200d-2642-fe0f',
|
||||
'native': '🤽♂️',
|
||||
},
|
||||
{
|
||||
'id': 'woman-playing-water-polo',
|
||||
'unified': '1f93d-200d-2640-fe0f',
|
||||
'native': '🤽♀️',
|
||||
},
|
||||
];
|
||||
expect(search('polo').map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('polo').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('can search for thinking_face', () => {
|
||||
const expected = [
|
||||
{
|
||||
id: 'thinking_face',
|
||||
unified: '1f914',
|
||||
native: '🤔',
|
||||
},
|
||||
];
|
||||
expect(search('thinking_fac').map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('thinking_fac').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('can search for woman-facepalming', () => {
|
||||
const expected = [
|
||||
{
|
||||
id: 'woman-facepalming',
|
||||
unified: '1f926-200d-2640-fe0f',
|
||||
native: '🤦♀️',
|
||||
},
|
||||
];
|
||||
expect(search('woman-facep').map(trimEmojis)).toEqual(expected);
|
||||
expect(emojiIndex.search('woman-facep').map(trimEmojis)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -54,7 +54,7 @@ class Image extends React.PureComponent {
|
||||
<img
|
||||
alt={alt}
|
||||
className={classes}
|
||||
{...otherProps}
|
||||
{...otherProps} // : todo : remove
|
||||
ref={imageRef}
|
||||
src={src}
|
||||
onError={this.handleOnError}
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import api from '../../api'
|
||||
import ModalLayout from './modal_layout'
|
||||
import Divider from '../divider'
|
||||
import Icon from '../icon'
|
||||
import Input from '../input'
|
||||
import Text from '../text'
|
||||
|
||||
class EmbedModal extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
loading: false,
|
||||
oembed: null,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { url } = this.props
|
||||
|
||||
this.setState({ loading: true })
|
||||
|
||||
api().post('/api/web/embed', { url }).then(res => {
|
||||
this.setState({ loading: false, oembed: res.data })
|
||||
|
||||
const iframeDocument = this.iframe.contentWindow.document
|
||||
|
||||
iframeDocument.open()
|
||||
iframeDocument.write(res.data.html)
|
||||
iframeDocument.close()
|
||||
|
||||
iframeDocument.body.style.margin = 0
|
||||
this.iframe.width = iframeDocument.body.scrollWidth
|
||||
this.iframe.height = iframeDocument.body.scrollHeight
|
||||
}).catch(error => {
|
||||
this.props.onError(error)
|
||||
})
|
||||
}
|
||||
|
||||
setIframeRef = c => {
|
||||
this.iframe = c
|
||||
}
|
||||
|
||||
handleTextareaClick = (e) => {
|
||||
e.target.select()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, onClose } = this.props
|
||||
const { oembed } = this.state
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
title={intl.formatMessage(messages.embed)}
|
||||
onClose={onClose}
|
||||
>
|
||||
<div className={_s.d}>
|
||||
<Text className={_s.my10}>
|
||||
{intl.formatMessage(messages.instructions)}
|
||||
</Text>
|
||||
|
||||
<div className={[_s.d, _s.mb10].join(' ')}>
|
||||
<Input
|
||||
readOnly
|
||||
type='text'
|
||||
value={oembed && oembed.html || ''}
|
||||
onClick={this.handleTextareaClick}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Text className={_s.mb10}>
|
||||
{intl.formatMessage(messages.preview)}
|
||||
</Text>
|
||||
|
||||
<div className={[_s.d, _s.w100PC, _s.bgSubtle, _s.h220PX, _s.aiCenter, _s.jcCenter].join(' ')}>
|
||||
<iframe
|
||||
className={[_s.d, _s.w100PC, _s.h100PC, _s.z2].join(' ')}
|
||||
frameBorder='0'
|
||||
ref={this.setIframeRef}
|
||||
sandbox='allow-same-origin'
|
||||
title='preview'
|
||||
/>
|
||||
{
|
||||
!oembed &&
|
||||
<Icon id='loading' size='34px' className={[_s.posAbs, _s.z3].join(' ')} />
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ModalLayout>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
||||
instructions: { id: 'embed.instructions', defaultMessage: 'Embed this status on your website by copying the code below.' },
|
||||
preview: { id: 'embed.preview', defaultMessage: 'Here is what it will look like:' },
|
||||
})
|
||||
|
||||
EmbedModal.propTypes = {
|
||||
url: PropTypes.string.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
onError: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default injectIntl(EmbedModal)
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
MODAL_EDIT_PROFILE,
|
||||
MODAL_EDIT_SHORTCUTS,
|
||||
MODAL_EMAIL_CONFIRMATION_REMINDER,
|
||||
MODAL_EMBED,
|
||||
MODAL_GROUP_CREATE,
|
||||
MODAL_GROUP_DELETE,
|
||||
MODAL_GROUP_PASSWORD,
|
||||
@@ -50,7 +49,6 @@ import {
|
||||
EditProfileModal,
|
||||
EditShortcutsModal,
|
||||
EmailConfirmationReminderModal,
|
||||
EmbedModal,
|
||||
GroupCreateModal,
|
||||
GroupDeleteModal,
|
||||
GroupMembersModal,
|
||||
@@ -86,7 +84,6 @@ MODAL_COMPONENTS[MODAL_DISPLAY_OPTIONS] = DisplayOptionsModal
|
||||
MODAL_COMPONENTS[MODAL_EDIT_SHORTCUTS] = EditShortcutsModal
|
||||
MODAL_COMPONENTS[MODAL_EDIT_PROFILE] = EditProfileModal
|
||||
MODAL_COMPONENTS[MODAL_EMAIL_CONFIRMATION_REMINDER] = EmailConfirmationReminderModal
|
||||
MODAL_COMPONENTS[MODAL_EMBED] = EmbedModal
|
||||
MODAL_COMPONENTS[MODAL_GROUP_CREATE] = GroupCreateModal
|
||||
MODAL_COMPONENTS[MODAL_GROUP_DELETE] = GroupDeleteModal
|
||||
MODAL_COMPONENTS[MODAL_GROUP_PASSWORD] = GroupPasswordModal
|
||||
|
||||
@@ -12,19 +12,38 @@ import MediaGalleryPanelPlaceholder from '../placeholder/media_gallery_panel_pla
|
||||
|
||||
class MediaGalleryPanel extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
fetched: false,
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.shouldLoad && !prevState.fetched) {
|
||||
return { fetched: true }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.fetched && this.state.fetched && this.props.isLazy) {
|
||||
this.props.dispatch(expandAccountMediaTimeline(this.props.accountId, { limit: 8 }))
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { accountId } = this.props
|
||||
const { accountId, isLazy } = this.props
|
||||
|
||||
if (accountId && accountId !== -1) {
|
||||
if (!isLazy && !!accountId && accountId !== -1) {
|
||||
this.props.dispatch(expandAccountMediaTimeline(accountId, { limit: 8 }))
|
||||
this.setState({ fetched: true })
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.accountId && nextProps.accountId !== this.props.accountId) {
|
||||
this.props.dispatch(expandAccountMediaTimeline(nextProps.accountId, { limit: 8 }))
|
||||
}
|
||||
}
|
||||
// componentWillReceiveProps(nextProps) {
|
||||
// if (nextProps.accountId && nextProps.accountId !== this.props.accountId) {
|
||||
// this.props.dispatch(expandAccountMediaTimeline(nextProps.accountId, { limit: 8 }))
|
||||
// }
|
||||
// }
|
||||
|
||||
render() {
|
||||
const {
|
||||
@@ -33,8 +52,9 @@ class MediaGalleryPanel extends ImmutablePureComponent {
|
||||
intl,
|
||||
isLoading,
|
||||
} = this.props
|
||||
const { fetched } = this.state
|
||||
|
||||
if (!attachments) return null
|
||||
if (!attachments && fetched) return null
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
|
||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { me, favouritesCount } from '../../initial_state'
|
||||
import { me } from '../../initial_state'
|
||||
import { shortNumberFormat } from '../../utils/numbers'
|
||||
import PanelLayout from './panel_layout'
|
||||
import UserStat from '../user_stat'
|
||||
@@ -56,7 +56,7 @@ class ProfileStatsPanel extends ImmutablePureComponent {
|
||||
account.get('id') === me &&
|
||||
<UserStat
|
||||
title={intl.formatMessage(messages.likes)}
|
||||
value={shortNumberFormat(favouritesCount)}
|
||||
value={shortNumberFormat(0)}
|
||||
to={`/${account.get('acct')}/likes`}
|
||||
isCentered={noPanel}
|
||||
/>
|
||||
|
||||
@@ -14,8 +14,6 @@ import {
|
||||
unbookmark,
|
||||
} from '../../actions/interactions';
|
||||
import {
|
||||
muteStatus,
|
||||
unmuteStatus,
|
||||
deleteStatus,
|
||||
editStatus,
|
||||
} from '../../actions/statuses';
|
||||
@@ -27,7 +25,6 @@ import {
|
||||
pinGroupStatus,
|
||||
unpinGroupStatus,
|
||||
} from '../../actions/groups'
|
||||
import { initMuteModal } from '../../actions/mutes'
|
||||
import { initReport } from '../../actions/reports'
|
||||
import { openModal } from '../../actions/modal'
|
||||
import {
|
||||
@@ -35,7 +32,6 @@ import {
|
||||
openPopover,
|
||||
} from '../../actions/popover'
|
||||
import {
|
||||
MODAL_EMBED,
|
||||
MODAL_PRO_UPGRADE,
|
||||
POPOVER_STATUS_SHARE,
|
||||
} from '../../constants'
|
||||
@@ -57,13 +53,12 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||
componentDidMount() {
|
||||
if (!this.props.groupRelationships && this.props.groupId) {
|
||||
this.props.onFetchGroupRelationships(this.props.groupId)
|
||||
// : todo :
|
||||
// check if pin
|
||||
// check if bookmark
|
||||
}
|
||||
}
|
||||
|
||||
handleConversationMuteClick = () => {
|
||||
this.props.onMuteConversation(this.props.status)
|
||||
}
|
||||
|
||||
handleGroupRemoveAccount = () => {
|
||||
const { status } = this.props
|
||||
|
||||
@@ -144,15 +139,6 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||
let menu = []
|
||||
|
||||
if (me) {
|
||||
if (status.getIn(['account', 'id']) === me) {
|
||||
menu.push({
|
||||
icon: 'audio-mute',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
||||
onClick: this.handleConversationMuteClick,
|
||||
})
|
||||
}
|
||||
|
||||
if (isReply) {
|
||||
menu.push({
|
||||
icon: 'repost',
|
||||
@@ -296,8 +282,6 @@ const messages = defineMessages({
|
||||
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
|
||||
like: { id: 'status.like', defaultMessage: 'Like' },
|
||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
||||
groupPin: { id: 'status.group_pin', defaultMessage: 'Pin in group' },
|
||||
@@ -327,16 +311,6 @@ const mapStateToProps = (state, { status }) => {
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onMuteConversation(status) {
|
||||
dispatch(closePopover())
|
||||
|
||||
if (status.get('muted')) {
|
||||
dispatch(unmuteStatus(status.get('id')))
|
||||
} else {
|
||||
dispatch(muteStatus(status.get('id')))
|
||||
}
|
||||
},
|
||||
|
||||
onPin(status) {
|
||||
dispatch(closePopover())
|
||||
|
||||
@@ -411,11 +385,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(editStatus(status))
|
||||
},
|
||||
|
||||
onMute(account) {
|
||||
dispatch(closePopover())
|
||||
dispatch(initMuteModal(account))
|
||||
},
|
||||
|
||||
onBlock(status) {
|
||||
dispatch(closePopover())
|
||||
const account = status.get('account')
|
||||
@@ -480,11 +449,9 @@ StatusOptionsPopover.propTypes = {
|
||||
onMute: PropTypes.func.isRequired,
|
||||
onBlock: PropTypes.func.isRequired,
|
||||
onReport: PropTypes.func.isRequired,
|
||||
onMuteConversation: PropTypes.func.isRequired,
|
||||
onPin: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onFetchGroupRelationships: PropTypes.func.isRequired,
|
||||
onOpenEmbedModal: PropTypes.func.isRequired,
|
||||
onOpenProUpgradeModal: PropTypes.func.isRequired,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
|
||||
@@ -82,6 +82,7 @@ class DefaultSidebar extends ImmutablePureComponent {
|
||||
</SidebarSectionTitle>
|
||||
<SidebarSectionItem title='Home' icon='home' to='/home' count={homeItemsQueueCount} />
|
||||
<SidebarSectionItem title='Notifications' icon='notifications' to='/notifications' count={notificationCount} />
|
||||
<SidebarSectionItem title='Chats' icon='chat' to='/messages' />
|
||||
<SidebarSectionItem title='Groups' icon='group' to='/groups' />
|
||||
<SidebarSectionItem title='Lists' icon='list' to='/lists' />
|
||||
<SidebarSectionItem title='Explore' icon='explore' to='/explore' />
|
||||
|
||||
@@ -52,7 +52,7 @@ class TabBarItem extends React.PureComponent {
|
||||
|
||||
// Combine state, props, location to make absolutely
|
||||
// sure of active status.
|
||||
const active = isActive || (to === location.pathname && !location.search) || isCurrent
|
||||
const active = (isActive === true || isCurrent || (to === location.pathname && !location.search))
|
||||
|
||||
const containerClasses = CX({
|
||||
d: 1,
|
||||
|
||||
125
app/javascript/gabsocial/components/toast.js
Normal file
125
app/javascript/gabsocial/components/toast.js
Normal file
@@ -0,0 +1,125 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {
|
||||
CX,
|
||||
TOAST_TYPE_ERROR,
|
||||
TOAST_TYPE_SUCCESS,
|
||||
// TOAST_TYPE_NOTIFICATION,
|
||||
} from '../constants'
|
||||
import Button from './button'
|
||||
import Image from './image'
|
||||
import RelativeTimestamp from './relative_timestamp'
|
||||
import Text from './text'
|
||||
|
||||
class Toast extends React.PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this._timer = setTimeout(() => {
|
||||
this.handleOnDismiss()
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this._timer)
|
||||
}
|
||||
|
||||
handleOnDismiss = () => {
|
||||
this.props.onDismiss(this.props.id)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
image,
|
||||
isImageAccount,
|
||||
title,
|
||||
message,
|
||||
date,
|
||||
to,
|
||||
type,
|
||||
} = this.props
|
||||
|
||||
const contentClasses = CX({
|
||||
default: 1,
|
||||
mt5: 1,
|
||||
pt2: 1,
|
||||
maxWidth240PX: 1,
|
||||
flexRow: !!image,
|
||||
})
|
||||
|
||||
const innerContentClasses = CX({
|
||||
default: 1,
|
||||
flexNormal: 1,
|
||||
pl10: !!image,
|
||||
pt2: !!image,
|
||||
displayInline: !!date && !image,
|
||||
})
|
||||
|
||||
const imageClasses = CX({
|
||||
radiusSmall: !isImageAccount,
|
||||
circle: isImageAccount,
|
||||
})
|
||||
|
||||
const dateClasses = CX({
|
||||
mr5: 1,
|
||||
mt2: !!image,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.radiusSmall, _s.mb5, _s.px15, _s.pt10, _s.pb15, _s.bgPrimary, _s.boxShadowToast].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
|
||||
<Text size='media' weight='medium' className={[_s.mr15, _s.minWidth160PX].join(' ')}>
|
||||
{title}
|
||||
</Text>
|
||||
<Button
|
||||
backgroundColor='secondary'
|
||||
color='primary'
|
||||
icon='close'
|
||||
iconSize='6px'
|
||||
onClick={this.handleOnDismiss}
|
||||
className={[_s.mlAuto, _s.px10].join(' ')}
|
||||
/>
|
||||
</div>
|
||||
<div className={contentClasses}>
|
||||
{
|
||||
!!image &&
|
||||
<Image
|
||||
src={image}
|
||||
className={imageClasses}
|
||||
height='52px'
|
||||
width='52px'
|
||||
/>
|
||||
}
|
||||
<div className={innerContentClasses}>
|
||||
<Text size='small'>
|
||||
{message}
|
||||
</Text>
|
||||
{
|
||||
date &&
|
||||
<Text color='secondary' size='extraSmall' className={dateClasses}>
|
||||
<RelativeTimestamp timestamp={date} />
|
||||
</Text>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Toast.propTypes = {
|
||||
date: PropTypes.string.isRequired,
|
||||
image: PropTypes.string,
|
||||
isImageAccount: PropTypes.bool,
|
||||
id: PropTypes.string.isRequired,
|
||||
message: PropTypes.string.isRequired,
|
||||
onDismiss: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
to: PropTypes.string,
|
||||
type: PropTypes.oneOf([
|
||||
TOAST_TYPE_ERROR,
|
||||
TOAST_TYPE_SUCCESS,
|
||||
]).isRequired,
|
||||
}
|
||||
|
||||
export default Toast
|
||||
@@ -11,6 +11,8 @@ export const BREAKPOINT_MEDIUM = 1160
|
||||
export const BREAKPOINT_SMALL = 1080
|
||||
export const BREAKPOINT_EXTRA_SMALL = 992
|
||||
|
||||
export const LAZY_LOAD_SCROLL_OFFSET = 50
|
||||
|
||||
export const ALLOWED_AROUND_SHORT_CODE = '><\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'
|
||||
export const MAX_POST_CHARACTER_COUNT = 3000
|
||||
|
||||
@@ -48,7 +50,6 @@ export const MODAL_DISPLAY_OPTIONS = 'DISPLAY_OPTIONS'
|
||||
export const MODAL_EDIT_PROFILE = 'EDIT_PROFILE'
|
||||
export const MODAL_EDIT_SHORTCUTS = 'EDIT_SHORTCUTS'
|
||||
export const MODAL_EMAIL_CONFIRMATION_REMINDER = 'EMAIL_CONFIRMATION_REMINDER'
|
||||
export const MODAL_EMBED = 'EMBED'
|
||||
export const MODAL_GROUP_CREATE = 'GROUP_CREATE'
|
||||
export const MODAL_GROUP_DELETE = 'GROUP_DELETE'
|
||||
export const MODAL_GROUP_PASSWORD = 'GROUP_PASSWORD'
|
||||
|
||||
67
app/javascript/gabsocial/containers/toasts_container.js
Normal file
67
app/javascript/gabsocial/containers/toasts_container.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { getToasts } from '../selectors'
|
||||
import { dismissToast } from '../actions/toasts'
|
||||
import { CX } from '../constants'
|
||||
import Toast from '../components/toast'
|
||||
|
||||
class ToastsContainer extends React.PureComponent {
|
||||
|
||||
handleOnDismiss = (key) => {
|
||||
this.props.dispatch(dismissToast(key))
|
||||
}
|
||||
|
||||
render() {
|
||||
const { notifications } = this.props
|
||||
const hasNotifications = Array.isArray(notifications) && notifications.length > 0
|
||||
|
||||
const containerClasses = CX({
|
||||
default: 1,
|
||||
z5: 1,
|
||||
posFixed: 1,
|
||||
bottom0: 1,
|
||||
left0: 1,
|
||||
pl15: 1,
|
||||
pt15: 1,
|
||||
heightMax100VH: 1,
|
||||
pb10: 1,
|
||||
displayNone: !hasNotifications
|
||||
})
|
||||
|
||||
return (
|
||||
<div className={containerClasses}>
|
||||
{
|
||||
hasNotifications && notifications.map((notification) => (
|
||||
<Toast
|
||||
onDismiss={this.handleOnDismiss}
|
||||
key={notification.key}
|
||||
id={notification.key}
|
||||
title={notification.title}
|
||||
type={notification.type}
|
||||
to={notification.to}
|
||||
image={notification.image}
|
||||
message={notification.message}
|
||||
date={notification.date}
|
||||
isImageAccount={notification.isImageAccount}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const notifications = getToasts(state)
|
||||
if (!notifications) return {}
|
||||
return { notifications }
|
||||
}
|
||||
|
||||
ToastsContainer.propTypes = {
|
||||
notifications: PropTypes.array,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(ToastsContainer)
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
GAB_COM_INTRODUCE_YOURSELF_GROUP_ID,
|
||||
} from '../constants'
|
||||
import { me } from '../initial_state'
|
||||
import { saveShownOnboarding } from '../actions/onboarding'
|
||||
import { saveShownOnboarding } from '../actions/settings'
|
||||
import { fetchGroups } from '../actions/groups'
|
||||
import { saveUserProfileInformation } from '../actions/user'
|
||||
import { makeGetAccount } from '../selectors'
|
||||
|
||||
@@ -4,7 +4,6 @@ import { connect } from 'react-redux'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import { connectListStream } from '../actions/streaming'
|
||||
import { expandListTimeline } from '../actions/timelines'
|
||||
import { fetchList, deleteList } from '../actions/lists'
|
||||
import { openModal } from '../actions/modal'
|
||||
@@ -29,7 +28,6 @@ class ListTimeline extends ImmutablePureComponent {
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.params.id !== this.props.params.id) {
|
||||
this.handleDisconnect()
|
||||
this.handleConnect(nextProps.params.id)
|
||||
}
|
||||
}
|
||||
@@ -39,15 +37,6 @@ class ListTimeline extends ImmutablePureComponent {
|
||||
|
||||
dispatch(fetchList(id))
|
||||
dispatch(expandListTimeline(id))
|
||||
|
||||
this.disconnect = dispatch(connectListStream(id))
|
||||
}
|
||||
|
||||
handleDisconnect() {
|
||||
if (this.disconnect) {
|
||||
this.disconnect()
|
||||
this.disconnect = null
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMore = (maxId) => {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { CX } from '../../../constants'
|
||||
import Input from '../../../components/input'
|
||||
import Avatar from '../../../components/avatar'
|
||||
import Button from '../../../components/button'
|
||||
import Text from '../../../components/text'
|
||||
import RelativeTimestamp from '../../../components/relative_timestamp'
|
||||
import { makeGetAccount } from '../../../selectors'
|
||||
|
||||
class MessagesItem extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
}
|
||||
|
||||
state = {
|
||||
hovering: false,
|
||||
}
|
||||
|
||||
handleOnMouseEnter = () => {
|
||||
this.setState({ isHovering: true })
|
||||
}
|
||||
|
||||
handleOnMouseLeave = () => {
|
||||
this.setState({ isHovering: false })
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
intl,
|
||||
alt,
|
||||
} = this.props
|
||||
const { isHovering } = this.state
|
||||
|
||||
const content = { __html: 'REEEE i heard you have the sauce2?' }
|
||||
const messageContainerClasses = CX({
|
||||
d: 1,
|
||||
flexRow: !alt,
|
||||
flexRowReverse: alt,
|
||||
})
|
||||
const messageInnerContainerClasses = CX({
|
||||
d: 1,
|
||||
px15: 1,
|
||||
py5: 1,
|
||||
bgSecondary: !alt,
|
||||
bgBrandLight: alt,
|
||||
circle: 1,
|
||||
ml10: 1,
|
||||
mr10: 1,
|
||||
})
|
||||
|
||||
const lowerContainerClasses = CX({
|
||||
d: 1,
|
||||
pt10: 1,
|
||||
pl50: !alt,
|
||||
pr50: alt,
|
||||
})
|
||||
|
||||
const buttonContainerClasses = CX({
|
||||
d: 1,
|
||||
flexRow: 1,
|
||||
displayNone: !isHovering,
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
className={[_s.d, _s.w100PC, _s.pb10].join(' ')}
|
||||
onMouseEnter={this.handleOnMouseEnter}
|
||||
onMouseLeave={this.handleOnMouseLeave}
|
||||
>
|
||||
<div className={[_s.d, _s.w100PC, _s.pb15].join(' ')}>
|
||||
|
||||
<div className={messageContainerClasses}>
|
||||
<Avatar account={account} size={38} />
|
||||
<div className={messageInnerContainerClasses}>
|
||||
<div className={[_s.py5, _s.dangerousContent].join(' ')} dangerouslySetInnerHTML={content} />
|
||||
</div>
|
||||
<div className={buttonContainerClasses}>
|
||||
<Button
|
||||
onClick={undefined}
|
||||
color='tertiary'
|
||||
backgroundColor='none'
|
||||
icon='ellipsis'
|
||||
iconSize='18px'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={lowerContainerClasses}>
|
||||
<Text size='small' color='tertiary' align={alt ? 'right' : 'left'}>
|
||||
Apr 16, 2020, 8:20 AM
|
||||
{ /* <RelativeTimestamp timestamp={'2020-20-10'} /> */ }
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
account: makeGetAccount()(state, '1'),
|
||||
})
|
||||
|
||||
MessagesItem.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
alt: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(MessagesItem)
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import Heading from '../../../components/heading'
|
||||
import Button from '../../../components/button'
|
||||
|
||||
class MessagesHeader extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.w100PC, _s.h60PX, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<div className={[_s.d, _s.flexRow, _s.pl15, _s.pr5, _s.py15].join(' ')}>
|
||||
<Heading size='h1'>
|
||||
Messages
|
||||
</Heading>
|
||||
<div className={[_s.d, _s.bgTransparent, _s.flexRow, _s.aiCenter, _s.jcCenter, _s.mlAuto].join(' ')}>
|
||||
<Button
|
||||
isNarrow
|
||||
onClick={undefined}
|
||||
className={[_s.ml5, _s.px15].join(' ')}
|
||||
>
|
||||
New
|
||||
</Button>
|
||||
<Button
|
||||
isNarrow
|
||||
onClick={undefined}
|
||||
color='brand'
|
||||
backgroundColor='none'
|
||||
className={_s.ml5}
|
||||
icon='cog'
|
||||
iconSize='18px'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default MessagesHeader
|
||||
@@ -0,0 +1,36 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import MessagesListItem from './messages_list_item'
|
||||
import { makeGetAccount } from '../../../selectors'
|
||||
|
||||
class MessagesList extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.w100PC].join(' ')}>
|
||||
<MessagesListItem />
|
||||
<MessagesListItem selected />
|
||||
<MessagesListItem />
|
||||
<MessagesListItem />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
account: makeGetAccount()(state, '1'),
|
||||
})
|
||||
|
||||
MessagesList.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(MessagesList)
|
||||
@@ -0,0 +1,107 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { CX } from '../../../constants'
|
||||
import Input from '../../../components/input'
|
||||
import DisplayName from '../../../components/display_name'
|
||||
import Avatar from '../../../components/avatar'
|
||||
import Text from '../../../components/text'
|
||||
import RelativeTimestamp from '../../../components/relative_timestamp'
|
||||
import { makeGetAccount } from '../../../selectors'
|
||||
|
||||
class MessagesListItem extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
}
|
||||
|
||||
state = {
|
||||
composeFocused: false,
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
intl,
|
||||
selected,
|
||||
} = this.props
|
||||
|
||||
const buttonClasses = CX({
|
||||
d: 1,
|
||||
pt2: 1,
|
||||
pr5: 1,
|
||||
noUnderline: 1,
|
||||
overflowHidden: 1,
|
||||
flexNormal: 1,
|
||||
flexRow: 1,
|
||||
aiStart: 1,
|
||||
aiCenter: 1,
|
||||
})
|
||||
|
||||
const containerClasses = CX({
|
||||
d: 1,
|
||||
bgSubtle_onHover: 1,
|
||||
borderBottom1PX: 1,
|
||||
borderColorSecondary: 1,
|
||||
noUnderline: 1,
|
||||
})
|
||||
|
||||
const innerContainerClasses = CX({
|
||||
d: 1,
|
||||
flexRow: 1,
|
||||
aiStart: 1,
|
||||
aiCenter: 0,
|
||||
px15: 1,
|
||||
py15: 1,
|
||||
borderRight4PX: selected,
|
||||
borderColorBrand: selected,
|
||||
})
|
||||
|
||||
const avatarSize = 49
|
||||
const content = { __html: 'REEEE i heard you have the sauce?' }
|
||||
|
||||
return (
|
||||
<NavLink
|
||||
className={containerClasses}
|
||||
title={account.get('acct')}
|
||||
to={`/messages/conversation-id`}
|
||||
>
|
||||
<div className={innerContainerClasses}>
|
||||
|
||||
<Avatar account={account} size={avatarSize} noHover />
|
||||
|
||||
<div className={[_s.d, _s.pl10, _s.overflowHidden, _s.flexNormal].join(' ')}>
|
||||
<div className={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
|
||||
<div className={buttonClasses}>
|
||||
<div className={_s.maxW100PC42PX}>
|
||||
<DisplayName account={account} noHover />
|
||||
</div>
|
||||
<Text size='extraSmall' color='secondary' className={_s.mlAuto}>
|
||||
May 1
|
||||
{ /* <RelativeTimestamp timestamp={'2020-20-10'} /> */ }
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={[_s.py5, _s.dangerousContent].join(' ')} dangerouslySetInnerHTML={content} />
|
||||
</div>
|
||||
</div>
|
||||
</NavLink>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
account: makeGetAccount()(state, '1'),
|
||||
})
|
||||
|
||||
MessagesListItem.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
selected: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(MessagesListItem)
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import Input from '../../../components/input'
|
||||
|
||||
class MessagesSearch extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
}
|
||||
|
||||
state = {
|
||||
composeFocused: false,
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.h60PX, _s.w100PC, _s.px10, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<Input
|
||||
type='search'
|
||||
placeholder='Search for messages'
|
||||
id='messages-search'
|
||||
prependIcon='search'
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: "What's on your mind?" },
|
||||
})
|
||||
|
||||
MessagesSearch.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default injectIntl(MessagesSearch)
|
||||
1
app/javascript/gabsocial/features/messages/index.js
Normal file
1
app/javascript/gabsocial/features/messages/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './messages'
|
||||
103
app/javascript/gabsocial/features/messages/messages.js
Normal file
103
app/javascript/gabsocial/features/messages/messages.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import Text from '../../components/text'
|
||||
import Button from '../../components/button'
|
||||
import Avatar from '../../components/avatar'
|
||||
import DisplayName from '../../components/display_name'
|
||||
import Input from '../../components/input'
|
||||
import EmojiPickerButton from '../compose/components/emoji_picker_button'
|
||||
import UploadButton from '../compose/components/media_upload_button'
|
||||
import MessageItem from './components/message_item'
|
||||
|
||||
// import MessagesContainer from './containers/messages_container'
|
||||
|
||||
class Messages extends React.PureComponent {
|
||||
|
||||
render () {
|
||||
const { account } = this.props
|
||||
|
||||
const selectedMessage = true
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.bgPrimary, _s.h100PC, _s.w100PC].join(' ')}>
|
||||
{
|
||||
!selectedMessage &&
|
||||
<div className={[_s.d, _s.w100PC, _s.h100PC, _s.aiCenter, _s.jcCenter].join(' ')}>
|
||||
<Text weight='bold' size='extraLarge'>
|
||||
You don’t have a message selected
|
||||
</Text>
|
||||
<Text size='medium' color='secondary' className={_s.py10}>
|
||||
Choose one from your existing messages, or start a new one.
|
||||
</Text>
|
||||
<Button className={_s.mt10}>
|
||||
<Text color='inherit' weight='bold' className={_s.px15}>
|
||||
New Message
|
||||
</Text>
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
selectedMessage &&
|
||||
<div className={[_s.d, _s.h100PC, _s.w100PC].join(' ')}>
|
||||
<div className={[_s.d, _s.posAbs, _s.top0, _s.left0, _s.right0, _s.flexRow, _s.aiCenter, _s.h60PX, _s.w100PC, _s.borderBottom1PX, _s.borderColorSecondary, _s.px15, _s.py5].join(' ')}>
|
||||
<Avatar account={account} size={34} />
|
||||
<div className={[_s.d, _s.pl10, _s.maxW100PC86PX, _s.overflowHidden].join(' ')}>
|
||||
<DisplayName account={account} isMultiline />
|
||||
</div>
|
||||
<Button
|
||||
isNarrow
|
||||
onClick={undefined}
|
||||
color='brand'
|
||||
backgroundColor='none'
|
||||
className={_s.mlAuto}
|
||||
icon='more'
|
||||
iconSize='18px'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={[_s.d, _s.posAbs, _s.bottom60PX, _s.left0, _s.right0, _s.px15, _s.py15, _s.top60PX, _s.w100PC, _s.overflowYScroll].join(' ')}>
|
||||
<MessageItem />
|
||||
<MessageItem />
|
||||
<MessageItem alt />
|
||||
<MessageItem />
|
||||
<MessageItem alt />
|
||||
<MessageItem alt />
|
||||
<MessageItem />
|
||||
<MessageItem />
|
||||
<MessageItem />
|
||||
<MessageItem alt />
|
||||
<MessageItem />
|
||||
</div>
|
||||
|
||||
<div className={[_s.d, _s.posAbs, _s.bottom0, _s.left0, _s.right0, _s.flexRow, _s.aiCenter, _s.h60PX, _s.w100PC, _s.borderTop1PX, _s.borderColorSecondary, _s.px15, _s.py5].join(' ')}>
|
||||
<EmojiPickerButton />
|
||||
<UploadButton />
|
||||
<div className={[_s.d, _s.px15, _s.flexGrow1].join(' ')}>
|
||||
<Input
|
||||
placeholder='Type a message...'
|
||||
/>
|
||||
</div>
|
||||
<Button>
|
||||
Send
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
account: makeGetAccount()(state, '1'),
|
||||
})
|
||||
|
||||
Messages.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
selected: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(Messages)
|
||||
@@ -3,7 +3,10 @@ import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { fetchPopularLinks } from '../actions/links'
|
||||
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||
import {
|
||||
BREAKPOINT_EXTRA_SMALL,
|
||||
LAZY_LOAD_SCROLL_OFFSET,
|
||||
} from '../constants'
|
||||
import Button from '../components/button'
|
||||
import Text from '../components/text'
|
||||
import TrendsItem from '../components/trends_item'
|
||||
@@ -46,14 +49,12 @@ class News extends React.PureComponent {
|
||||
if (this.window) {
|
||||
const { scrollTop } = this.documentElement
|
||||
|
||||
if (scrollTop > 25 && !this.state.lazyLoaded) {
|
||||
if (scrollTop > LAZY_LOAD_SCROLL_OFFSET && !this.state.lazyLoaded) {
|
||||
this.setState({ lazyLoaded: true })
|
||||
this.detachScrollListener()
|
||||
}
|
||||
}
|
||||
}, 150, {
|
||||
trailing: true,
|
||||
})
|
||||
}, 150, { trailing: true })
|
||||
|
||||
render() {
|
||||
const { children } = this.props
|
||||
|
||||
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { expandProTimeline } from '../actions/timelines'
|
||||
import { connectProStream } from '../actions/streaming'
|
||||
import StatusList from '../components/status_list'
|
||||
|
||||
class ProTimeline extends React.PureComponent {
|
||||
@@ -16,15 +15,6 @@ class ProTimeline extends React.PureComponent {
|
||||
const { dispatch } = this.props
|
||||
|
||||
dispatch(expandProTimeline())
|
||||
|
||||
this.disconnect = dispatch(connectProStream())
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.disconnect) {
|
||||
this.disconnect()
|
||||
this.disconnect = null
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMore = (maxId) => {
|
||||
|
||||
@@ -6,7 +6,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { me } from '../initial_state'
|
||||
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
|
||||
import HashtagItem from '../components/hashtag_item'
|
||||
import GroupListItem from '../components/group_list_item'
|
||||
import Text from '../components/text'
|
||||
import Account from '../components/account'
|
||||
@@ -60,14 +59,13 @@ class Search extends ImmutablePureComponent {
|
||||
|
||||
const pathname = location.pathname || ''
|
||||
const showPeople = pathname === '/search/people'
|
||||
const showHashtags = pathname === '/search/hashtags'
|
||||
const showGroups = pathname === '/search/groups'
|
||||
const showStatuses = pathname === '/search/statuses'
|
||||
const showLinks = pathname === '/search/links'
|
||||
const isTop = !showPeople && !showHashtags && !showGroups && !showStatuses && !showLinks
|
||||
const isTop = !showPeople && !showGroups && !showStatuses && !showLinks
|
||||
const theLimit = 4
|
||||
|
||||
let accounts, statuses, hashtags, groups, links
|
||||
let accounts, statuses, groups, links
|
||||
|
||||
if (results.get('accounts') && results.get('accounts').size > 0 && (isTop || showPeople)) {
|
||||
const size = isTop ? Math.min(results.get('accounts').size, theLimit) : results.get('accounts').size;
|
||||
@@ -192,30 +190,7 @@ class Search extends ImmutablePureComponent {
|
||||
)
|
||||
}
|
||||
|
||||
if (results.get('hashtags') && results.get('hashtags').size > 0 && me && (isTop || showHashtags)) {
|
||||
const size = isTop ? Math.min(results.get('hashtags').size, theLimit) : results.get('hashtags').size;
|
||||
const isMax = size === results.get('hashtags').size
|
||||
|
||||
hashtags = (
|
||||
<PanelLayout
|
||||
title='Hashtags'
|
||||
headerButtonTo={isMax ? undefined : '/search/hashtags'}
|
||||
headerButtonTitle={isMax ? undefined : 'See more'}
|
||||
footerButtonTo={isMax ? undefined : '/search/hashtags'}
|
||||
footerButtonTitle={isMax ? undefined : 'See more'}
|
||||
noPadding
|
||||
>
|
||||
<div className={[_s.d, _s.pb10, _s.px15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<Text color='tertiary' size='small'>
|
||||
Showing {size} of {results.get('hashtags').size} results
|
||||
</Text>
|
||||
</div>
|
||||
{results.get('hashtags').slice(0, size).map(hashtag => <HashtagItem isCompact key={hashtag.get('name')} hashtag={hashtag} />)}
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
|
||||
if (!accounts && !statuses && !hashtags && !groups && !links) {
|
||||
if (!accounts && !statuses && !groups && !links) {
|
||||
return (
|
||||
<ResponsiveClassesComponent classNamesXS={[_s.px10, _s.pt15].join(' ')}>
|
||||
<Block>
|
||||
@@ -231,7 +206,6 @@ class Search extends ImmutablePureComponent {
|
||||
{groups}
|
||||
{statuses}
|
||||
{links}
|
||||
{hashtags}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import { clearHeight } from '../../actions/height_cache'
|
||||
import { openModal } from '../../actions/modal'
|
||||
import WrappedRoute from './util/wrapped_route'
|
||||
import ModalRoot from '../../components/modal/modal_root'
|
||||
import ToastsContainer from '../../containers/toasts_container'
|
||||
import PopoverRoot from '../../components/popover/popover_root'
|
||||
import UploadArea from '../../components/upload_area'
|
||||
import ProfilePage from '../../pages/profile_page'
|
||||
@@ -45,6 +46,8 @@ import ExplorePage from '../../pages/explore_page'
|
||||
import NewsPage from '../../pages/news_page'
|
||||
import AboutPage from '../../pages/about_page'
|
||||
import LinkPage from '../../pages/link_page'
|
||||
import MessagesPage from '../../pages/messages_page'
|
||||
import ComposePage from '../../pages/compose_page'
|
||||
|
||||
import {
|
||||
About,
|
||||
@@ -83,6 +86,7 @@ import {
|
||||
ListsDirectory,
|
||||
ListEdit,
|
||||
ListTimeline,
|
||||
Messages,
|
||||
Mutes,
|
||||
News,
|
||||
NewsView,
|
||||
@@ -190,12 +194,14 @@ class SwitchingArea extends React.PureComponent {
|
||||
|
||||
<WrappedRoute path='/explore' publicRoute page={ExplorePage} component={ExploreTimeline} content={children} componentParams={{ title: 'Explore' }} />
|
||||
<WrappedRoute path='/suggestions' exact page={BasicPage} component={Suggestions} content={children} componentParams={{ title: 'Suggestions' }} />
|
||||
|
||||
<WrappedRoute path='/compose' exact page={BasicPage} component={Compose} content={children} componentParams={{ title: 'Compose', page: 'compose' }} />
|
||||
<WrappedRoute path='/compose' exact page={ComposePage} component={Compose} content={children} componentParams={{ title: 'Compose', page: 'compose' }} />
|
||||
|
||||
<WrappedRoute path='/news' exact publicRoute page={NewsPage} component={News} content={children} componentParams={{ title: 'News' }} />
|
||||
<WrappedRoute path='/news/view/:trendsRSSId' page={NewsPage} component={NewsView} content={children} componentParams={{ title: 'News RSS Feed' }} />
|
||||
|
||||
<WrappedRoute path='/messages' exact page={MessagesPage} component={Messages} content={children} />
|
||||
<WrappedRoute path='/messages/:conversationId' exact page={MessagesPage} component={Messages} content={children} />
|
||||
|
||||
<WrappedRoute path='/timeline/all' exact page={CommunityPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Community Feed' }} />
|
||||
<WrappedRoute path='/timeline/pro' exact page={ProPage} component={ProTimeline} content={children} componentParams={{ title: 'Pro Feed' }} />
|
||||
|
||||
@@ -234,7 +240,6 @@ class SwitchingArea extends React.PureComponent {
|
||||
|
||||
<WrappedRoute path='/search' exact publicRoute page={SearchPage} component={Search} content={children} />
|
||||
<WrappedRoute path='/search/people' exact publicRoute page={SearchPage} component={Search} content={children} />
|
||||
<WrappedRoute path='/search/hashtags' exact publicRoute page={SearchPage} component={Search} content={children} />
|
||||
<WrappedRoute path='/search/groups' exact publicRoute page={SearchPage} component={Search} content={children} />
|
||||
<WrappedRoute path='/search/statuses' exact publicRoute page={SearchPage} component={Search} content={children} />
|
||||
<WrappedRoute path='/search/links' exact page={SearchPage} component={Search} content={children} />
|
||||
@@ -593,6 +598,8 @@ class UI extends React.PureComponent {
|
||||
<PopoverRoot />
|
||||
|
||||
<UploadArea active={draggingOver} onClose={this.closeUploadModal} />
|
||||
|
||||
<ToastsContainer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ export function DMCA() { return import(/* webpackChunkName: "features/about/dmca
|
||||
export function EditProfileModal() { return import(/* webpackChunkName: "components/edit_profile_modal" */'../../../components/modal/edit_profile_modal') }
|
||||
export function EditShortcutsModal() { return import(/* webpackChunkName: "components/edit_shortcuts_modal" */'../../../components/modal/edit_shortcuts_modal') }
|
||||
export function EmailConfirmationReminderModal() { return import(/* webpackChunkName: "components/email_confirmation_reminder_modal" */'../../../components/modal/email_confirmation_reminder_modal') }
|
||||
export function EmbedModal() { return import(/* webpackChunkName: "modals/embed_modal" */'../../../components/modal/embed_modal') }
|
||||
export function EmojiPicker() { return import(/* webpackChunkName: "emoji_picker" */'../../../components/emoji/emoji_picker') }
|
||||
export function EmojiPickerPopover() { return import(/* webpackChunkName: "components/emoji_picker_popover" */'../../../components/popover/emoji_picker_popover') }
|
||||
export function ExploreTimeline() { return import(/* webpackChunkName: "features/explore_timeline" */'../../explore_timeline') }
|
||||
|
||||
@@ -20,7 +20,6 @@ export const isStaff = getMeta('is_staff');
|
||||
export const unreadCount = getMeta('unread_count');
|
||||
export const lastReadNotificationId = getMeta('last_read_notification_id');
|
||||
export const monthlyExpensesComplete = getMeta('monthly_expenses_complete');
|
||||
export const favouritesCount = getMeta('favourites_count');
|
||||
export const isFirstSession = getMeta('is_first_session');
|
||||
export const emailConfirmed = getMeta('email_confirmed');
|
||||
export const meEmail = getMeta('email');
|
||||
|
||||
@@ -5,7 +5,10 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import throttle from 'lodash.throttle'
|
||||
import Sticky from 'react-stickynode'
|
||||
import { me } from '../initial_state'
|
||||
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||
import {
|
||||
BREAKPOINT_EXTRA_SMALL,
|
||||
LAZY_LOAD_SCROLL_OFFSET,
|
||||
} from '../constants'
|
||||
import Layout from './layout'
|
||||
import SidebarPanelGroup from '../components/sidebar_panel_group'
|
||||
import Responsive from '../features/ui/util/responsive_component'
|
||||
@@ -43,14 +46,12 @@ class ExploreLayout extends ImmutablePureComponent {
|
||||
if (this.window) {
|
||||
const { scrollTop } = this.documentElement
|
||||
|
||||
if (scrollTop > 25 && !this.state.lazyLoaded) {
|
||||
if (scrollTop > LAZY_LOAD_SCROLL_OFFSET && !this.state.lazyLoaded) {
|
||||
this.setState({ lazyLoaded: true })
|
||||
this.detachScrollListener()
|
||||
}
|
||||
}
|
||||
}, 150, {
|
||||
trailing: true,
|
||||
})
|
||||
}, 150, { trailing: true })
|
||||
|
||||
render() {
|
||||
const { children, title } = this.props
|
||||
@@ -67,7 +68,7 @@ class ExploreLayout extends ImmutablePureComponent {
|
||||
<WrappedBundle component={GroupsPanel} componentParams={{ groupType: 'featured' }} />,
|
||||
]
|
||||
if (!!me) {
|
||||
layout.push(<WrappedBundle component={UserSuggestionsPanel} componentParams={{ suggestionType: 'verified' }} />)
|
||||
layout.push(<WrappedBundle component={UserSuggestionsPanel} componentParams={{ isLazy: true, shouldLoad: lazyLoaded, suggestionType: 'verified' }} />)
|
||||
}
|
||||
layout.push(<WrappedBundle component={TrendsBreakingPanel} componentParams={{ isLazy: true, shouldLoad: lazyLoaded }} />)
|
||||
|
||||
|
||||
@@ -40,13 +40,15 @@ class Layout extends React.PureComponent {
|
||||
title,
|
||||
} = this.props
|
||||
|
||||
const noPaddingPages = ['group', 'messages']
|
||||
const hasPadding = noPaddingPages.indexOf(page) === -1
|
||||
const mainBlockClasses = CX({
|
||||
d: 1,
|
||||
w1015PX: 1,
|
||||
flexRow: 1,
|
||||
jcEnd: 1,
|
||||
py15: page !== 'group',
|
||||
pb15: page === 'group',
|
||||
py15: hasPadding,
|
||||
pb15: hasPadding,
|
||||
})
|
||||
|
||||
return (
|
||||
|
||||
96
app/javascript/gabsocial/layouts/messages_layout.js
Normal file
96
app/javascript/gabsocial/layouts/messages_layout.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { me } from '../initial_state'
|
||||
import {
|
||||
CX,
|
||||
BREAKPOINT_EXTRA_SMALL,
|
||||
} from '../constants'
|
||||
import Layout from './layout'
|
||||
import Responsive from '../features/ui/util/responsive_component'
|
||||
import ResponsiveClassesComponent from '../features/ui/util/responsive_classes_component'
|
||||
import MessagesSearch from '../features/messages/components/messages_search'
|
||||
import MessagesList from '../features/messages/components/messages_list'
|
||||
import MessagesHeader from '../features/messages/components/messages_header'
|
||||
|
||||
class MessagesLayout extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
showBackBtn,
|
||||
title,
|
||||
} = this.props
|
||||
|
||||
const mainBlockClasses = CX({
|
||||
d: 1,
|
||||
w1015PX: 1,
|
||||
h100PC: 1,
|
||||
flexRow: 1,
|
||||
jcEnd: 1,
|
||||
})
|
||||
|
||||
return (
|
||||
<Layout
|
||||
showBackBtn
|
||||
showGlobalFooter
|
||||
noRightSidebar
|
||||
showLinkFooterInSidebar
|
||||
page='messages'
|
||||
title='Chats'
|
||||
actions={[
|
||||
{
|
||||
icon: 'cog',
|
||||
onClick: this.onOpenCommunityPageSettingsModal,
|
||||
},
|
||||
{
|
||||
icon: 'pencil',
|
||||
onClick: this.onOpenCommunityPageSettingsModal,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<div className={[_s.d, _s.flexRow, _s.w100PC, _s.calcH53PX].join(' ')}>
|
||||
<ResponsiveClassesComponent
|
||||
classNames={[_s.d, _s.flexShrink1, _s.flexGrow1].join(' ')}
|
||||
classNamesSmall={[_s.d, _s.flexShrink1, _s.flexGrow1].join(' ')}
|
||||
classNamesXS={[_s.d, _s.w100PC].join(' ')}
|
||||
>
|
||||
<ResponsiveClassesComponent
|
||||
classNames={mainBlockClasses}
|
||||
classNamesXS={[_s.d, _s.w100PC, _s.jcEnd].join(' ')}
|
||||
>
|
||||
|
||||
<Responsive min={BREAKPOINT_EXTRA_SMALL}>
|
||||
<div className={[_s.d, _s.w340PX, _s.h100PC, _s.bgPrimary, _s.borderLeft1PX, _s.borderRight1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<div className={[_s.d, _s.w340PX].join(' ')}>
|
||||
|
||||
{ /* <MessagesHeader /> */ }
|
||||
<MessagesSearch />
|
||||
<MessagesList />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Responsive>
|
||||
|
||||
<div className={[_s.d, _s.flexGrow1, _s.h100PC, _s.bgPrimary, _s.borderColorSecondary, _s.borderRight1PX, _s.z1].join(' ')}>
|
||||
<div className={[_s.d, _s.w100PC, _s.h100PC].join(' ')}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</ResponsiveClassesComponent>
|
||||
</ResponsiveClassesComponent>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MessagesLayout.propTypes = {
|
||||
children: PropTypes.node,
|
||||
showBackBtn: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
}
|
||||
|
||||
export default MessagesLayout
|
||||
@@ -4,8 +4,12 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { BREAKPOINT_EXTRA_SMALL } from '../constants'
|
||||
import Sticky from 'react-stickynode'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { me } from '../initial_state'
|
||||
import { CX } from '../constants'
|
||||
import {
|
||||
CX,
|
||||
LAZY_LOAD_SCROLL_OFFSET,
|
||||
} from '../constants'
|
||||
import DefaultNavigationBar from '../components/navigation_bar/default_navigation_bar'
|
||||
import FooterBar from '../components/footer_bar'
|
||||
import ProfileHeader from '../components/profile_header'
|
||||
@@ -26,6 +30,37 @@ import {
|
||||
|
||||
class ProfileLayout extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
lazyLoaded: false,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.window = window
|
||||
this.documentElement = document.scrollingElement || document.documentElement
|
||||
|
||||
this.window.addEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.detachScrollListener()
|
||||
}
|
||||
|
||||
detachScrollListener = () => {
|
||||
this.window.removeEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
handleScroll = throttle(() => {
|
||||
if (this.window) {
|
||||
const { scrollTop } = this.documentElement
|
||||
|
||||
if (scrollTop > LAZY_LOAD_SCROLL_OFFSET && !this.state.lazyLoaded) {
|
||||
this.setState({ lazyLoaded: true })
|
||||
this.detachScrollListener()
|
||||
}
|
||||
}
|
||||
}, 150, { trailing: true })
|
||||
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
@@ -34,6 +69,7 @@ class ProfileLayout extends ImmutablePureComponent {
|
||||
unavailable,
|
||||
noSidebar,
|
||||
} = this.props
|
||||
const { lazyLoaded } = this.state
|
||||
|
||||
const mainContentClasses = CX({
|
||||
d: 1,
|
||||
@@ -121,7 +157,7 @@ class ProfileLayout extends ImmutablePureComponent {
|
||||
<div className={[_s.d, _s.w340PX].join(' ')}>
|
||||
<WrappedBundle component={ProfileStatsPanel} componentParams={{ account }} />
|
||||
<WrappedBundle component={ProfileInfoPanel} componentParams={{ account }} />
|
||||
{ !unavailable && <WrappedBundle component={MediaGalleryPanel} componentParams={{ account }} /> }
|
||||
{ !unavailable && <WrappedBundle component={MediaGalleryPanel} componentParams={{ account, isLazy: true, shouldLoad: lazyLoaded }} />}
|
||||
{ !me && <WrappedBundle component={SignUpPanel} /> }
|
||||
<WrappedBundle component={LinkFooter} />
|
||||
</div>
|
||||
|
||||
40
app/javascript/gabsocial/pages/compose_page.js
Normal file
40
app/javascript/gabsocial/pages/compose_page.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import PageTitle from '../features/ui/util/page_title'
|
||||
import DefaultLayout from '../layouts/default_layout'
|
||||
|
||||
class ComposePage extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
page,
|
||||
title,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<DefaultLayout
|
||||
noComposeButton
|
||||
showBackBtn
|
||||
title={title}
|
||||
page={page}
|
||||
actions={[
|
||||
{
|
||||
title: 'Post',
|
||||
onClick: this.onOpenCommunityPageSettingsModal,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<PageTitle path={title} />
|
||||
{children}
|
||||
</DefaultLayout>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ComposePage.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
}
|
||||
|
||||
export default ComposePage
|
||||
@@ -2,13 +2,17 @@ import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { openModal } from '../actions/modal'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { MODAL_HOME_TIMELINE_SETTINGS } from '../constants'
|
||||
import { openModal } from '../actions/modal'
|
||||
import {
|
||||
MODAL_HOME_TIMELINE_SETTINGS,
|
||||
LAZY_LOAD_SCROLL_OFFSET,
|
||||
} from '../constants'
|
||||
import { me } from '../initial_state'
|
||||
import PageTitle from '../features/ui/util/page_title'
|
||||
import DefaultLayout from '../layouts/default_layout'
|
||||
import TimelineComposeBlock from '../components/timeline_compose_block'
|
||||
import TabBar from '../components/tab_bar'
|
||||
import WrappedBundle from '../features/ui/util/wrapped_bundle'
|
||||
import {
|
||||
UserPanel,
|
||||
@@ -47,7 +51,7 @@ class HomePage extends React.PureComponent {
|
||||
if (this.window) {
|
||||
const { scrollTop } = this.documentElement
|
||||
|
||||
if (scrollTop > 25 && !this.state.lazyLoaded) {
|
||||
if (scrollTop > LAZY_LOAD_SCROLL_OFFSET && !this.state.lazyLoaded) {
|
||||
this.setState({ lazyLoaded: true })
|
||||
this.detachScrollListener()
|
||||
}
|
||||
@@ -98,11 +102,10 @@ class HomePage extends React.PureComponent {
|
||||
path={title}
|
||||
badge={totalQueuedItemsCount}
|
||||
/>
|
||||
|
||||
|
||||
<TimelineComposeBlock autoFocus={false} />
|
||||
|
||||
{children}
|
||||
|
||||
|
||||
</DefaultLayout>
|
||||
)
|
||||
}
|
||||
|
||||
38
app/javascript/gabsocial/pages/messages_page.js
Normal file
38
app/javascript/gabsocial/pages/messages_page.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import PageTitle from '../features/ui/util/page_title'
|
||||
import MessagesLayout from '../layouts/messages_layout'
|
||||
|
||||
class MessagesPage extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const { children, intl } = this.props
|
||||
|
||||
const title = intl.formatMessage(messages.chats)
|
||||
|
||||
return (
|
||||
<MessagesLayout
|
||||
showBackBtn
|
||||
title={title}
|
||||
>
|
||||
<PageTitle path={title} />
|
||||
{children}
|
||||
</MessagesLayout>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
chats: { id: 'chats', defaultMessage: 'Chats' },
|
||||
})
|
||||
|
||||
MessagesPage.propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
export default injectIntl(connect()(MessagesPage))
|
||||
@@ -15,7 +15,9 @@ import ProfileLayout from '../layouts/profile_layout'
|
||||
class ProfilePage extends ImmutablePureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchAccountByUsername(this.props.params.username))
|
||||
if (!this.props.account) {
|
||||
this.props.dispatch(fetchAccountByUsername(this.props.params.username))
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import {
|
||||
CONVERSATIONS_MOUNT,
|
||||
CONVERSATIONS_UNMOUNT,
|
||||
CONVERSATIONS_FETCH_REQUEST,
|
||||
CONVERSATIONS_FETCH_SUCCESS,
|
||||
CONVERSATIONS_FETCH_FAIL,
|
||||
CONVERSATIONS_UPDATE,
|
||||
CONVERSATIONS_READ,
|
||||
} from '../actions/conversations';
|
||||
import compareId from '../utils/compare_id';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isLoading: false,
|
||||
hasMore: true,
|
||||
mounted: false,
|
||||
});
|
||||
|
||||
const conversationToMap = item => ImmutableMap({
|
||||
id: item.id,
|
||||
unread: item.unread,
|
||||
accounts: ImmutableList(item.accounts.map(a => a.id)),
|
||||
last_status: item.last_status ? item.last_status.id : null,
|
||||
});
|
||||
|
||||
const updateConversation = (state, item) => state.update('items', list => {
|
||||
const index = list.findIndex(x => x.get('id') === item.id);
|
||||
const newItem = conversationToMap(item);
|
||||
|
||||
if (index === -1) {
|
||||
return list.unshift(newItem);
|
||||
} else {
|
||||
return list.set(index, newItem);
|
||||
}
|
||||
});
|
||||
|
||||
const expandNormalizedConversations = (state, conversations, next, isLoadingRecent) => {
|
||||
let items = ImmutableList(conversations.map(conversationToMap));
|
||||
|
||||
return state.withMutations(mutable => {
|
||||
if (!items.isEmpty()) {
|
||||
mutable.update('items', list => {
|
||||
list = list.map(oldItem => {
|
||||
const newItemIndex = items.findIndex(x => x.get('id') === oldItem.get('id'));
|
||||
|
||||
if (newItemIndex === -1) {
|
||||
return oldItem;
|
||||
}
|
||||
|
||||
const newItem = items.get(newItemIndex);
|
||||
items = items.delete(newItemIndex);
|
||||
|
||||
return newItem;
|
||||
});
|
||||
|
||||
list = list.concat(items);
|
||||
|
||||
return list.sortBy(x => x.get('last_status'), (a, b) => {
|
||||
if(a === null || b === null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return compareId(a, b) * -1;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!next && !isLoadingRecent) {
|
||||
mutable.set('hasMore', false);
|
||||
}
|
||||
|
||||
mutable.set('isLoading', false);
|
||||
});
|
||||
};
|
||||
|
||||
export default function conversations(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case CONVERSATIONS_FETCH_REQUEST:
|
||||
return state.set('isLoading', true);
|
||||
case CONVERSATIONS_FETCH_FAIL:
|
||||
return state.set('isLoading', false);
|
||||
case CONVERSATIONS_FETCH_SUCCESS:
|
||||
return expandNormalizedConversations(state, action.conversations, action.next, action.isLoadingRecent);
|
||||
case CONVERSATIONS_UPDATE:
|
||||
return updateConversation(state, action.conversation);
|
||||
case CONVERSATIONS_MOUNT:
|
||||
return state.update('mounted', count => count + 1);
|
||||
case CONVERSATIONS_UNMOUNT:
|
||||
return state.update('mounted', count => count - 1);
|
||||
case CONVERSATIONS_READ:
|
||||
return state.update('items', list => list.map(item => {
|
||||
if (item.get('id') === action.id) {
|
||||
return item.set('unread', false);
|
||||
}
|
||||
|
||||
return item;
|
||||
}));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
@@ -4,7 +4,6 @@ import accounts from './accounts'
|
||||
import accounts_counters from './accounts_counters'
|
||||
import compose from './compose'
|
||||
import contexts from './contexts'
|
||||
import conversations from './conversations'
|
||||
import custom_emojis from './custom_emojis'
|
||||
import filters from './filters'
|
||||
import groups from './groups'
|
||||
@@ -49,7 +48,6 @@ const reducers = {
|
||||
accounts_counters,
|
||||
compose,
|
||||
contexts,
|
||||
conversations,
|
||||
custom_emojis,
|
||||
filters,
|
||||
groups,
|
||||
|
||||
@@ -31,6 +31,7 @@ const initialState = ImmutableMap({
|
||||
top: false,
|
||||
unread: 0,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
queuedNotifications: ImmutableList(), //max = MAX_QUEUED_NOTIFICATIONS
|
||||
totalQueuedNotificationsCount: 0, //used for queuedItems overflow for MAX_QUEUED_NOTIFICATIONS+
|
||||
lastReadId: -1,
|
||||
@@ -271,7 +272,10 @@ export default function notifications(state = initialState, action) {
|
||||
case NOTIFICATIONS_EXPAND_REQUEST:
|
||||
return state.set('isLoading', true);
|
||||
case NOTIFICATIONS_EXPAND_FAIL:
|
||||
return state.set('isLoading', false);
|
||||
return state.withMutations(mutable => {
|
||||
mutable.set('isLoading', false)
|
||||
mutable.set('isError', true)
|
||||
})
|
||||
case NOTIFICATIONS_FILTER_SET:
|
||||
return state.withMutations(mutable => {
|
||||
mutable.set('items', ImmutableList()).set('hasMore', true)
|
||||
|
||||
@@ -9,8 +9,6 @@ import {
|
||||
ACCOUNT_UNBLOCK_SUCCESS,
|
||||
ACCOUNT_MUTE_SUCCESS,
|
||||
ACCOUNT_UNMUTE_SUCCESS,
|
||||
ACCOUNT_PIN_SUCCESS,
|
||||
ACCOUNT_UNPIN_SUCCESS,
|
||||
RELATIONSHIPS_FETCH_SUCCESS,
|
||||
} from '../actions/accounts';
|
||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||
@@ -43,8 +41,6 @@ export default function relationships(state = initialState, action) {
|
||||
case ACCOUNT_UNBLOCK_SUCCESS:
|
||||
case ACCOUNT_MUTE_SUCCESS:
|
||||
case ACCOUNT_UNMUTE_SUCCESS:
|
||||
case ACCOUNT_PIN_SUCCESS:
|
||||
case ACCOUNT_UNPIN_SUCCESS:
|
||||
return normalizeRelationship(state, action.relationship);
|
||||
case RELATIONSHIPS_FETCH_SUCCESS:
|
||||
return normalizeRelationships(state, action.relationships);
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'
|
||||
const initialState = ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isLoading: false,
|
||||
isFetched: false,
|
||||
isError: false,
|
||||
})
|
||||
|
||||
@@ -50,17 +51,20 @@ export default function shortcutsReducer(state = initialState, action) {
|
||||
case SHORTCUTS_FETCH_REQUEST:
|
||||
return state.withMutations((map) => {
|
||||
map.set('isLoading', true)
|
||||
map.set('isFetched', false)
|
||||
map.set('isError', false)
|
||||
})
|
||||
case SHORTCUTS_FETCH_SUCCESS:
|
||||
return state.withMutations((map) => {
|
||||
map.set('items', normalizeShortcuts(action.shortcuts))
|
||||
map.set('isLoading', false)
|
||||
map.set('isFetched', true)
|
||||
map.set('isError', false)
|
||||
})
|
||||
case SHORTCUTS_FETCH_FAIL:
|
||||
return state.withMutations((map) => {
|
||||
map.set('isLoading', false)
|
||||
map.set('isFetched', true)
|
||||
map.set('isError', true)
|
||||
})
|
||||
case SHORTCUTS_ADD_SUCCESS:
|
||||
|
||||
@@ -15,14 +15,6 @@ import {
|
||||
BOOKMARKED_STATUSES_EXPAND_FAIL,
|
||||
} from '../actions/bookmarks'
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import {
|
||||
FAVORITE_SUCCESS,
|
||||
UNFAVORITE_SUCCESS,
|
||||
PIN_SUCCESS,
|
||||
UNPIN_SUCCESS,
|
||||
BOOKMARK_SUCCESS,
|
||||
UNBOOKMARK_SUCCESS,
|
||||
} from '../actions/interactions';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
bookmarks: ImmutableMap({
|
||||
@@ -35,11 +27,6 @@ const initialState = ImmutableMap({
|
||||
loaded: false,
|
||||
items: ImmutableList(),
|
||||
}),
|
||||
pins: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableList(),
|
||||
}),
|
||||
});
|
||||
|
||||
const normalizeList = (state, listType, statuses, next) => {
|
||||
@@ -93,18 +80,6 @@ export default function statusLists(state = initialState, action) {
|
||||
return normalizeList(state, 'favorites', action.statuses, action.next);
|
||||
case FAVORITED_STATUSES_EXPAND_SUCCESS:
|
||||
return appendToList(state, 'favorites', action.statuses, action.next);
|
||||
case FAVORITE_SUCCESS:
|
||||
return prependOneToList(state, 'favorites', action.status);
|
||||
case UNFAVORITE_SUCCESS:
|
||||
return removeOneFromList(state, 'favorites', action.status);
|
||||
case PIN_SUCCESS:
|
||||
return prependOneToList(state, 'pins', action.status);
|
||||
case UNPIN_SUCCESS:
|
||||
return removeOneFromList(state, 'pins', action.status);
|
||||
case BOOKMARK_SUCCESS:
|
||||
return prependOneToList(state, 'bookmarks', action.status);
|
||||
case UNBOOKMARK_SUCCESS:
|
||||
return removeOneFromList(state, 'bookmarks', action.status);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import {
|
||||
UNFAVORITE_REQUEST,
|
||||
} from '../actions/interactions';
|
||||
import {
|
||||
STATUS_MUTE_SUCCESS,
|
||||
STATUS_UNMUTE_SUCCESS,
|
||||
STATUS_REVEAL,
|
||||
STATUS_HIDE,
|
||||
UPDATE_STATUS_STATS,
|
||||
} from '../actions/statuses';
|
||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||
import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer';
|
||||
@@ -46,10 +45,6 @@ export default function statuses(state = initialState, action) {
|
||||
return state.setIn([action.status.get('id'), 'reblogged'], true);
|
||||
case REPOST_FAIL:
|
||||
return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
|
||||
case STATUS_MUTE_SUCCESS:
|
||||
return state.setIn([action.id, 'muted'], true);
|
||||
case STATUS_UNMUTE_SUCCESS:
|
||||
return state.setIn([action.id, 'muted'], false);
|
||||
case STATUS_REVEAL:
|
||||
return state.withMutations(map => {
|
||||
action.ids.forEach(id => {
|
||||
@@ -68,6 +63,9 @@ export default function statuses(state = initialState, action) {
|
||||
});
|
||||
case TIMELINE_DELETE:
|
||||
return deleteStatus(state, action.id, action.references);
|
||||
case UPDATE_STATUS_STATS:
|
||||
// : todo :
|
||||
return state;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ const initialTimeline = ImmutableMap({
|
||||
online: false,
|
||||
top: true,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
hasMore: true,
|
||||
items: ImmutableList(),
|
||||
queuedItems: ImmutableList(), //max= MAX_QUEUED_ITEMS
|
||||
@@ -49,10 +50,15 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
|
||||
return newIds;
|
||||
}
|
||||
|
||||
// const realtime = ['home']
|
||||
// if no realtime, do all that, otherwise just concat
|
||||
// return oldIds.concat(newIds);
|
||||
|
||||
const lastIndex = oldIds.findLastIndex(id => id !== null && compareId(id, newIds.last()) >= 0) + 1;
|
||||
const firstIndex = oldIds.take(lastIndex).findLastIndex(id => id !== null && compareId(id, newIds.first()) > 0);
|
||||
|
||||
if (firstIndex < 0) {
|
||||
console.log("----2")
|
||||
return (isPartial ? newIds.unshift(null) : newIds).concat(oldIds.skip(lastIndex));
|
||||
}
|
||||
|
||||
@@ -162,7 +168,10 @@ export default function timelines(state = initialState, action) {
|
||||
case TIMELINE_EXPAND_REQUEST:
|
||||
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', true));
|
||||
case TIMELINE_EXPAND_FAIL:
|
||||
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
|
||||
return state.update(action.timeline, initialTimeline, map => map.withMutations(mMap => {
|
||||
map.set('isLoading', false)
|
||||
map.set('isError', true)
|
||||
}));
|
||||
case TIMELINE_EXPAND_SUCCESS:
|
||||
return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent);
|
||||
case TIMELINE_UPDATE:
|
||||
|
||||
@@ -78,6 +78,7 @@ export const makeGetStatus = () => {
|
||||
[
|
||||
(state) => state,
|
||||
(state, { id }) => state.getIn(['statuses', id]),
|
||||
(state, { id }) => state.getIn(['groups', state.getIn(['statuses', id, 'group'])]),
|
||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'quote_of_id'])]),
|
||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
|
||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
|
||||
@@ -87,7 +88,7 @@ export const makeGetStatus = () => {
|
||||
getFilters,
|
||||
],
|
||||
|
||||
(state, statusBase, quotedStatus, statusRepost, accountBase, accountQuoted, accountRepost, username, filters) => {
|
||||
(state, statusBase, group, quotedStatus, statusRepost, accountBase, accountQuoted, accountRepost, username, filters) => {
|
||||
if (!statusBase) {
|
||||
return null
|
||||
}
|
||||
@@ -122,16 +123,20 @@ export const makeGetStatus = () => {
|
||||
quotedStatus = quotedStatus.set('account', accountQuoted);
|
||||
}
|
||||
|
||||
|
||||
console.log("group:", group)
|
||||
|
||||
//Find ancestor status
|
||||
|
||||
const regex = (accountRepost || accountBase).get('id') !== me && regexFromFilters(filters);
|
||||
const filtered = regex && regex.test(statusBase.get('reblog') ? statusRepost.get('search_index') : statusBase.get('search_index'));
|
||||
|
||||
return statusBase.withMutations(map => {
|
||||
return statusBase.withMutations((map) => {
|
||||
map.set('quoted_status', quotedStatus);
|
||||
map.set('reblog', statusRepost);
|
||||
map.set('account', accountBase);
|
||||
map.set('filtered', filtered);
|
||||
map.set('group', group);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -50,13 +50,11 @@ self.addEventListener('fetch', function(event) {
|
||||
url.pathname.startsWith('/about') ||
|
||||
url.pathname.startsWith('/auth') ||
|
||||
url.pathname.startsWith('/oauth') ||
|
||||
url.pathname.startsWith('/invites') ||
|
||||
url.pathname.startsWith('/pghero') ||
|
||||
url.pathname.startsWith('/sidekiq') ||
|
||||
url.pathname.startsWith('/filters') ||
|
||||
url.pathname.startsWith('/tags') ||
|
||||
url.pathname.startsWith('/emojis') ||
|
||||
url.pathname.startsWith('/inbox') ||
|
||||
url.pathname.startsWith('/accounts') ||
|
||||
url.pathname.startsWith('/user') ||
|
||||
url.pathname.startsWith('/users') ||
|
||||
@@ -64,8 +62,7 @@ self.addEventListener('fetch', function(event) {
|
||||
url.pathname.startsWith('/public') ||
|
||||
url.pathname.startsWith('/avatars') ||
|
||||
url.pathname.startsWith('/authorize_follow') ||
|
||||
url.pathname.startsWith('/media_proxy') ||
|
||||
url.pathname.startsWith('/relationships')) {
|
||||
url.pathname.startsWith('/media_proxy')) {
|
||||
//non-webapp routes
|
||||
} else if (url.pathname.startsWith('/')) {
|
||||
// : TODO : if is /web
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { configure } from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
const adapter = new Adapter();
|
||||
configure({ adapter });
|
||||
@@ -1,10 +0,0 @@
|
||||
import * as base64 from '../base64';
|
||||
|
||||
describe('base64', () => {
|
||||
describe('decode', () => {
|
||||
it('returns a uint8 array', () => {
|
||||
const arr = base64.decode('dGVzdA==');
|
||||
expect(arr).toEqual(new Uint8Array([116, 101, 115, 116]));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import * as html from '../html';
|
||||
|
||||
describe('html', () => {
|
||||
describe('unsecapeHTML', () => {
|
||||
it('returns unescaped HTML', () => {
|
||||
const output = html.unescapeHTML('<p>lorem</p><p>ipsum</p><br><br>');
|
||||
expect(output).toEqual('lorem\n\nipsum\n<br>');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user