sforkowany z mirror/soapbox
Placeholder: display placeholders for Notifications, refactor scss
rodzic
7f1613dd20
commit
f808ac6786
|
@ -20,6 +20,7 @@ import ScrollableList from '../../components/scrollable_list';
|
||||||
import LoadGap from '../../components/load_gap';
|
import LoadGap from '../../components/load_gap';
|
||||||
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
|
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
|
import PlaceholderNotification from 'soapbox/features/placeholder/components/placeholder_notification';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'column.notifications', defaultMessage: 'Notifications' },
|
title: { id: 'column.notifications', defaultMessage: 'Notifications' },
|
||||||
|
@ -170,6 +171,8 @@ class Notifications extends React.PureComponent {
|
||||||
showLoading={isLoading && notifications.size === 0}
|
showLoading={isLoading && notifications.size === 0}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
emptyMessage={emptyMessage}
|
emptyMessage={emptyMessage}
|
||||||
|
placeholderComponent={PlaceholderNotification}
|
||||||
|
placeholderCount={20}
|
||||||
onLoadMore={this.handleLoadOlder}
|
onLoadMore={this.handleLoadOlder}
|
||||||
onScrollToTop={this.handleScrollToTop}
|
onScrollToTop={this.handleScrollToTop}
|
||||||
onScroll={this.handleScroll}
|
onScroll={this.handleScroll}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PlaceholderAvatar from './placeholder_avatar';
|
||||||
|
import PlaceholderDisplayName from './placeholder_display_name';
|
||||||
|
|
||||||
|
export default class PlaceholderAccount extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className='account'>
|
||||||
|
<div className='account__wrapper'>
|
||||||
|
<span className='account__display-name'>
|
||||||
|
<div className='account__avatar-wrapper'>
|
||||||
|
<PlaceholderAvatar size={36} />
|
||||||
|
</div>
|
||||||
|
<PlaceholderDisplayName minLength={3} maxLength={25} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,14 +12,16 @@ export default class DisplayName extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { maxLength, minLength } = this.props;
|
const { maxLength, minLength } = this.props;
|
||||||
const length = randomIntFromInterval(maxLength, minLength);
|
const length = randomIntFromInterval(maxLength, minLength);
|
||||||
|
const acctLength = randomIntFromInterval(maxLength, minLength);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className='display-name'>
|
<span className='display-name display-name--placeholder'>
|
||||||
<span>
|
<span>
|
||||||
<span className='display-name__name'>
|
<span className='display-name__name'>
|
||||||
<bdi><strong className='display-name__html'>{generateText(length)}</strong></bdi>
|
<bdi><strong className='display-name__html'>{generateText(length)}</strong></bdi>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
<span class='display-name__account'>{generateText(acctLength)}</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PlaceholderAccount from './placeholder_account';
|
||||||
|
import { randomIntFromInterval, generateText } from '../utils';
|
||||||
|
|
||||||
|
export default class PlaceholderNotification extends React.Component {
|
||||||
|
|
||||||
|
shouldComponentUpdate() {
|
||||||
|
// Re-rendering this will just cause the random lengths to jump around.
|
||||||
|
// There's basically no reason to ever do it.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className='notification notification-follow notification--placeholder' tabIndex='0'>
|
||||||
|
<div className='notification__message'>
|
||||||
|
<span>
|
||||||
|
{generateText(randomIntFromInterval(15, 30))}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PlaceholderAccount />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ export default class PlaceholderStatusContent extends React.Component {
|
||||||
const length = randomIntFromInterval(maxLength, minLength);
|
const length = randomIntFromInterval(maxLength, minLength);
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className='status__content' tabIndex='0' key='content'>
|
<div className='status__content status__content--placeholder' tabIndex='0' key='content'>
|
||||||
{generateText(length)}
|
{generateText(length)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
@import 'demetricator';
|
@import 'demetricator';
|
||||||
@import 'chats';
|
@import 'chats';
|
||||||
@import 'navigation';
|
@import 'navigation';
|
||||||
|
@import 'placeholder';
|
||||||
|
|
||||||
// COMPONENTS
|
// COMPONENTS
|
||||||
@import 'components/buttons';
|
@import 'components/buttons';
|
||||||
|
|
|
@ -204,43 +204,3 @@ noscript {
|
||||||
.greentext {
|
.greentext {
|
||||||
color: #789922;
|
color: #789922;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder-status {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 0%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 25%,
|
|
||||||
var(--foreground-color) 50%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 70%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 100%
|
|
||||||
);
|
|
||||||
background-size: 200%;
|
|
||||||
animation: placeholder-pulse 2s infinite;
|
|
||||||
z-index: 1;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status__display-name strong,
|
|
||||||
.status__content {
|
|
||||||
letter-spacing: -1px;
|
|
||||||
color: var(--brand-color);
|
|
||||||
opacity: 0.1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes placeholder-pulse {
|
|
||||||
0% { background-position-x: 200%; }
|
|
||||||
100% { background-position-x: 0; }
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
.placeholder-status,
|
||||||
|
.notification--placeholder {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
hsla(var(--foreground-color_hsl), 0) 0%,
|
||||||
|
hsla(var(--foreground-color_hsl), 0) 25%,
|
||||||
|
var(--foreground-color) 50%,
|
||||||
|
hsla(var(--foreground-color_hsl), 0) 70%,
|
||||||
|
hsla(var(--foreground-color_hsl), 0) 100%
|
||||||
|
);
|
||||||
|
background-size: 200%;
|
||||||
|
animation: placeholder-pulse 2s infinite;
|
||||||
|
z-index: 1;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-status .display-name__account {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes placeholder-pulse {
|
||||||
|
0% { background-position-x: 200%; }
|
||||||
|
100% { background-position-x: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification--placeholder {
|
||||||
|
.notification__message span {
|
||||||
|
color: var(--brand-color);
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status__content--placeholder,
|
||||||
|
.display-name--placeholder {
|
||||||
|
letter-spacing: -1px;
|
||||||
|
color: var(--brand-color) !important;
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-name--placeholder {
|
||||||
|
.display-name__html {
|
||||||
|
color: var(--brand-color) !important;
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue