Implement load transitions and fix resetting filters (#365)
This PR implements: * Fade-in transitions when cells load in, making navigation and loading appear less janky. * When scrolling, skeleton reps show up before the actual ones load in. * Resetting filters will also reset any set inclusions or exclusions
This commit is contained in:
parent
6dd2579e6e
commit
2d1af335c3
15 changed files with 371 additions and 69 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import TableField from '~components/common/TableField'
|
||||
import MentionTypeahead from '../MentionTypeahead'
|
||||
import Typeahead from 'react-bootstrap-typeahead/types/core/Typeahead'
|
||||
|
||||
interface Props
|
||||
extends React.DetailedHTMLProps<
|
||||
|
|
@ -11,6 +12,7 @@ interface Props
|
|||
placeholder?: string
|
||||
inclusions: MentionItem[]
|
||||
exclusions: MentionItem[]
|
||||
typeaheadRef: React.Ref<Typeahead>
|
||||
onUpdate: (content: MentionItem[]) => void
|
||||
}
|
||||
|
||||
|
|
@ -20,6 +22,7 @@ const MentionTableField = ({
|
|||
placeholder,
|
||||
inclusions,
|
||||
exclusions,
|
||||
typeaheadRef,
|
||||
...props
|
||||
}: Props) => {
|
||||
return (
|
||||
|
|
@ -31,6 +34,7 @@ const MentionTableField = ({
|
|||
label={label}
|
||||
>
|
||||
<MentionTypeahead
|
||||
ref={typeaheadRef}
|
||||
label={label}
|
||||
description={description}
|
||||
placeholder={placeholder}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react'
|
||||
import { useState } from 'react'
|
||||
import { getCookie } from 'cookies-next'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
|
@ -14,6 +15,7 @@ import {
|
|||
RenderMenuProps,
|
||||
Token,
|
||||
} from 'react-bootstrap-typeahead'
|
||||
import Typeahead from 'react-bootstrap-typeahead/types/core/Typeahead'
|
||||
|
||||
import api from '~utils/api'
|
||||
import { numberToElement } from '~utils/elements'
|
||||
|
|
@ -41,14 +43,10 @@ interface RawSearchResponse {
|
|||
element: number
|
||||
}
|
||||
|
||||
const MentionTypeahead = ({
|
||||
label,
|
||||
description,
|
||||
placeholder,
|
||||
inclusions,
|
||||
exclusions,
|
||||
...props
|
||||
}: Props) => {
|
||||
const MentionTypeahead = React.forwardRef<Typeahead, Props>(function Typeahead(
|
||||
{ label, description, placeholder, inclusions, exclusions, ...props }: Props,
|
||||
forwardedRef
|
||||
) {
|
||||
const { t } = useTranslation('common')
|
||||
const locale = getCookie('NEXT_LOCALE')
|
||||
? (getCookie('NEXT_LOCALE') as string)
|
||||
|
|
@ -159,6 +157,7 @@ const MentionTypeahead = ({
|
|||
return (
|
||||
<AsyncTypeahead
|
||||
multiple
|
||||
ref={forwardedRef}
|
||||
className={styles.typeahead}
|
||||
id={label}
|
||||
align="left"
|
||||
|
|
@ -166,7 +165,6 @@ const MentionTypeahead = ({
|
|||
labelKey={(option) => (option as MentionItem).name[locale]}
|
||||
defaultSelected={inclusions}
|
||||
filterBy={() => true}
|
||||
minLength={3}
|
||||
onSearch={handleSearch}
|
||||
options={options}
|
||||
useCache={false}
|
||||
|
|
@ -181,6 +179,6 @@ const MentionTypeahead = ({
|
|||
onChange={(selected) => props.onUpdate(selected as MentionItem[])}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default MentionTypeahead
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { getCookie, setCookie } from 'cookies-next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
|
@ -10,16 +10,16 @@ import DialogContent from '~components/common/DialogContent'
|
|||
|
||||
import Button from '~components/common/Button'
|
||||
import InputTableField from '~components/common/InputTableField'
|
||||
import MentionTableField from '~components/common/MentionTableField'
|
||||
import SelectTableField from '~components/common/SelectTableField'
|
||||
import SliderTableField from '~components/common/SliderTableField'
|
||||
import SwitchTableField from '~components/common/SwitchTableField'
|
||||
import SelectItem from '~components/common/SelectItem'
|
||||
|
||||
import type { DialogProps } from '@radix-ui/react-dialog'
|
||||
import Typeahead from 'react-bootstrap-typeahead/types/core/Typeahead'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
import MentionTableField from '~components/common/MentionTableField'
|
||||
import classNames from 'classnames'
|
||||
|
||||
interface Props extends DialogProps {
|
||||
defaultFilterSet: FilterSet
|
||||
|
|
@ -43,6 +43,8 @@ const FilterModal = (props: Props) => {
|
|||
// Refs
|
||||
const headerRef = React.createRef<HTMLDivElement>()
|
||||
const footerRef = React.createRef<HTMLDivElement>()
|
||||
const inclusionRef = useRef<Typeahead>(null)
|
||||
const exclusionRef = useRef<Typeahead>(null)
|
||||
|
||||
// States
|
||||
const [open, setOpen] = useState(false)
|
||||
|
|
@ -88,7 +90,6 @@ const FilterModal = (props: Props) => {
|
|||
useEffect(() => {
|
||||
if (props.open !== undefined) {
|
||||
setOpen(props.open)
|
||||
|
||||
// When should we reset the filter state?
|
||||
}
|
||||
})
|
||||
|
|
@ -160,6 +161,12 @@ const FilterModal = (props: Props) => {
|
|||
setUserQuality(props.defaultFilterSet.user_quality)
|
||||
setNameQuality(props.defaultFilterSet.name_quality)
|
||||
setOriginalOnly(props.defaultFilterSet.original)
|
||||
|
||||
setInclusions([])
|
||||
inclusionRef.current?.clear()
|
||||
|
||||
setExclusions([])
|
||||
exclusionRef.current?.clear()
|
||||
}
|
||||
|
||||
function openChange() {
|
||||
|
|
@ -413,6 +420,7 @@ const FilterModal = (props: Props) => {
|
|||
exclusions={exclusions}
|
||||
placeholder={t('modals.filters.placeholders.inclusion')}
|
||||
label={t('modals.filters.labels.inclusion')}
|
||||
typeaheadRef={inclusionRef}
|
||||
onUpdate={storeInclusions}
|
||||
/>
|
||||
)
|
||||
|
|
@ -424,6 +432,7 @@ const FilterModal = (props: Props) => {
|
|||
exclusions={inclusions}
|
||||
placeholder={t('modals.filters.placeholders.exclusion')}
|
||||
label={t('modals.filters.labels.exclusion')}
|
||||
typeaheadRef={exclusionRef}
|
||||
onUpdate={storeExclusions}
|
||||
/>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import DOMPurify from 'dompurify'
|
|||
import Button from '~components/common/Button'
|
||||
import SegmentedControl from '~components/common/SegmentedControl'
|
||||
import Segment from '~components/common/Segment'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/reps/GridRepCollection'
|
||||
import GridRep from '~components/reps/GridRep'
|
||||
import RemixTeamAlert from '~components/dialogs/RemixTeamAlert'
|
||||
import RemixedToast from '~components/toasts/RemixedToast'
|
||||
import EditPartyModal from '../EditPartyModal'
|
||||
|
|
|
|||
|
|
@ -9,6 +9,16 @@
|
|||
padding: $unit-2x;
|
||||
min-width: 320px;
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--grid-rep-hover);
|
||||
|
|
@ -40,10 +40,16 @@ const GridRep = (props: Props) => {
|
|||
const locale =
|
||||
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [mainhand, setMainhand] = useState<Weapon>()
|
||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
||||
const [grid, setGrid] = useState<GridArray<GridWeapon>>({})
|
||||
|
||||
const gridRepStyles = classNames({
|
||||
[styles.gridRep]: true,
|
||||
[styles.visible]: visible,
|
||||
[styles.hidden]: !visible,
|
||||
})
|
||||
const titleClass = classNames({
|
||||
empty: !props.name,
|
||||
})
|
||||
|
|
@ -68,6 +74,14 @@ const GridRep = (props: Props) => {
|
|||
[styles.grid]: true,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setVisible(false) // Trigger fade out
|
||||
const timeout = setTimeout(() => {
|
||||
setVisible(true) // Trigger fade in
|
||||
}, 300) // You can adjust the timing based on your preference
|
||||
return () => clearTimeout(timeout)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const newWeapons = Array(numWeapons)
|
||||
const gridWeapons = Array(numWeapons)
|
||||
|
|
@ -249,7 +263,7 @@ const GridRep = (props: Props) => {
|
|||
|
||||
return (
|
||||
<Link legacyBehavior href={`/p/${props.shortcode}`}>
|
||||
<a className={styles.gridRep}>
|
||||
<a className={gridRepStyles}>
|
||||
{detailsWithUsername}
|
||||
<div className={styles.weaponGrid}>
|
||||
<div className={mainhandClasses}>{generateMainhandImage()}</div>
|
||||
150
components/reps/LoadingRep/index.module.scss
Normal file
150
components/reps/LoadingRep/index.module.scss
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
.gridRep {
|
||||
aspect-ratio: 3/2;
|
||||
border: 1px solid transparent;
|
||||
border-radius: $card-corner;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: $unit;
|
||||
padding: $unit-2x;
|
||||
min-width: 320px;
|
||||
width: 100%;
|
||||
|
||||
.placeholder {
|
||||
// background: var(--placeholder-bg);
|
||||
animation-duration: 2s;
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: placeHolderShimmer;
|
||||
animation-timing-function: linear;
|
||||
background-color: #f6f7f8;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--placeholder-bg) 8%,
|
||||
var(--placeholder-bg-accent) 18%,
|
||||
var(--placeholder-bg) 33%
|
||||
);
|
||||
background-size: 1200px 104px;
|
||||
|
||||
&.small {
|
||||
border-radius: calc($font-small / 2);
|
||||
height: $font-small;
|
||||
}
|
||||
|
||||
&.regular {
|
||||
border-radius: calc($font-regular / 2);
|
||||
height: $font-regular;
|
||||
}
|
||||
}
|
||||
|
||||
& > .weaponGrid {
|
||||
aspect-ratio: 2/0.95;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3.36fr; /* left column takes up 1 fraction, right column takes up 3 fractions */
|
||||
grid-gap: $unit; /* add a gap of 8px between grid items */
|
||||
|
||||
.weapon {
|
||||
border-radius: $item-corner-small;
|
||||
}
|
||||
|
||||
.mainhand.weapon {
|
||||
aspect-ratio: 73/153;
|
||||
display: grid;
|
||||
grid-column: 1 / 2; /* spans one column */
|
||||
height: calc(100% - $unit-fourth);
|
||||
}
|
||||
|
||||
.weapons {
|
||||
display: grid; /* make the right-images container a grid */
|
||||
grid-template-columns: repeat(
|
||||
3,
|
||||
1fr
|
||||
); /* create 3 columns, each taking up 1 fraction */
|
||||
grid-template-rows: repeat(
|
||||
3,
|
||||
1fr
|
||||
); /* create 3 rows, each taking up 1 fraction */
|
||||
gap: $unit;
|
||||
// column-gap: $unit;
|
||||
// row-gap: $unit-2x;
|
||||
}
|
||||
|
||||
.grid.weapon {
|
||||
aspect-ratio: 280 / 160;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.mainhand.weapon img[src*='jpg'],
|
||||
.grid.weapon img[src*='jpg'] {
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit-half;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: calc($unit / 2);
|
||||
align-items: center;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
gap: calc($unit / 2);
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.attributed {
|
||||
display: flex;
|
||||
gap: $unit-half;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
gap: calc($unit / 2);
|
||||
align-items: center;
|
||||
|
||||
.image {
|
||||
$diameter: 18px;
|
||||
|
||||
border-radius: calc($diameter / 2);
|
||||
height: $diameter;
|
||||
width: $diameter;
|
||||
}
|
||||
|
||||
.text {
|
||||
border-radius: calc($font-small / 2);
|
||||
height: $font-small;
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes placeHolderShimmer {
|
||||
$width: 400px;
|
||||
|
||||
0% {
|
||||
background-position: ($width * -1) 0;
|
||||
}
|
||||
100% {
|
||||
background-position: $width 0;
|
||||
}
|
||||
}
|
||||
81
components/reps/LoadingRep/index.tsx
Normal file
81
components/reps/LoadingRep/index.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import classNames from 'classnames'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
interface Props {}
|
||||
|
||||
const LoadingRep = (props: Props) => {
|
||||
const numWeapons: number = 9
|
||||
|
||||
const mainhandClasses = classNames({
|
||||
[styles.weapon]: true,
|
||||
[styles.mainhand]: true,
|
||||
[styles.placeholder]: true,
|
||||
})
|
||||
|
||||
const weaponClasses = classNames({
|
||||
[styles.weapon]: true,
|
||||
[styles.grid]: true,
|
||||
[styles.placeholder]: true,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className={styles.gridRep}>
|
||||
<div className={styles.details}>
|
||||
<div className={styles.top}>
|
||||
<div className={styles.info}>
|
||||
<div
|
||||
className={classNames({
|
||||
[styles.title]: true,
|
||||
[styles.placeholder]: true,
|
||||
[styles.regular]: true,
|
||||
})}
|
||||
/>
|
||||
<div className={styles.properties}>
|
||||
<span className={styles.raid} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.attributed}>
|
||||
<span className={styles.user}>
|
||||
<figure
|
||||
className={classNames({
|
||||
[styles.image]: true,
|
||||
[styles.placeholder]: true,
|
||||
})}
|
||||
/>
|
||||
<span
|
||||
className={classNames({
|
||||
[styles.text]: true,
|
||||
[styles.placeholder]: true,
|
||||
[styles.small]: true,
|
||||
})}
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className={classNames({
|
||||
[styles.timestamp]: true,
|
||||
[styles.placeholder]: true,
|
||||
[styles.small]: true,
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.weaponGrid}>
|
||||
<div className={mainhandClasses} />
|
||||
|
||||
<ul className={styles.weapons}>
|
||||
{Array.from(Array(numWeapons)).map((x, i) => {
|
||||
return (
|
||||
<li
|
||||
key={`placeholder-${Math.random()}`}
|
||||
className={weaponClasses}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoadingRep
|
||||
|
|
@ -15,8 +15,9 @@ import { permissiveFilterset } from '~utils/defaultFilters'
|
|||
import { elements, allElement } from '~data/elements'
|
||||
import { emptyPaginationObject } from '~utils/emptyStates'
|
||||
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import GridRep from '~components/reps/GridRep'
|
||||
import GridRepCollection from '~components/reps/GridRepCollection'
|
||||
import LoadingRep from '~components/reps/LoadingRep'
|
||||
import ErrorSection from '~components/ErrorSection'
|
||||
import FilterBar from '~components/filters/FilterBar'
|
||||
import ProfileHead from '~components/head/ProfileHead'
|
||||
|
|
@ -265,6 +266,26 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
)
|
||||
})
|
||||
}
|
||||
function renderLoading(number: number) {
|
||||
return (
|
||||
<GridRepCollection>
|
||||
{Array.from(Array(number)).map((x, i) => (
|
||||
<LoadingRep key={`loading-${i}`} />
|
||||
))}
|
||||
</GridRepCollection>
|
||||
)
|
||||
}
|
||||
|
||||
const renderInfiniteScroll = (
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={renderLoading(3)}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
)
|
||||
|
||||
if (context) {
|
||||
return (
|
||||
|
|
@ -285,18 +306,7 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
</FilterBar>
|
||||
|
||||
<section>
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={
|
||||
<div className="notFound">
|
||||
<h2>{t('loading')}</h2>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
{renderInfiniteScroll}
|
||||
|
||||
{parties.length == 0 ? (
|
||||
<div className="notFound">
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ import { elements, allElement } from '~data/elements'
|
|||
import { emptyPaginationObject } from '~utils/emptyStates'
|
||||
|
||||
import ErrorSection from '~components/ErrorSection'
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import GridRep from '~components/reps/GridRep'
|
||||
import GridRepCollection from '~components/reps/GridRepCollection'
|
||||
import LoadingRep from '~components/reps/LoadingRep'
|
||||
import FilterBar from '~components/filters/FilterBar'
|
||||
import SavedHead from '~components/head/SavedHead'
|
||||
|
||||
|
|
@ -306,6 +307,27 @@ const SavedRoute: React.FC<Props> = ({
|
|||
})
|
||||
}
|
||||
|
||||
function renderLoading(number: number) {
|
||||
return (
|
||||
<GridRepCollection>
|
||||
{Array.from(Array(number)).map((x, i) => (
|
||||
<LoadingRep key={`loading-${i}`} />
|
||||
))}
|
||||
</GridRepCollection>
|
||||
)
|
||||
}
|
||||
|
||||
const renderInfiniteScroll = (
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={renderLoading(3)}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
)
|
||||
|
||||
if (context) {
|
||||
return (
|
||||
<div className="teams">
|
||||
|
|
@ -325,18 +347,7 @@ const SavedRoute: React.FC<Props> = ({
|
|||
</FilterBar>
|
||||
|
||||
<section>
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={
|
||||
<div className="notFound">
|
||||
<h2>{t('loading')}</h2>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
{renderInfiniteScroll}
|
||||
|
||||
{parties.length == 0 ? (
|
||||
<div className="notFound">
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ import { emptyPaginationObject } from '~utils/emptyStates'
|
|||
import { convertAdvancedFilters } from '~utils/convertAdvancedFilters'
|
||||
|
||||
import ErrorSection from '~components/ErrorSection'
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import GridRep from '~components/reps/GridRep'
|
||||
import GridRepCollection from '~components/reps/GridRepCollection'
|
||||
import LoadingRep from '~components/reps/LoadingRep'
|
||||
import FilterBar from '~components/filters/FilterBar'
|
||||
import TeamsHead from '~components/head/TeamsHead'
|
||||
|
||||
|
|
@ -55,6 +56,7 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
// Set up app-specific states
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
// Set up page-specific states
|
||||
const [parties, setParties] = useState<Party[]>([])
|
||||
|
|
@ -122,6 +124,8 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
appState.version = version
|
||||
}
|
||||
setCurrentPage(1)
|
||||
|
||||
setIsLoading(false)
|
||||
}, [])
|
||||
|
||||
// Add scroll event listener for shadow on FilterBar on mount
|
||||
|
|
@ -151,6 +155,8 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
|
||||
const fetchTeams = useCallback(
|
||||
({ replace }: { replace: boolean }) => {
|
||||
setIsLoading(true)
|
||||
|
||||
const filters: {
|
||||
[key: string]: any
|
||||
} = {
|
||||
|
|
@ -183,6 +189,10 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
if (replace) replaceResults(meta.count, results)
|
||||
else appendResults(results)
|
||||
})
|
||||
.then(() => {
|
||||
console.log('You are here')
|
||||
setIsLoading(false)
|
||||
})
|
||||
.catch((error) => handleError(error))
|
||||
},
|
||||
[currentPage, parties, element, raid, recency, advancedFilters]
|
||||
|
|
@ -318,6 +328,27 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
})
|
||||
}
|
||||
|
||||
function renderLoading(number: number) {
|
||||
return (
|
||||
<GridRepCollection>
|
||||
{Array.from(Array(number)).map((x, i) => (
|
||||
<LoadingRep key={`loading-${i}`} />
|
||||
))}
|
||||
</GridRepCollection>
|
||||
)
|
||||
}
|
||||
|
||||
const renderInfiniteScroll = (
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={renderLoading(3)}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
)
|
||||
|
||||
if (context) {
|
||||
return (
|
||||
<div className="teams">
|
||||
|
|
@ -336,28 +367,7 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
<h1>{t('teams.title')}</h1>
|
||||
</FilterBar>
|
||||
|
||||
<section>
|
||||
<InfiniteScroll
|
||||
dataLength={parties && parties.length > 0 ? parties.length : 0}
|
||||
next={() => setCurrentPage(currentPage + 1)}
|
||||
hasMore={totalPages > currentPage}
|
||||
loader={
|
||||
<div className="notFound">
|
||||
<h2>{t('loading')}</h2>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<GridRepCollection>{renderParties()}</GridRepCollection>
|
||||
</InfiniteScroll>
|
||||
|
||||
{parties.length == 0 ? (
|
||||
<div className="notFound">
|
||||
<h2>{t('teams.not_found')}</h2>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
<section>{renderInfiniteScroll}</section>
|
||||
</div>
|
||||
)
|
||||
} else return pageError()
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@
|
|||
--selected-item-bg: #{$selected--item--bg--light};
|
||||
--selected-item-bg-hover: #{$selected--item--bg--light--hover};
|
||||
--anonymous-bg: #{$anonymous--bg--light};
|
||||
|
||||
--placeholder-bg: #{$grey-80};
|
||||
--placeholder-bg-accent: #{$grey-75};
|
||||
|
||||
--transparent-stroke: #{$transparent--stroke--light};
|
||||
|
||||
|
|
@ -252,7 +254,9 @@
|
|||
--selected-item-bg-hover: #{$selected--item--bg--dark--hover};
|
||||
|
||||
--anonymous-bg: #{$anonymous--bg--dark};
|
||||
|
||||
--placeholder-bg: #{$grey-40};
|
||||
--placeholder-bg-accent: #{$grey-45};
|
||||
|
||||
--transparent-stroke: #{$transparent--stroke--dark};
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ $grey-20: #212121;
|
|||
$grey-25: #232323;
|
||||
$grey-30: #2f2f2f;
|
||||
$grey-40: #444;
|
||||
$grey-45: #515151;
|
||||
$grey-50: #777;
|
||||
$grey-55: #888;
|
||||
$grey-60: #a9a9a9;
|
||||
|
|
|
|||
Loading…
Reference in a new issue