Further UI improvements
This commit is contained in:
parent
05e519c737
commit
7542e762fc
15 changed files with 189 additions and 182 deletions
|
@ -1,5 +1,5 @@
|
|||
$black: #454545;
|
||||
$max-width: 475px;
|
||||
$max-width: 728px;
|
||||
|
||||
[lang="en"] {
|
||||
font-family: "Kanit Regular";
|
||||
|
@ -26,7 +26,8 @@ body .root {
|
|||
|
||||
body .root .content {
|
||||
margin: 0 auto;
|
||||
width: $max-width;
|
||||
width: 80%;
|
||||
max-width: $max-width;
|
||||
height: 100%;
|
||||
|
||||
@media screen and (max-width: $max-width) {
|
||||
|
@ -59,7 +60,7 @@ body .root .content .row.dropdown-row {
|
|||
body .root .content ul.body {
|
||||
clear: both;
|
||||
list-style-type: none;
|
||||
height: 400px;
|
||||
height: 90%;
|
||||
padding: 0;
|
||||
|
||||
/* Height of 625px, or less */
|
||||
|
|
96
src/css/components/Icon.scss
Normal file
96
src/css/components/Icon.scss
Normal file
|
@ -0,0 +1,96 @@
|
|||
.play.icon, .pause.icon {
|
||||
width: 32px;
|
||||
height: 22px;
|
||||
g {
|
||||
transform: translate(2px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.pause.icon g {
|
||||
rect {
|
||||
width: 15px;
|
||||
height: 40px;
|
||||
fill: #FFF;
|
||||
}
|
||||
rect:first-child {
|
||||
transform: translate(-3px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.refresh.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.stalled.icon {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
left: 7px;
|
||||
height: 4px;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
width: 6px;
|
||||
animation: stalled 0.8s cubic-bezier(0, 0.5, 0.5, 1) infinite;
|
||||
}
|
||||
|
||||
div:nth-child(1) {
|
||||
left: 12px;
|
||||
animation-delay: -0.24s;
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
left: 20px;
|
||||
animation-delay: -0.12s;
|
||||
}
|
||||
|
||||
div:nth-child(3) {
|
||||
left: 28px;
|
||||
animation-delay: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes stalled {
|
||||
0% {
|
||||
top: 4px;
|
||||
height: 8px;
|
||||
}
|
||||
50%, 100% {
|
||||
top: 8px;
|
||||
height: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.content.theme ul.stream span.title {
|
||||
.sound-on.icon, .sound-off.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
transform: translate(0, 4px);
|
||||
}
|
||||
}
|
||||
|
||||
.content.theme {
|
||||
.footer .sound-on.icon, .footer .sound-off.icon {
|
||||
width: 32px;
|
||||
height: 30px;
|
||||
g { transform: translate(32px,30px); }
|
||||
}
|
||||
}
|
||||
|
||||
.content.theme.ar {
|
||||
ul.stream span.title {
|
||||
.sound-on.icon, .sound-off.icon {
|
||||
transform: rotate(180deg);
|
||||
g {
|
||||
transform: translate(0px, 10px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer .sound-on.icon, .footer .sound-off.icon {
|
||||
transform: rotate(180deg);
|
||||
g {transform: translate(32px,3px); }
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
.shape {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 5px;
|
||||
background: #606850;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
.shape .play-shape {
|
||||
position: relative;
|
||||
left: 1px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #FFF;
|
||||
clip-path: polygon(0 0, 100% 50%, 0 100%);
|
||||
}
|
||||
|
||||
.shape .pause-shape {
|
||||
width: 3px;
|
||||
height: 12px;
|
||||
background: #FFF;
|
||||
clip-path: stroke-box;
|
||||
|
||||
&:first-child {
|
||||
position: relative;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
position: relative;
|
||||
left: 1.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
right: 38px;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
width: 6px;
|
||||
animation: loading 0.8s cubic-bezier(0, 0.5, 0.5, 1) infinite;
|
||||
}
|
||||
|
||||
div:nth-child(1) {
|
||||
left: 12px;
|
||||
animation-delay: -0.24s;
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
left: 20px;
|
||||
animation-delay: -0.12s;
|
||||
}
|
||||
|
||||
div:nth-child(3) {
|
||||
left: 28px;
|
||||
animation-delay: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
top: 4px;
|
||||
height: 8px;
|
||||
}
|
||||
50%, 100% {
|
||||
top: 8px;
|
||||
height: 4px;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
@import "layout";
|
||||
@import "components/Select";
|
||||
@import "components/Shape";
|
||||
@import "components/Icon";
|
||||
|
||||
.content .row.details {
|
||||
direction: rtl;
|
||||
|
@ -41,34 +41,18 @@
|
|||
}
|
||||
|
||||
.content .row.footer {
|
||||
height: 32px;
|
||||
align-items: flex-end;
|
||||
|
||||
.timer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 65%;
|
||||
justify-content: flex-end;
|
||||
width: 40px;
|
||||
|
||||
font-size: 80%;
|
||||
font-family: "Kanit Regular";
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.shape {
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.svg.sound-on, .svg.sound-off {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
g { transform: translate(16px, 16px); }
|
||||
}
|
||||
|
||||
.shape.refresh {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,10 +81,6 @@
|
|||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.svg.sound-on, .svg.sound-off {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@import "themes/moon";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
$green: #606850;
|
||||
$white: #FFF;
|
||||
$white-primary: #FFF;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.surah.id {
|
||||
background: $green;
|
||||
color: $white;
|
||||
color: $white-primary;
|
||||
border-radius: 5px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.timer {
|
||||
background-color: $green;
|
||||
color: $white;
|
||||
color: $white-primary;
|
||||
}
|
||||
|
||||
.row .shape.refresh {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
$gold: #ECB200;
|
||||
$gold-light: lighten($gold, 10%);
|
||||
$blue :darken(#e4eff8, 35%);
|
||||
$white: #FFF;
|
||||
$gold-primary: #ECB200;
|
||||
$gold-secondary: lighten($gold-primary, 5%);
|
||||
$blue-primary: darken(#e4eff8, 35%);
|
||||
$white-primary: #FFF;
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
.root .content.theme.moon {
|
||||
@import "colors";
|
||||
|
||||
.header .image {
|
||||
background-image: url("/images/moon.svg");
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.row.title {
|
||||
color: $gold;
|
||||
color: $gold-primary;
|
||||
}
|
||||
|
||||
.row.dropdown-row .react-select {
|
||||
color: $gold;
|
||||
color: $gold-primary;
|
||||
}
|
||||
}
|
||||
|
|
31
src/css/themes/moon/components/_Icon.scss
Normal file
31
src/css/themes/moon/components/_Icon.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
.play.icon {
|
||||
fill: $blue-primary;
|
||||
stroke: darken($blue-primary, 40%);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.pause.icon {
|
||||
background: unset;
|
||||
rect {
|
||||
fill: $blue-primary;
|
||||
stroke: darken($blue-primary, 40%);
|
||||
stroke-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.refresh.icon {
|
||||
background: unset;
|
||||
fill: $blue-primary;
|
||||
}
|
||||
|
||||
.stalled.icon {
|
||||
div { background: $gold-secondary; }
|
||||
}
|
||||
|
||||
.sound-on.icon, .sound-off.icon {
|
||||
polygon {
|
||||
fill: $blue-primary;
|
||||
stroke-width: 2;
|
||||
}
|
||||
}
|
|
@ -7,21 +7,21 @@
|
|||
|
||||
ul.body.index a {
|
||||
&:active, &:link, &:visited {
|
||||
color: $blue;
|
||||
color: $blue-primary;
|
||||
}
|
||||
|
||||
.surah.id {
|
||||
background: $gold-light;
|
||||
color: $white;
|
||||
background: $gold-secondary;
|
||||
color: $white-primary;
|
||||
border-radius: 5px;
|
||||
padding: 3px;
|
||||
border: 1px solid $blue;
|
||||
border: 1px solid $blue-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.row.surah.choose-random {
|
||||
&:active, &:link, &:visited {
|
||||
color: $blue;
|
||||
color: $blue-primary;
|
||||
text-decoration: none;
|
||||
}
|
||||
&:hover {
|
||||
|
|
|
@ -1,41 +1,21 @@
|
|||
.root .content.theme.moon {
|
||||
@import "themes/moon/colors";
|
||||
@import "themes/moon/components/Icon";
|
||||
|
||||
.row.details {
|
||||
color: $gold;
|
||||
color: $gold-primary;
|
||||
}
|
||||
|
||||
.row.footer .timer {
|
||||
color: $blue-primary;
|
||||
}
|
||||
|
||||
ul.body.stream {
|
||||
li.ayah {
|
||||
span.title {
|
||||
color: $gold;
|
||||
color: $gold-primary;
|
||||
}
|
||||
p { }
|
||||
}
|
||||
}
|
||||
|
||||
.row .timer {
|
||||
color: $white;
|
||||
background: $gold;
|
||||
}
|
||||
|
||||
.row .shape {
|
||||
background: $gold;
|
||||
}
|
||||
|
||||
.row .shape.refresh {
|
||||
background: unset;
|
||||
fill: $gold;
|
||||
}
|
||||
|
||||
.row .loading div {
|
||||
background: $gold;
|
||||
}
|
||||
|
||||
.svg.sound-on, .svg.sound-off {
|
||||
polygon {
|
||||
fill: $blue;
|
||||
stroke-width: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import url from "url";
|
||||
import * as Quran from "lib/Quran";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { SoundOnShape, SoundOffShape } from "components/Shape";
|
||||
import { SoundOnIcon, SoundOffIcon } from "components/Icon";
|
||||
|
||||
type Props = {
|
||||
recitation: Quran.Recitation;
|
||||
|
@ -54,8 +54,8 @@ export function AudioControl({
|
|||
|
||||
return (
|
||||
<>
|
||||
{soundOn && <SoundOnShape onClick={turnOffSound} />}
|
||||
{!soundOn && <SoundOffShape onClick={turnOnSound} />}
|
||||
{soundOn && <SoundOnIcon onClick={turnOffSound} />}
|
||||
{!soundOn && <SoundOffIcon onClick={turnOnSound} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,29 +4,33 @@ interface Props {
|
|||
onClick: () => void;
|
||||
}
|
||||
|
||||
export function PlayShape({ onClick }: Props) {
|
||||
export function PlayIcon({ onClick }: Props) {
|
||||
return (
|
||||
<div className="shape" onClick={onClick}>
|
||||
<div className="play-shape" />
|
||||
</div>
|
||||
<svg className="play icon" onClick={onClick} viewBox="0 0 48 48">
|
||||
<g>
|
||||
<path d="M10,6 L38,24 L10,42 Z" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function PauseShape({ onClick }: Props) {
|
||||
export function PauseIcon({ onClick }: Props) {
|
||||
return (
|
||||
<div className="shape" onClick={onClick}>
|
||||
<div className="pause-shape" />
|
||||
<div className="pause-shape" />
|
||||
</div>
|
||||
<svg className="icon pause" onClick={onClick} viewBox="0 0 48 48">
|
||||
<g>
|
||||
<rect x="7" y="6" />
|
||||
<rect x="28" y="6" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function SoundOnShape({ onClick }: Props) {
|
||||
export function SoundOnIcon({ onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
className="svg sound-off"
|
||||
className="sound-on icon"
|
||||
onClick={onClick}
|
||||
>
|
||||
<g>
|
||||
|
@ -57,12 +61,12 @@ export function SoundOnShape({ onClick }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export function SoundOffShape({ onClick }: Props) {
|
||||
export function SoundOffIcon({ onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
className="svg sound-off"
|
||||
className="sound-off icon"
|
||||
onClick={onClick}
|
||||
>
|
||||
<g>
|
||||
|
@ -99,11 +103,11 @@ export function SoundOffShape({ onClick }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export function RefreshShape({ onClick }: Props) {
|
||||
export function RefreshIcon({ onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
onClick={onClick}
|
||||
className="shape refresh"
|
||||
className="refresh icon"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="438.542px"
|
||||
|
@ -145,9 +149,9 @@ export function RefreshShape({ onClick }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export function LoadingShape() {
|
||||
export function StalledIcon() {
|
||||
return (
|
||||
<div className="loading">
|
||||
<div className="stalled icon">
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
|
@ -8,7 +8,7 @@ import { SelectOption } from "components/Select";
|
|||
import { ThemeSelect } from "components/ThemeSelect";
|
||||
import { LanguageSelect } from "components/LanguageSelect";
|
||||
import { AudioControl } from "components/AudioControl";
|
||||
import { PlayShape, PauseShape, RefreshShape, LoadingShape } from "components/Shape";
|
||||
import { PlayIcon, PauseIcon, RefreshIcon, StalledIcon } from "components/Icon";
|
||||
import * as Quran from "lib/Quran";
|
||||
import { i18n, TFunction } from "lib/i18n";
|
||||
|
||||
|
@ -86,10 +86,10 @@ function SurahStream({ node, recitations, locale, paused, t }: Props) {
|
|||
)}
|
||||
<div className={classNames({ "justify-end": endOfStream }, "row", "footer")}>
|
||||
{readyToRender && isPaused && !endOfStream && (
|
||||
<PlayShape onClick={() => setIsPaused(false)} />
|
||||
<PlayIcon onClick={() => setIsPaused(false)} />
|
||||
)}
|
||||
{readyToRender && !isPaused && !endOfStream && (
|
||||
<PauseShape onClick={() => setIsPaused(true)} />
|
||||
<PauseIcon onClick={() => setIsPaused(true)} />
|
||||
)}
|
||||
{readyToRender && !endOfStream && (
|
||||
<AudioControl
|
||||
|
@ -114,11 +114,11 @@ function SurahStream({ node, recitations, locale, paused, t }: Props) {
|
|||
isStalled={isStalled}
|
||||
/>
|
||||
)}
|
||||
{readyToRender && endOfStream && <RefreshShape onClick={() => setStream([])} />}
|
||||
{readyToRender && endOfStream && <RefreshIcon onClick={() => setStream([])} />}
|
||||
</div>
|
||||
{readyToRender && soundOn && isStalled && (
|
||||
<div className="row spinner justify-end">
|
||||
<LoadingShape />
|
||||
<StalledIcon />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue