From 6b2eefc7bf8cf1bb58da165d9594d9b17bf97e11 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 21:13:17 +0100 Subject: [Glitch] Add WebP support Port 5092d17f2936146fa26e5d8a9b9e391f77010f28 to glitch-soc --- app/javascript/flavours/glitch/util/resize_image.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/util/resize_image.js b/app/javascript/flavours/glitch/util/resize_image.js index d1608094f..bbdbc865e 100644 --- a/app/javascript/flavours/glitch/util/resize_image.js +++ b/app/javascript/flavours/glitch/util/resize_image.js @@ -31,7 +31,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => { }); const getOrientation = (img, type = 'image/png') => new Promise(resolve => { - if (type !== 'image/jpeg') { + if (!['image/jpeg', 'image/webp'].includes(type)) { resolve(1); return; } -- cgit From a963ea67dda17f69ed783b3fbcc91e5ce3858ad3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 21:28:29 +0100 Subject: [Glitch] Add missing rejection handling for Promises Port missing parts from 2c51bc0ca5a4c3a4bb140b4b40dabdda859ebb94 to glitch-soc --- app/javascript/flavours/glitch/actions/alerts.js | 25 ++++++++++++++++++++++ app/javascript/flavours/glitch/actions/compose.js | 7 +++++- app/javascript/flavours/glitch/actions/lists.js | 4 +++- .../actions/push_notifications/registerer.js | 15 ++++++------- app/javascript/flavours/glitch/actions/settings.js | 5 ++++- .../flavours/glitch/containers/status_container.js | 6 +++++- .../glitch/features/ui/components/embed_modal.js | 3 +++ .../flavours/glitch/middleware/errors.js | 18 ++-------------- 8 files changed, 54 insertions(+), 29 deletions(-) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/actions/alerts.js b/app/javascript/flavours/glitch/actions/alerts.js index f37fdeeb6..3f5d7ef46 100644 --- a/app/javascript/flavours/glitch/actions/alerts.js +++ b/app/javascript/flavours/glitch/actions/alerts.js @@ -1,3 +1,10 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' }, + unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' }, +}); + export const ALERT_SHOW = 'ALERT_SHOW'; export const ALERT_DISMISS = 'ALERT_DISMISS'; export const ALERT_CLEAR = 'ALERT_CLEAR'; @@ -22,3 +29,21 @@ export function showAlert(title, message) { message, }; }; + +export function showAlertForError(error) { + if (error.response) { + const { data, status, statusText } = error.response; + + let message = statusText; + let title = `${status}`; + + if (data.error) { + message = data.error; + } + + return showAlert(title, message); + } else { + console.error(error); + return showAlert(messages.unexpectedTitle, messages.unexpectedMessage); + } +} diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 04e857713..204d609b0 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -1,5 +1,5 @@ import api from 'flavours/glitch/util/api'; -import { CancelToken } from 'axios'; +import { CancelToken, isCancel } from 'axios'; import { throttle } from 'lodash'; import { search as emojiSearch } from 'flavours/glitch/util/emoji/emoji_mart_search_light'; import { useEmoji } from './emojis'; @@ -8,6 +8,7 @@ import { recoverHashtags } from 'flavours/glitch/util/hashtag'; import resizeImage from 'flavours/glitch/util/resize_image'; import { updateTimeline } from './timelines'; +import { showAlertForError } from './alerts'; let cancelFetchComposeSuggestionsAccounts; @@ -320,6 +321,10 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => }, }).then(response => { dispatch(readyComposeSuggestionsAccounts(token, response.data)); + }).catch(error => { + if (!isCancel(error)) { + dispatch(showAlertForError(error)); + } }); }, 200, { leading: true, trailing: true }); diff --git a/app/javascript/flavours/glitch/actions/lists.js b/app/javascript/flavours/glitch/actions/lists.js index 7d94ee950..f29ca1e01 100644 --- a/app/javascript/flavours/glitch/actions/lists.js +++ b/app/javascript/flavours/glitch/actions/lists.js @@ -1,4 +1,5 @@ import api from 'flavours/glitch/util/api'; +import { showAlertForError } from './alerts'; export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST'; export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS'; @@ -239,7 +240,8 @@ export const fetchListSuggestions = q => (dispatch, getState) => { }; api(getState).get('/api/v1/accounts/search', { params }) - .then(({ data }) => dispatch(fetchListSuggestionsReady(q, data))); + .then(({ data }) => dispatch(fetchListSuggestionsReady(q, data))) + .catch(error => dispatch(showAlertForError(error))); }; export const fetchListSuggestionsReady = (query, accounts) => ({ diff --git a/app/javascript/flavours/glitch/actions/push_notifications/registerer.js b/app/javascript/flavours/glitch/actions/push_notifications/registerer.js index 91f442415..8fdb239f7 100644 --- a/app/javascript/flavours/glitch/actions/push_notifications/registerer.js +++ b/app/javascript/flavours/glitch/actions/push_notifications/registerer.js @@ -109,14 +109,11 @@ export function register () { pushNotificationsSetting.remove(me); } - try { - getRegistration() - .then(getPushSubscription) - .then(unsubscribe); - } catch (e) { - - } - }); + return getRegistration() + .then(getPushSubscription) + .then(unsubscribe); + }) + .catch(console.warn); } else { console.warn('Your browser does not support Web Push Notifications.'); } @@ -137,6 +134,6 @@ export function saveSettings() { if (me) { pushNotificationsSetting.set(me, data); } - }); + }).catch(console.warn); }; } diff --git a/app/javascript/flavours/glitch/actions/settings.js b/app/javascript/flavours/glitch/actions/settings.js index 87b2ae76d..fb0bcc09c 100644 --- a/app/javascript/flavours/glitch/actions/settings.js +++ b/app/javascript/flavours/glitch/actions/settings.js @@ -1,5 +1,6 @@ import api from 'flavours/glitch/util/api'; import { debounce } from 'lodash'; +import { showAlertForError } from './alerts'; export const SETTING_CHANGE = 'SETTING_CHANGE'; export const SETTING_SAVE = 'SETTING_SAVE'; @@ -23,7 +24,9 @@ const debouncedSave = debounce((dispatch, getState) => { const data = getState().get('settings').filter((_, path) => path !== 'saved').toJS(); - api(getState).put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE })); + api(getState).put('/api/web/settings', { data }) + .then(() => dispatch({ type: SETTING_SAVE })) + .catch(error => dispatch(showAlertForError(error))); }, 5000, { trailing: true }); export function saveSettings() { diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index f28dce609..f783878b0 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -25,6 +25,7 @@ import { openModal } from 'flavours/glitch/actions/modal'; import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/util/initial_state'; +import { showAlertForError } from '../actions/alerts'; const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, @@ -134,7 +135,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, onEmbed (status) { - dispatch(openModal('EMBED', { url: status.get('url') })); + dispatch(openModal('EMBED', { + url: status.get('url'), + onError: error => dispatch(showAlertForError(error)), + })); }, onDelete (status, history, withRedraft = false) { diff --git a/app/javascript/flavours/glitch/features/ui/components/embed_modal.js b/app/javascript/flavours/glitch/features/ui/components/embed_modal.js index bf29b0da5..b1643df1c 100644 --- a/app/javascript/flavours/glitch/features/ui/components/embed_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/embed_modal.js @@ -10,6 +10,7 @@ export default class EmbedModal extends ImmutablePureComponent { static propTypes = { url: PropTypes.string.isRequired, onClose: PropTypes.func.isRequired, + onError: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, } @@ -35,6 +36,8 @@ export default class EmbedModal extends ImmutablePureComponent { iframeDocument.body.style.margin = 0; this.iframe.width = iframeDocument.body.scrollWidth; this.iframe.height = iframeDocument.body.scrollHeight; + }).catch(error => { + this.props.onError(error); }); } diff --git a/app/javascript/flavours/glitch/middleware/errors.js b/app/javascript/flavours/glitch/middleware/errors.js index f3dfc8b06..212c1f4ad 100644 --- a/app/javascript/flavours/glitch/middleware/errors.js +++ b/app/javascript/flavours/glitch/middleware/errors.js @@ -1,4 +1,4 @@ -import { showAlert } from 'flavours/glitch/actions/alerts'; +import { showAlertForError } from 'flavours/glitch/actions/alerts'; const defaultFailSuffix = 'FAIL'; @@ -8,21 +8,7 @@ export default function errorsMiddleware() { const isFail = new RegExp(`${defaultFailSuffix}$`, 'g'); if (action.type.match(isFail)) { - if (action.error.response) { - const { data, status, statusText } = action.error.response; - - let message = statusText; - let title = `${status}`; - - if (data.error) { - message = data.error; - } - - dispatch(showAlert(title, message)); - } else { - console.error(action.error); - dispatch(showAlert('Oops!', 'An unexpected error occurred.')); - } + dispatch(showAlertForError(action.error)); } } -- cgit From 7ed2aeb6e9b0fe4fc7fbe7c76003d1e044c682eb Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 21:35:04 +0100 Subject: [Glitch] Allow multiple files upload through web UI, including drag & drop Port 750c67660de753065ec160b4e389ba0dda2f81cc to glitch-soc --- app/javascript/flavours/glitch/actions/alerts.js | 4 +-- app/javascript/flavours/glitch/actions/compose.js | 38 ++++++++++++++++------ .../glitch/features/composer/options/index.js | 1 + .../flavours/glitch/features/ui/index.js | 2 +- 4 files changed, 32 insertions(+), 13 deletions(-) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/actions/alerts.js b/app/javascript/flavours/glitch/actions/alerts.js index 3f5d7ef46..50cd48a9e 100644 --- a/app/javascript/flavours/glitch/actions/alerts.js +++ b/app/javascript/flavours/glitch/actions/alerts.js @@ -22,7 +22,7 @@ export function clearAlert() { }; }; -export function showAlert(title, message) { +export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage) { return { type: ALERT_SHOW, title, @@ -44,6 +44,6 @@ export function showAlertForError(error) { return showAlert(title, message); } else { console.error(error); - return showAlert(messages.unexpectedTitle, messages.unexpectedMessage); + return showAlert(); } } diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 204d609b0..0dd1766bc 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -9,6 +9,8 @@ import resizeImage from 'flavours/glitch/util/resize_image'; import { updateTimeline } from './timelines'; import { showAlertForError } from './alerts'; +import { showAlert } from './alerts'; +import { defineMessages } from 'react-intl'; let cancelFetchComposeSuggestionsAccounts; @@ -53,6 +55,10 @@ export const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL'; export const COMPOSE_DOODLE_SET = 'COMPOSE_DOODLE_SET'; +const messages = defineMessages({ + uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' }, +}); + export function changeCompose(text) { return { type: COMPOSE_CHANGE, @@ -208,20 +214,32 @@ export function doodleSet(options) { export function uploadCompose(files) { return function (dispatch, getState) { - if (getState().getIn(['compose', 'media_attachments']).size > 3) { + const uploadLimit = 4; + const media = getState().getIn(['compose', 'media_attachments']); + const total = Array.from(files).reduce((a, v) => a + v.size, 0); + const progress = new Array(files.length).fill(0); + + if (files.length + media.size > uploadLimit) { + dispatch(showAlert(undefined, messages.uploadErrorLimit)); return; } - dispatch(uploadComposeRequest()); - resizeImage(files[0]).then(file => { - const data = new FormData(); - data.append('file', file); - - return api(getState).post('/api/v1/media', data, { - onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)), - }).then(({ data }) => dispatch(uploadComposeSuccess(data))); - }).catch(error => dispatch(uploadComposeFail(error))); + for (const [i, f] of Array.from(files).entries()) { + if (media.size + i > 3) break; + + resizeImage(f).then(file => { + const data = new FormData(); + data.append('file', file); + + return api(getState).post('/api/v1/media', data, { + onUploadProgress: function({ loaded }){ + progress[i] = loaded; + dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total)); + }, + }).then(({ data }) => dispatch(uploadComposeSuccess(data))); + }).catch(error => dispatch(uploadComposeFail(error))); + }; }; }; diff --git a/app/javascript/flavours/glitch/features/composer/options/index.js b/app/javascript/flavours/glitch/features/composer/options/index.js index 9fe3abc03..5b4a7444c 100644 --- a/app/javascript/flavours/glitch/features/composer/options/index.js +++ b/app/javascript/flavours/glitch/features/composer/options/index.js @@ -214,6 +214,7 @@ export default class ComposerOptions extends React.PureComponent { onChange={handleChangeFiles} ref={handleRefFileElement} type='file' + multiple {...hiddenComponent} /> = 1) { this.props.dispatch(uploadCompose(e.dataTransfer.files)); } } -- cgit From b7fbcb21b3ca7f7ee560785fa1249bf689fbaff3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 21:50:42 +0100 Subject: [Glitch] Add featured hashtags to profiles Port SCSS changes from 364f2ff9aa2b4bf601d68a12bce758aeb5530467 --- app/javascript/flavours/glitch/styles/accounts.scss | 4 ++++ app/javascript/flavours/glitch/styles/admin.scss | 7 ++++++- app/javascript/flavours/glitch/styles/widgets.scss | 7 +++++-- 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/styles/accounts.scss b/app/javascript/flavours/glitch/styles/accounts.scss index 9c6518bea..d2ae83b2e 100644 --- a/app/javascript/flavours/glitch/styles/accounts.scss +++ b/app/javascript/flavours/glitch/styles/accounts.scss @@ -290,3 +290,7 @@ border-bottom: 0; } } + +.directory__tag .trends__item__current { + width: auto; +} diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 4e969601b..4dbbaa1e8 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -153,10 +153,15 @@ $content-width: 840px; font-weight: 500; } - .directory__tag a { + .directory__tag > a, + .directory__tag > div { box-shadow: none; } + .directory__tag .table-action-link .fa { + color: inherit; + } + .directory__tag h4 { font-size: 18px; font-weight: 700; diff --git a/app/javascript/flavours/glitch/styles/widgets.scss b/app/javascript/flavours/glitch/styles/widgets.scss index c97337e4e..1eaf30c5b 100644 --- a/app/javascript/flavours/glitch/styles/widgets.scss +++ b/app/javascript/flavours/glitch/styles/widgets.scss @@ -269,7 +269,8 @@ box-sizing: border-box; margin-bottom: 10px; - a { + & > a, + & > div { display: flex; align-items: center; justify-content: space-between; @@ -279,7 +280,9 @@ text-decoration: none; color: inherit; box-shadow: 0 0 15px rgba($base-shadow-color, 0.2); + } + & > a { &:hover, &:active, &:focus { @@ -287,7 +290,7 @@ } } - &.active a { + &.active > a { background: $ui-highlight-color; cursor: default; } -- cgit From 14a1bb703a98282349cc95ac9a561c795c6881a0 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 21:54:43 +0100 Subject: [Glitch] Fix not showing custom emojis in share page emoji picker Port e02a13f64e5c2c93fa73a67a4ce32a7d1df24760 to glitch-soc --- app/javascript/flavours/glitch/containers/compose_container.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/containers/compose_container.js b/app/javascript/flavours/glitch/containers/compose_container.js index 60f6a9c9f..74c411b7c 100644 --- a/app/javascript/flavours/glitch/containers/compose_container.js +++ b/app/javascript/flavours/glitch/containers/compose_container.js @@ -7,6 +7,7 @@ import { IntlProvider, addLocaleData } from 'react-intl'; import { getLocale } from 'mastodon/locales'; import Compose from 'flavours/glitch/features/standalone/compose'; import initialState from 'flavours/glitch/util/initial_state'; +import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis'; const { localeData, messages } = getLocale(); addLocaleData(localeData); @@ -17,6 +18,8 @@ if (initialState) { store.dispatch(hydrateStore(initialState)); } +store.dispatch(fetchCustomEmojis()); + export default class TimelineContainer extends React.PureComponent { static propTypes = { -- cgit From b47a53f90299a1fb52423aacbc0c23427e2eb132 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 10 Feb 2019 22:19:26 +0100 Subject: [Glitch] Rename from instance to server. Port 46e806cd2f14a5e45d66b4c23040855202818984 to glitch-soc --- app/javascript/flavours/glitch/features/getting_started/index.js | 2 +- app/javascript/flavours/glitch/features/public_timeline/index.js | 2 +- app/javascript/flavours/glitch/features/ui/components/report_modal.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours') diff --git a/app/javascript/flavours/glitch/features/getting_started/index.js b/app/javascript/flavours/glitch/features/getting_started/index.js index fe0dd506e..7b645c9d0 100644 --- a/app/javascript/flavours/glitch/features/getting_started/index.js +++ b/app/javascript/flavours/glitch/features/getting_started/index.js @@ -166,7 +166,7 @@ export default class GettingStarted extends ImmutablePureComponent {
    {invitesEnabled &&
  • ·
  • } -
  • ·
  • +
  • ·
  • ·
  • ·
  • diff --git a/app/javascript/flavours/glitch/features/public_timeline/index.js b/app/javascript/flavours/glitch/features/public_timeline/index.js index 477d3b8c7..7fe472202 100644 --- a/app/javascript/flavours/glitch/features/public_timeline/index.js +++ b/app/javascript/flavours/glitch/features/public_timeline/index.js @@ -127,7 +127,7 @@ export default class PublicTimeline extends React.PureComponent { onLoadMore={this.handleLoadMore} trackScroll={!pinned} scrollKey={`public_timeline-${columnId}`} - emptyMessage={} + emptyMessage={} /> ); diff --git a/app/javascript/flavours/glitch/features/ui/components/report_modal.js b/app/javascript/flavours/glitch/features/ui/components/report_modal.js index a139394ac..8be1d5856 100644 --- a/app/javascript/flavours/glitch/features/ui/components/report_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/report_modal.js @@ -97,7 +97,7 @@ export default class ReportModal extends ImmutablePureComponent {
    -

    +