1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 21:06:42 +07:00

several bug fixes

This commit is contained in:
Fedor Katurov 2019-11-15 13:36:13 +07:00
parent f23b9166e1
commit 11348aa411
13 changed files with 281 additions and 110 deletions

View file

@ -228,12 +228,14 @@ const NodeImageSlideBlock: FC<IProps> = ({
</div>
)}
<ImageSwitcher
total={images.length}
current={current}
onChange={changeCurrent}
loaded={loaded}
/>
{!is_loading && (
<ImageSwitcher
total={images.length}
current={current}
onChange={changeCurrent}
loaded={loaded}
/>
)}
<div
className={styles.image_container}
@ -253,7 +255,7 @@ const NodeImageSlideBlock: FC<IProps> = ({
is_active: index === current && loaded[index]
})}
ref={setRef(index)}
key={file.id}
key={node.updated_at + file.id}
>
<img
className={styles.image}

View file

@ -1,10 +1,10 @@
import React, { FC } from 'react';
import * as styles from './styles.scss';
import { Group } from '~/components/containers/Group';
import classNames from 'classnames';
import { Filler } from '~/components/containers/Filler';
import { ERRORS } from '~/constants/errors';
import { t } from '~/utils/trans';
import React, { FC } from "react";
import * as styles from "./styles.scss";
import { Group } from "~/components/containers/Group";
import classNames from "classnames";
import { Filler } from "~/components/containers/Filler";
import { ERRORS } from "~/constants/errors";
import { t } from "~/utils/trans";
interface IProps {
is_loading?: boolean;
@ -17,8 +17,6 @@ const NodeNoComments: FC<IProps> = ({ is_loading = false }) => (
<div className={styles.card}>{!is_loading && t(ERRORS.NO_COMMENTS)}</div>
<div className={styles.card} />
</Group>
<Filler />
</>
);

View file

@ -1,30 +1,34 @@
@keyframes fade {
0% {
opacity: 0.25;
// opacity: 0.25;
}
100% {
opacity: 0.1;
// opacity: 0.1;
}
}
.wrap {
user-select: none;
height: 300px;
overflow: hidden;
position: relative;
@include after_shade($node_bg);
// @include after_shade($node_bg);
&:global(.is_loading) {
opacity: 1;
.card {
background: $placeholder_bg;
animation: fade 0.5s infinite alternate;
}
}
}
.card {
opacity: 0.2;
opacity: 0.3;
border-radius: $radius;
height: 96px;
background: $comment_bg;
background: $placeholder_bg;
display: flex;
align-items: center;
justify-content: center;
@ -33,7 +37,7 @@
color: transparentize(white, 0.5);
flex: 0 0 $comment_height;
@include outer_shadow();
// @include outer_shadow();
&:nth-child(2) {
// animation-delay: -300ms !important;

View file

@ -1,9 +1,16 @@
import React, { FC, useCallback, useEffect, useRef, useState, memo } from 'react';
import * as styles from './styles.scss';
import { INode } from '~/redux/types';
import { createPortal } from 'react-dom';
import { NodePanelInner } from '~/components/node/NodePanelInner';
import pick from 'ramda/es/pick';
import React, {
FC,
useCallback,
useEffect,
useRef,
useState,
memo
} from "react";
import * as styles from "./styles.scss";
import { INode } from "~/redux/types";
import { createPortal } from "react-dom";
import { NodePanelInner } from "~/components/node/NodePanelInner";
import pick from "ramda/es/pick";
interface IProps {
node: Partial<INode>;
@ -13,13 +20,25 @@ interface IProps {
can_like: boolean;
can_star: boolean;
is_loading?: boolean;
onEdit: () => void;
onLike: () => void;
onStar: () => void;
}
const NodePanel: FC<IProps> = memo(
({ node, layout, can_edit, can_like, can_star, onEdit, onLike, onStar }) => {
({
node,
layout,
can_edit,
can_like,
can_star,
is_loading,
onEdit,
onLike,
onStar
}) => {
const [stack, setStack] = useState(false);
const ref = useRef(null);
@ -35,12 +54,12 @@ const NodePanel: FC<IProps> = memo(
useEffect(() => {
getPlace();
window.addEventListener('scroll', getPlace);
window.addEventListener('resize', getPlace);
window.addEventListener("scroll", getPlace);
window.addEventListener("resize", getPlace);
return () => {
window.removeEventListener('scroll', getPlace);
window.removeEventListener('resize', getPlace);
window.removeEventListener("scroll", getPlace);
window.removeEventListener("resize", getPlace);
};
}, [layout]);
@ -57,6 +76,7 @@ const NodePanel: FC<IProps> = memo(
can_edit={can_edit}
can_like={can_like}
can_star={can_star}
is_loading={is_loading}
/>,
document.body
)
@ -69,6 +89,7 @@ const NodePanel: FC<IProps> = memo(
can_edit={can_edit}
can_like={can_like}
can_star={can_star}
is_loading={is_loading}
/>
)}
</div>

View file

@ -1,10 +1,11 @@
import React, { FC } from 'react';
import * as styles from './styles.scss';
import { Group } from '~/components/containers/Group';
import { Filler } from '~/components/containers/Filler';
import { Icon } from '~/components/input/Icon';
import { INode } from '~/redux/types';
import classNames from 'classnames';
import React, { FC } from "react";
import * as styles from "./styles.scss";
import { Group } from "~/components/containers/Group";
import { Filler } from "~/components/containers/Filler";
import { Icon } from "~/components/input/Icon";
import { INode } from "~/redux/types";
import classNames from "classnames";
import { Placeholder } from "~/components/placeholders/Placeholder";
interface IProps {
node: Partial<INode>;
@ -13,6 +14,9 @@ interface IProps {
can_edit: boolean;
can_like: boolean;
can_star: boolean;
is_loading: boolean;
onEdit: () => void;
onLike: () => void;
onStar: () => void;
@ -21,20 +25,34 @@ interface IProps {
const NodePanelInner: FC<IProps> = ({
node: { title, user, is_liked, is_heroic },
stack,
can_star,
can_edit,
can_like,
is_loading,
onStar,
onEdit,
onLike,
onLike
}) => {
return (
<div className={classNames(styles.wrap, { stack })}>
<div className={styles.content}>
<Group horizontal className={styles.panel}>
<Filler>
<div className={styles.title}>{title || '...'}</div>
{user && user.username && <div className={styles.name}>~{user.username}</div>}
<div className={styles.title}>
{is_loading ? <Placeholder width="40%" /> : title || "..."}
</div>
{user && user.username && (
<div className={styles.name}>
{is_loading ? (
<Placeholder width="100px" />
) : (
`~${user.username}`
)}
</div>
)}
</Filler>
</Group>

View file

@ -0,0 +1,31 @@
import React, { FC, memo } from "react";
import styles from "./styles.scss";
import cell_style from "~/components/node/NodeRelatedItem/styles.scss";
import { Group } from "~/components/containers/Group";
import { Placeholder } from "~/components/placeholders/Placeholder";
import range from "ramda/es/range";
import classNames from "classnames";
interface IProps {}
const NodeRelatedPlaceholder: FC<IProps> = memo(() => {
return (
<Group className={classNames(styles.wrap, styles.placeholder)}>
<div className={styles.title}>
<div className={styles.line} />
<div className={styles.text}>
<Placeholder />
</div>
<div className={styles.line} />
</div>
<div className={styles.grid}>
{range(0, 6).map(el => (
<div className={cell_style.item} key={el} />
))}
</div>
</Group>
);
});
export { NodeRelatedPlaceholder };

View file

@ -36,3 +36,15 @@
.text {
margin: 0 $gap;
}
.placeholder {
.text {
opacity: 1;
}
.grid {
div {
background: $placeholder_bg;
}
}
}

View file

@ -0,0 +1,17 @@
import React, { FC, memo } from "react";
import { Tags } from "../Tags";
import { ITag } from "~/redux/types";
interface IProps {
is_editable?: boolean;
tags: ITag[];
onChange?: (tags: string[]) => void;
}
const NodeTagsPlaceholder: FC<IProps> = memo(
({ is_editable, tags, onChange }) => (
<Tags tags={tags} is_editable={is_editable} onTagsChange={onChange} />
)
);
export { NodeTagsPlaceholder };

View file

@ -6,13 +6,12 @@ import React, {
useEffect,
KeyboardEvent,
ChangeEvent,
useRef,
} from 'react';
import { TagField } from '~/components/containers/TagField';
import { ITag } from '~/redux/types';
import { Tag } from '~/components/node/Tag';
import uniq from 'ramda/es/uniq';
import assocPath from 'ramda/es/assocPath';
useRef
} from "react";
import { TagField } from "~/components/containers/TagField";
import { ITag } from "~/redux/types";
import { Tag } from "~/components/node/Tag";
import uniq from "ramda/es/uniq";
type IProps = HTMLAttributes<HTMLDivElement> & {
tags: Partial<ITag>[];
@ -20,8 +19,13 @@ type IProps = HTMLAttributes<HTMLDivElement> & {
onTagsChange?: (tags: string[]) => void;
};
export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props }) => {
const [input, setInput] = useState('');
export const Tags: FC<IProps> = ({
tags,
is_editable,
onTagsChange,
...props
}) => {
const [input, setInput] = useState("");
const [data, setData] = useState([]);
const timer = useRef(null);
@ -35,17 +39,17 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
const onKeyUp = useCallback(
({ key }: KeyboardEvent) => {
if (key === 'Backspace' && input === '' && data.length) {
if (key === "Backspace" && input === "" && data.length) {
setData(data.slice(0, data.length - 1));
setInput(data[data.length - 1].title);
}
if (key === 'Enter' || key === ',' || key === 'Comma') {
if (key === "Enter" || key === "," || key === "Comma") {
setData(
uniq([
...data,
...input
.split(',')
.split(",")
.map((title: string) =>
title
.trim()
@ -55,11 +59,11 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
.filter(el => el.length > 0)
.filter(el => !tags.some(tag => tag.title.trim() === el.trim()))
.map(title => ({
title,
})),
title
}))
])
);
setInput('');
setInput("");
}
},
[input, setInput, data, setData]
@ -71,12 +75,16 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
if (!items.length) return;
setData(items);
setInput('');
setInput("");
onTagsChange(uniq([...tags, ...items]).map(tag => tag.title));
}, [tags, data, onTagsChange, input, setInput]);
useEffect(() => {
setData(data.filter(({ title }) => !tags.some(tag => tag.title.trim() === title.trim())));
setData(
data.filter(
({ title }) => !tags.some(tag => tag.title.trim() === title.trim())
)
);
}, [tags]);
return (
@ -90,7 +98,12 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
))}
{is_editable && (
<Tag tag={{ title: input }} onInput={onInput} onKeyUp={onKeyUp} onBlur={onSubmit} />
<Tag
tag={{ title: input }}
onInput={onInput}
onKeyUp={onKeyUp}
onBlur={onSubmit}
/>
)}
</TagField>
);

View file

@ -1,6 +1,6 @@
.placeholder {
height: 1em;
width: 120px;
background: transparentize(white, 0.95);
background: $placeholder_bg;
border-radius: 1em;
}