Add scroll, languages, settings

This commit is contained in:
obergodmar
2020-06-25 03:20:33 +03:00
parent 98a307f2cc
commit 8647adc66c
47 changed files with 946 additions and 120 deletions
@@ -1,98 +1,78 @@
@import "../../app/style";
$panelWidth: $previewWidth + 40px;
$panelHeight: $previewHeight + 40px;
$panelBorderSize: 8px;
.panel {
z-index: 2;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 20px;
border: none;
position: absolute;
height: 220px;
width: 360px;
height: $panelHeight;
width: $panelWidth;
background-image: $panelBackground;
background-repeat: repeat;
&-content {
display: flex;
justify-content: flex-start;
align-items: center;
}
button {
z-index: 3;
cursor: pointer;
position: absolute;
width: 10px;
height: 10px;
border: 2px solid var(--foreground);
background-color: unset;
transition: width 0.2s;
&:hover {
background-color: var(--foreground);
}
&:focus {
outline: none;
}
}
&--bottom {
bottom: -220px;
bottom: -$panelHeight + $panelBorderSize;
width: 100%;
transition: bottom 0.5s;
transition: bottom $transitionDuration $transitionType;
border-top: $panelBorderSize double $fontColor;
border-image: $borderTop 16 32 16 32;
border-image-outset: $panelBorderSize - 2px 0 0 0;
border-image-width: $panelBorderSize*2 0 0 100%;
border-image-repeat: round round;
.panel-border {
position: absolute;
z-index: 3;
top: -10px;
min-width: 100%;
background-image: $borderRight;
background-repeat: repeat;
height: 16px;
.panel-content {
height: 100%;
}
button {
left: 50%;
transform: translateX(-50%);
top: -10px;
width: 50px;
top: -$buttonHeight - 5px;
}
&--shown {
bottom: 0;
button {
height: 25px;
top: -25px;
}
}
}
&--left {
left: -360px;
flex-direction: column;
left: -$panelWidth + $panelBorderSize;
height: 100%;
transition: left 0.5s;
border-right: $panelBorderSize double $fontColor;
border-image: $borderRight 32 16 0 0;
border-image-outset: 0 $panelBorderSize - 2px 0 0;
border-image-width: 100% $panelBorderSize*2 0 0;
transition: left $transitionDuration $transitionType;
.panel-border {
position: absolute;
z-index: 3;
right: -8px;
min-height: 100%;
background-image: $borderTop;
background-repeat: repeat;
width: 16px;
.panel-content {
flex-direction: column;
width: 100%;
}
button {
top: 50%;
transform: translateY(-50%);
right: -10px;
height: 50px;
transform: translateY(-50%) rotate(90deg);
right: -80px;
}
&--shown {
left: 0;
button {
width: 25px;
right: -25px;
}
}
}
}
@@ -1,34 +1,124 @@
import * as React from 'react'
import { useCallback, useEffect, useState } from 'react'
import { FocusEvent, MouseEvent, useEffect, useMemo, useRef, useState, WheelEvent } from 'react'
import UIfx from 'uifx'
import { PREVIEW_HEIGHT, PREVIEW_WIDTH, UI_SOUND_VOLUME } from '../../utils'
import { useSettings } from '../../hooks'
import './panel-component.scss'
interface Props {
orientation: 'bottom' | 'left'
isShown: boolean
itemsCount: number
setShown: () => void
openSound: UIfx
closeSound: UIfx
children: React.ReactNode
}
export const PanelComponent = ({orientation, isShown, setShown, children}: Props) => {
const [isRendered, setRendered] = useState(false)
export const PanelComponent = ({
isShown,
setShown,
children,
openSound,
closeSound,
itemsCount,
orientation
}: Props) => {
const {settings: {language, uiSound}} = useSettings()
const [isDrag, setDrag] = useState(false)
const [trackMouse, setTrackMouse] = useState(0)
const [lastPosition, setLastPosition] = useState(0)
const panel = useRef<HTMLInputElement>(null)
let position = 0
const isBottom = useMemo(() => orientation === 'bottom', [orientation])
useEffect(() => {
setRendered(isShown)
if (!isShown && panel.current) {
panel.current.style.transform = 'unset'
setLastPosition(0)
}
}, [isShown])
const handleClick = useCallback((event) => {
const handleClick = (event: MouseEvent) => {
event.preventDefault()
setShown()
}, [setShown])
if (!uiSound) {
return
}
if (isShown) {
openSound.play(UI_SOUND_VOLUME)
} else {
closeSound.play(UI_SOUND_VOLUME)
}
}
const handleDragScroll = (e: MouseEvent) => {
if (!isDrag) {
return
}
const {clientX, clientY} = e
const value = isBottom ? clientX : clientY
position = trackMouse - value + lastPosition
changePosition()
}
const changePosition = () => {
if (!panel.current) {
return
}
const {innerHeight, innerWidth} = window
const overflowWindow = isBottom ? innerWidth : innerHeight
const overflowContainer = itemsCount * ((isBottom ? PREVIEW_WIDTH : PREVIEW_HEIGHT) + 10)
const overflow = overflowContainer > overflowWindow ? overflowContainer : overflowWindow
if (Math.abs(position) > overflow) {
position = -position
}
panel.current.style.transform = `translate${isBottom ? 'X' : 'Y'}(${-position}px)`
}
const handlePress = (e: MouseEvent) => {
e.preventDefault()
setTrackMouse(isBottom ? e.clientX : e.clientY)
setDrag(true)
}
const handleFree = (e: MouseEvent | FocusEvent) => {
e.preventDefault()
setDrag(false)
setLastPosition(position)
}
const handleScroll = (e: WheelEvent) => {
const {deltaY} = e
const value = deltaY > 0 ? 50 : -50
position = value + lastPosition
changePosition()
setLastPosition(position)
}
return (
<div
onMouseDown={handlePress}
onMouseUp={handleFree}
onMouseMove={handleDragScroll}
onMouseLeave={handleFree}
onWheel={handleScroll}
onBlur={handleFree}
className={`panel panel--${orientation} ${isShown ? `panel--${orientation}--shown` : ''}`}
>
<div className='panel-border'/>
{isRendered && children}
<button onClick={handleClick}/>
<div
ref={panel}
className='panel-content'
>
{isShown && children}
</div>
<button onClick={handleClick}>
{orientation === 'bottom' ? language['ui.button.views'] : language['ui.button.places']}
</button>
</div>
)
}