From 9e6bb5264a3b9194452c17cf5790e368c5f11efb Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 23 Jun 2022 09:26:13 -0400 Subject: [PATCH] Handle error state for carousels --- .../features/feed-filtering/feed-carousel.tsx | 12 ++++++++++++ app/soapbox/locales/en.json | 1 + app/soapbox/reducers/__tests__/carousels.test.ts | 6 +++++- app/soapbox/reducers/carousels.ts | 6 ++++-- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/soapbox/features/feed-filtering/feed-carousel.tsx b/app/soapbox/features/feed-filtering/feed-carousel.tsx index dfd9ba2ea..ca3904900 100644 --- a/app/soapbox/features/feed-filtering/feed-carousel.tsx +++ b/app/soapbox/features/feed-filtering/feed-carousel.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; import React, { useEffect, useState } from 'react'; +import { FormattedMessage } from 'react-intl'; import { fetchCarouselAvatars } from 'soapbox/actions/carousels'; import { replaceHomeTimeline } from 'soapbox/actions/timelines'; @@ -57,6 +58,7 @@ const FeedCarousel = () => { const avatars = useAppSelector((state) => state.carousels.avatars); const isLoading = useAppSelector((state) => state.carousels.isLoading); + const hasError = useAppSelector((state) => state.carousels.error); const numberOfPages = Math.floor(avatars.length / pageSize); const hasNextPage = currentPage < numberOfPages && numberOfPages > 1; @@ -81,6 +83,16 @@ const FeedCarousel = () => { return null; } + if (hasError) { + return ( + + + + + + ); + } + return (
diff --git a/app/soapbox/locales/en.json b/app/soapbox/locales/en.json index 3e740d32c..9a1af5b43 100644 --- a/app/soapbox/locales/en.json +++ b/app/soapbox/locales/en.json @@ -258,6 +258,7 @@ "column_forbidden.title": "Forbidden", "column_header.show_settings": "Show settings", "common.cancel": "Cancel", + "common.error": "Something isn't right. Try reloading the page.", "community.column_settings.media_only": "Media Only", "community.column_settings.title": "Local timeline settings", "compose.character_counter.title": "Used {chars} out of {maxChars} characters", diff --git a/app/soapbox/reducers/__tests__/carousels.test.ts b/app/soapbox/reducers/__tests__/carousels.test.ts index 394a2c037..40b8f928a 100644 --- a/app/soapbox/reducers/__tests__/carousels.test.ts +++ b/app/soapbox/reducers/__tests__/carousels.test.ts @@ -32,6 +32,7 @@ describe('carousels reducer', () => { expect(result.isLoading).toEqual(false); expect(result.avatars).toEqual([45]); + expect(result.error).toEqual(false); }); }); @@ -39,7 +40,10 @@ describe('carousels reducer', () => { it('sets "isLoading" to "true"', () => { const initialState = { isLoading: true, avatars: [] }; const action = { type: CAROUSEL_AVATAR_FAIL }; - expect(reducer(initialState, action).isLoading).toEqual(false); + const result = reducer(initialState, action); + + expect(result.isLoading).toEqual(false); + expect(result.error).toEqual(true); }); }); }); diff --git a/app/soapbox/reducers/carousels.ts b/app/soapbox/reducers/carousels.ts index 47a6c7576..091c47238 100644 --- a/app/soapbox/reducers/carousels.ts +++ b/app/soapbox/reducers/carousels.ts @@ -13,13 +13,15 @@ type Avatar = { } type CarouselsState = { - avatars: Avatar[], + avatars: Avatar[] isLoading: boolean + error: boolean } const initialState: CarouselsState = { avatars: [], isLoading: false, + error: false, }; export default function rules(state: CarouselsState = initialState, action: AnyAction): CarouselsState { @@ -29,7 +31,7 @@ export default function rules(state: CarouselsState = initialState, action: AnyA case CAROUSEL_AVATAR_SUCCESS: return { ...state, isLoading: false, avatars: action.payload }; case CAROUSEL_AVATAR_FAIL: - return { ...state, isLoading: false }; + return { ...state, isLoading: false, error: true }; default: return state; }