mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
submit bar
This commit is contained in:
parent
6bb24fc869
commit
3fdf14d680
10 changed files with 131 additions and 24 deletions
|
@ -1,14 +1,8 @@
|
||||||
.place {
|
.place {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 64px;
|
height: $bar_height;
|
||||||
flex: 0 1 500px;
|
flex: 0 1 500px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.seeker {
|
|
||||||
transform: translate(0, -64px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrap {
|
.wrap {
|
||||||
|
@ -22,7 +16,7 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 64px;
|
height: $bar_height;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
transform: translate(0, 0);
|
transform: translate(0, 0);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
@ -30,18 +24,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
flex: 0 0 64px;
|
flex: 0 0 $bar_height;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 64px;
|
height: $bar_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playpause,
|
.playpause,
|
||||||
.close {
|
.close {
|
||||||
flex: 0 0 48px;
|
flex: 0 0 $bar_height;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
39
src/components/bars/SubmitBar/index.tsx
Normal file
39
src/components/bars/SubmitBar/index.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { FC, useCallback } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
import * as MODAL_ACTIONS from '~/redux/modal/actions';
|
||||||
|
import { DIALOGS } from '~/redux/modal/constants';
|
||||||
|
|
||||||
|
import * as styles from './styles.scss';
|
||||||
|
|
||||||
|
const mapStateToProps = null;
|
||||||
|
const mapDispatchToProps = {
|
||||||
|
showDialog: MODAL_ACTIONS.modalShowDialog,
|
||||||
|
};
|
||||||
|
|
||||||
|
type IProps = typeof mapDispatchToProps & {};
|
||||||
|
|
||||||
|
const SubmitBarUnconnected: FC<IProps> = ({ showDialog }) => {
|
||||||
|
const onOpenImageEditor = useCallback(() => showDialog(DIALOGS.EDITOR_IMAGE), [showDialog]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrap}>
|
||||||
|
<div className={styles.panel}>
|
||||||
|
<div onClick={onOpenImageEditor}>
|
||||||
|
<Icon icon="image" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.button}>
|
||||||
|
<Icon icon="plus" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SubmitBar = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(SubmitBarUnconnected);
|
||||||
|
|
||||||
|
export { SubmitBar };
|
65
src/components/bars/SubmitBar/styles.scss
Normal file
65
src/components/bars/SubmitBar/styles.scss
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
.wrap {
|
||||||
|
position: absolute;
|
||||||
|
right: -($bar_height + $gap);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.panel {
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include tablet {
|
||||||
|
position: relative;
|
||||||
|
right: 0;
|
||||||
|
margin-left: $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: $red_gradient;
|
||||||
|
width: $bar_height;
|
||||||
|
height: $bar_height;
|
||||||
|
border-radius: $bar_height / 2;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background: lighten($content_bg, 4%);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1;
|
||||||
|
padding-bottom: $bar_height;
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
transform: translate(0, 100%);
|
||||||
|
transition: transform 250ms;
|
||||||
|
|
||||||
|
div {
|
||||||
|
@include outer_shadow;
|
||||||
|
height: $bar_height;
|
||||||
|
width: $bar_height;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-radius: $radius $radius 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,9 +12,7 @@ import * as MODAL_ACTIONS from '~/redux/modal/actions';
|
||||||
import { DIALOGS } from '~/redux/modal/constants';
|
import { DIALOGS } from '~/redux/modal/constants';
|
||||||
import { pick } from 'ramda';
|
import { pick } from 'ramda';
|
||||||
import { Icon } from '~/components/input/Icon';
|
import { Icon } from '~/components/input/Icon';
|
||||||
import { url } from 'inspector';
|
|
||||||
import { getURL } from '~/utils/dom';
|
import { getURL } from '~/utils/dom';
|
||||||
import path from 'ramda/es/path';
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
user: pick(['username', 'is_user', 'photo'])(selectUser(state)),
|
user: pick(['username', 'is_user', 'photo'])(selectUser(state)),
|
||||||
|
@ -29,7 +27,6 @@ type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {
|
||||||
|
|
||||||
const HeaderUnconnected: FC<IProps> = ({ user: { username, is_user, photo }, showDialog }) => {
|
const HeaderUnconnected: FC<IProps> = ({ user: { username, is_user, photo }, showDialog }) => {
|
||||||
const onLogin = useCallback(() => showDialog(DIALOGS.LOGIN), [showDialog]);
|
const onLogin = useCallback(() => showDialog(DIALOGS.LOGIN), [showDialog]);
|
||||||
const onOpenEditor = useCallback(() => showDialog(DIALOGS.EDITOR), [showDialog]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.container}>
|
<div className={style.container}>
|
||||||
|
@ -38,7 +35,6 @@ const HeaderUnconnected: FC<IProps> = ({ user: { username, is_user, photo }, sho
|
||||||
<Filler />
|
<Filler />
|
||||||
|
|
||||||
<div className={style.plugs}>
|
<div className={style.plugs}>
|
||||||
<div onClick={onOpenEditor}>editor</div>
|
|
||||||
<Link to="/">flow</Link>
|
<Link to="/">flow</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import * as styles from './styles.scss';
|
import * as styles from './styles.scss';
|
||||||
import { PlayerBar } from '~/components/bars/PlayerBar';
|
import { PlayerBar } from '~/components/bars/PlayerBar';
|
||||||
|
import { SubmitBar } from '~/components/bars/SubmitBar';
|
||||||
|
import { selectUser } from '~/redux/auth/selectors';
|
||||||
|
import pick from 'ramda/es/pick';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
interface IProps {}
|
const mapStateToProps = state => pick(['is_user'], selectUser(state));
|
||||||
|
|
||||||
const BottomContainer: FC<IProps> = ({}) => (
|
type IProps = ReturnType<typeof mapStateToProps> & {};
|
||||||
|
|
||||||
|
const BottomContainerUnconnected: FC<IProps> = ({ is_user }) => (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<PlayerBar />
|
<PlayerBar />
|
||||||
|
|
||||||
|
{is_user && <SubmitBar />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const BottomContainer = connect(mapStateToProps)(BottomContainerUnconnected);
|
||||||
export { BottomContainer };
|
export { BottomContainer };
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
height: 64px;
|
height: $bar_height;
|
||||||
display: flex;
|
display: flex;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 0 1 $content_width;
|
flex: 0 1 $content_width;
|
||||||
height: 48px;
|
height: $bar_height;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
@include tablet {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { ValueOf } from '~/redux/types';
|
import { ValueOf } from '~/redux/types';
|
||||||
import { HorizontalExample } from '~/containers/examples/HorizontalExample';
|
|
||||||
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
||||||
import { LoginDialog } from '~/containers/dialogs/LoginDialog';
|
import { LoginDialog } from '~/containers/dialogs/LoginDialog';
|
||||||
|
|
||||||
|
@ -10,12 +9,12 @@ export const MODAL_ACTIONS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DIALOGS = {
|
export const DIALOGS = {
|
||||||
EDITOR: 'EDITOR',
|
EDITOR_IMAGE: 'EDITOR_IMAGE',
|
||||||
LOGIN: 'LOGIN',
|
LOGIN: 'LOGIN',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DIALOG_CONTENT = {
|
export const DIALOG_CONTENT = {
|
||||||
[DIALOGS.EDITOR]: EditorDialog,
|
[DIALOGS.EDITOR_IMAGE]: EditorDialog,
|
||||||
[DIALOGS.LOGIN]: LoginDialog,
|
[DIALOGS.LOGIN]: LoginDialog,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ export interface IModalState {
|
||||||
|
|
||||||
const INITIAL_STATE: IModalState = {
|
const INITIAL_STATE: IModalState = {
|
||||||
is_shown: false,
|
is_shown: false,
|
||||||
dialog: DIALOGS.EDITOR,
|
dialog: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createReducer(INITIAL_STATE, MODAL_HANDLERS);
|
export default createReducer(INITIAL_STATE, MODAL_HANDLERS);
|
||||||
|
|
|
@ -6,6 +6,7 @@ $content_width: $cell * 4 + $grid_line * 3;
|
||||||
$gap: 10px;
|
$gap: 10px;
|
||||||
$spc: $gap * 2;
|
$spc: $gap * 2;
|
||||||
$comment_height: 72px;
|
$comment_height: 72px;
|
||||||
|
$bar_height: 64px;
|
||||||
|
|
||||||
$radius: 8px;
|
$radius: 8px;
|
||||||
$cell_radius: $radius;
|
$cell_radius: $radius;
|
||||||
|
@ -67,7 +68,7 @@ $input_shadow_error: inset $red 0 0 0 1px;
|
||||||
$input_shadow_filled: $input_shadow;
|
$input_shadow_filled: $input_shadow;
|
||||||
|
|
||||||
@mixin outer_shadow() {
|
@mixin outer_shadow() {
|
||||||
box-shadow: inset transparentize(white, 0.95) 0 1px, transparentize(black, 0.8) 0 3px;
|
box-shadow: inset transparentize(white, 0.95) 1px 1px, transparentize(black, 0.8) -1px -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin inner_shadow() {
|
@mixin inner_shadow() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue