footer setting

demo
taha12322 3 years ago
parent 42b3ae6602
commit e5adef5f51
  1. 20
      src/components/style/footerStyle.scss
  2. 305
      src/containers/Footer.tsx
  3. 11
      src/containers/Header.tsx
  4. 15
      src/containers/Reader.tsx
  5. 82
      src/containers/menu/Option.tsx
  6. 4
      src/lib/svg/BookClose.js
  7. 4
      src/lib/svg/BookOpen.js
  8. 6
      src/lib/svg/ScrollVertical.js
  9. 197
      src/slices/book.ts

@ -19,8 +19,14 @@
align-items: center; align-items: center;
margin-bottom: 5px; margin-bottom: 5px;
.icon{ .icon{
width: 25px; width: 30px;
margin-left: 1rem; padding: 4px 5px;
margin-left: 0.25rem;
cursor: pointer;
}
.active{
border-radius: 7px;
background-color: #009aa8;
} }
} }
} }
@ -31,14 +37,4 @@
} }
.active{
border-radius: 20%;
width: 65px;
background-color: #009aa873;
}
.icon{
width: 65px;
}

@ -18,59 +18,73 @@ import "../components/style/footerStyle.scss";
const Footer = ({ const Footer = ({
// title, // title,
nowPage, nowPage,
totalPage, // totalPage,
viewType, //viewType,
// onPageMove, // // onPageMove,
CountPage, // CountPage,
onClickDirection, // onClickDirection,
onClickViewType, // onClickViewType,
onBookOptionChange, onBookOptionChange,
bookOption, bookOption,
}: Props) => { }: Props) => {
//scroll onepage //desctop setting
//noscoroll onepage const [mode, setdesctopIsActive] = useState(2);
//noscroll twopage //desctop fnc
const desctopTwoPageHandler = () => {
const [scrollToggle, setScrollToggle] = useState(false); setdesctopIsActive(2);
onBookOptionChange({
// const [settingIcons, setSettingIcons] = useState({ ...bookOption,
// scroll: 0, flow: "paginated",
// onePage: 0, spread: "auto",
// twoPage: 0, });
// noscroll: 0, };
// }); const desctopSinglePageHandler = () => {
setdesctopIsActive(1);
// const changeActiveHandler = () => { onBookOptionChange({
// if (toggleIcon === 1) { ...bookOption,
// setSettingIcons({ flow: "paginated",
// ...settingIcons, spread: "none",
// noscroll: 1, });
// }); };
// } else if (toggleIcon === 2) { const desctopScrollPageHandler = () => {
// setSettingIcons({ setdesctopIsActive(0);
// ...settingIcons, onBookOptionChange({
// scroll: 1, ...bookOption,
// }); flow: "scrolled-doc",
// } spread: "none",
// }; });
};
// const [active, setActive] = useState(1);
// const [toggleIcon, setToggleIcon] = useState(false); //mobile fnc
// const onToggle = () => { const mobilePageHandler = () => {
// if (active === 1 || 2) { setdesctopIsActive(1);
// setActive(3); onBookOptionChange({
// } ...bookOption,
// setToggleIcon(false); flow: "paginated",
// }; spread: "none",
let isMobile = window.innerWidth <= 768 });
};
const mobileScrollPageHandler = () => {
setdesctopIsActive(0);
onBookOptionChange({
...bookOption,
flow: "scrolled-doc",
spread: "none",
});
};
let isMobile = window.innerWidth <= 768;
const color = {
notactive: "#221",
active: "#fff",
};
return ( return (
<nav className="nav-footer" <nav
// style={{display: isMobile?"":"flex" }} className="nav-footer"
// style={{display: isMobile?"":"flex" }}
> >
<nav className="footer-item"> <nav className="footer-item">
<> <>
<nav className="nav-footer-item" id="toggler"> <nav className="nav-footer-item" id="toggler">
<Item text={`${nowPage} / ${101}`} /> <Item text={`${nowPage} / ${101}`} />
</nav> </nav>
@ -78,57 +92,108 @@ const Footer = ({
<ProgressBar value={nowPage} max={100} /> <ProgressBar value={nowPage} max={100} />
</nav> </nav>
{isMobile ? ( {isMobile ? (
// --------- Mobile
<> <>
<nav className="icon" > <nav
<BookCloseIcon onClick={() => onBookOptionChange({ onClick={mobilePageHandler}
...bookOption, className={`icon ${mode >= 1 ? "active" : ""} ms-3`}
flow: "scrolled-doc", >
}) <BookCloseIcon
} color={mode >= 1 ? color.active : color.notactive}
onClick={() =>
onBookOptionChange({
...bookOption,
flow: "scrolled-doc",
})
}
/> />
</nav> </nav>
<nav className="icon" > <nav
<ScrollVerticalIcon onClick={() => onBookOptionChange({ onClick={() => mobileScrollPageHandler()}
...bookOption, className={`icon ${mode == 0 ? "active" : ""}`}
flow: "paginated" >
}) <ScrollVerticalIcon
} color={mode == 0 ? color.active : color.notactive}
/> />
</nav> </nav>
</> </>
) : ( ) : (
// --------- Desctop
<> <>
<nav className="icon" > <nav
<BookOpenIcon onClick={() => onBookOptionChange({ onClick={desctopTwoPageHandler}
...bookOption, className={`icon ${mode === 2 ? "active" : ""} ms-3`}
flow: "paginated" >
}) <BookOpenIcon
} color={mode === 2 ? color.active : color.notactive}
/> />
</nav> </nav>
<nav className="icon" > <nav
<BookCloseIcon onClick={() => onBookOptionChange({ onClick={desctopSinglePageHandler}
...bookOption, className={`icon ${mode === 1 ? "active" : ""}`}
flow: "paginated" >
}) <BookCloseIcon
} color={mode === 1 ? color.active : color.notactive}
/> />
</nav> </nav>
<nav className="icon" > <nav
<ScrollVerticalIcon onClick={() => onBookOptionChange({ onClick={desctopScrollPageHandler}
...bookOption, className={`icon ${mode === 0 ? "active" : ""}`}
flow: "paginated" >
}) <ScrollVerticalIcon
} color={mode === 0 ? color.active : color.notactive}
/> />
</nav> </nav>
</>
)}
</>
</nav>
<Button>خرید کتاب</Button>
</nav>
);
};
const Button = styled.button`
width: 100%;
height: 35px;
display: flex;
justify-content: center;
align-items: center;
padding: 2px 2rem;
color: #fff;
font-family: inherit;
background-color: rgb(0, 154, 168);
`;
interface Props {
onBookOptionChange: any;
onClickViewType: any;
onClickDirection: any;
title: string;
nowPage: number;
totalPage: number;
CountPage: number;
bookOption: any;
viewType: any;
color?: any;
onPageMove: (type: "PREV" | "NEXT") => void;
}
export default Footer;
// const WrapperBtn = styled.div`
// position: fixed;
// left: 0;
// top: 60px;
// width: 100%;
// height: 100%;
// display: flex;
// align-items: center;
// justify-content: space-between;
// `;
{/* <nav className="nav-icon"> {
/* <nav className="nav-icon">
<div className="display-icon" style={{ cursor: "pointer" }}> <div className="display-icon" style={{ cursor: "pointer" }}>
<nav <nav
@ -183,53 +248,35 @@ const Footer = ({
</div> </div>
</nav> </nav>
*/} </> */
)}
</>
</nav>
{isMobile ? <Button>خرید کتاب</Button> : null}
</nav>
);
};
const Button = styled.button`
width: 100%;
height: 35px;
display: flex;
justify-content: center;
align-items: center;
padding: 2px 2rem;
color: #fff;
font-family: inherit;
background-color: rgb(0, 154, 168);
`;
interface Props {
onBookOptionChange: any;
onClickViewType: any;
onClickDirection: any;
title: string;
nowPage: number;
totalPage: number;
CountPage: number;
bookOption: any;
viewType: any;
onPageMove: (type: "PREV" | "NEXT") => void;
} }
export default Footer; // const [settingIcons, setSettingIcons] = useState({
// scroll: 0,
// onePage: 0,
// twoPage: 0,
// noscroll: 0,
// });
// const WrapperBtn = styled.div` // const changeActiveHandler = () => {
// position: fixed; // if (toggleIcon === 1) {
// left: 0; // setSettingIcons({
// top: 60px; // ...settingIcons,
// width: 100%; // noscroll: 1,
// height: 100%; // });
// display: flex; // } else if (toggleIcon === 2) {
// align-items: center; // setSettingIcons({
// justify-content: space-between; // ...settingIcons,
// `; // scroll: 1,
// });
// }
// };
// const [active, setActive] = useState(1);
// const [toggleIcon, setToggleIcon] = useState(false);
// const onToggle = () => {
// if (active === 1 || 2) {
// setActive(3);
// }
// setToggleIcon(false);
// };

@ -36,9 +36,6 @@ const Header = ({
onClick={onLearningToggle as any} onClick={onLearningToggle as any}
/> />
</nav> </nav>
<nav>
{window.innerWidth > 768 ? <ButtonB>خرید کتاب</ButtonB> : null}
</nav>
<nav <nav
style={{ style={{
display: "flex", display: "flex",
@ -47,10 +44,14 @@ const Header = ({
}} }}
> >
<Item text={title as any} /> <Item text={title as any} />
<span style={{ color: "#fff", marginRight: "10px" }}>|</span> <span style={{ color: "#fff", marginRight: "10px" }}>
{title ? "|" : ""}
</span>
{/* <BookInfo/> */} {/* <BookInfo/> */}
<div> <div>
<p style={{ margin: "0", color: "#fff" , width: '85px' }}>{nameBook}</p> <p style={{ margin: "0", color: "#fff", width: "85px" }}>
{nameBook}
</p>
</div> </div>
<Logo /> <Logo />
<Img <Img

@ -63,7 +63,7 @@ const Reader = ({ url, loadingView }: Props) => {
resizeOnOrientationChange: true, resizeOnOrientationChange: true,
spread: "auto", spread: "auto",
}); });
const [pPage, setpPage] = useState(0);
const [navControl, onNavToggle] = useMenu(navRef, 300); const [navControl, onNavToggle] = useMenu(navRef, 300);
const [optionControl, onOptionToggle, emitEvent] = useMenu(optionRef, 300); const [optionControl, onOptionToggle, emitEvent] = useMenu(optionRef, 300);
const [learningControl, onLearningToggle] = useMenu(learningRef, 300); const [learningControl, onLearningToggle] = useMenu(learningRef, 300);
@ -105,6 +105,7 @@ const Reader = ({ url, loadingView }: Props) => {
* @param loc epubCFI or href * @param loc epubCFI or href
*/ */
const onLocationChange = (loc: string) => { const onLocationChange = (loc: string) => {
//console.log("onLocationChange", currentLocation);
if (!viewerRef.current) return; if (!viewerRef.current) return;
viewerRef.current.setLocation(loc); viewerRef.current.setLocation(loc);
}; };
@ -116,7 +117,12 @@ const Reader = ({ url, loadingView }: Props) => {
const onPageMove = (type: "NEXT" | "PREV") => { const onPageMove = (type: "NEXT" | "PREV") => {
//loadFont(); //loadFont();
const node = viewerRef.current; const node = viewerRef.current;
if (!node || !node.prevPage || !node.nextPage) return; if (!node || !node.prevPage || !node.nextPage) {
// console.log("no page found");
return;
}
//console.log("onPageMove", type, currentLocation);
//setpPage(currentLocation.currentPage)
type === "NEXT" && node.nextPage(); type === "NEXT" && node.nextPage();
type === "PREV" && node.prevPage(); type === "PREV" && node.prevPage();
@ -148,7 +154,10 @@ const Reader = ({ url, loadingView }: Props) => {
* Change current page * Change current page
* @param page Epub page * @param page Epub page
*/ */
const onPageChange = (page: Page) => dispatch(updateCurrentPage(page)); const onPageChange = (page: Page) => {
// console.log("onPageChange:", currentLocation, page.currentPage);
dispatch(updateCurrentPage(page));
};
/** /**
* ContextMenu on * ContextMenu on

@ -11,9 +11,9 @@ import ControlIconBtn from "components/option/ControlIconBtn";
import { BookStyle, BookFontFamily, BookFlow } from "types/book"; import { BookStyle, BookFontFamily, BookFlow } from "types/book";
import { MenuControl } from "lib/hooks/useMenu"; import { MenuControl } from "lib/hooks/useMenu";
import { BookOption } from "types/book"; import { BookOption } from "types/book";
import * as styles from "lib/styles/styles"; // import * as styles from "lib/styles/styles";
// import palette from 'lib/styles/palette' // import palette from 'lib/styles/palette'
import styled from "styled-components"; // import styled from "styled-components";
// import Setting from "components/Setting/setting"; // import Setting from "components/Setting/setting";
@ -253,50 +253,50 @@ interface Props {
onBookOptionChange: (bookOption: BookOption) => void; onBookOptionChange: (bookOption: BookOption) => void;
} }
const Btn = styled.button` // const Btn = styled.button`
position: relative; // position: relative;
height: 100%; // height: 100%;
padding: 0 12px; // padding: 0 12px;
dispayl: flex; // dispayl: flex;
align-items: center; // align-items: center;
justify-content: center; // justify-content: center;
z-index: 0; // z-index: 0;
transition: 0.3s ${styles.transition}; // transition: 0.3s ${styles.transition};
outline: none; // outline: none;
&::before { // &::before {
content: ""; // content: "";
position: absolute; // position: absolute;
left: 0; // left: 0;
right: 0; // right: 0;
top: 0; // top: 0;
bottom: 0; // bottom: 0;
margin: auto; // margin: auto;
z-index: -1; // z-index: -1;
border-radius: 30px; // border-radius: 30px;
transition: 0.1s ${styles.transition}; // transition: 0.1s ${styles.transition};
background-color: rgb(0, 154, 168); // background-color: rgb(0, 154, 168);
} // }
`; // `;
const BtnWrapper = styled.div` // const BtnWrapper = styled.div`
display: flex; // display: flex;
align-items: center; // align-items: center;
justify-content: space-around; // justify-content: space-around;
padding: 8px 0; // padding: 8px 0;
`; // `;
const OptionTitle = styled.div` // const OptionTitle = styled.div`
font-size: 14px; // font-size: 14px;
font-weight: 500; // font-weight: 500;
margin-bottom: 16px; // margin-bottom: 16px;
`; // `;
type SliderType = type SliderType =
| "FontSize" | "FontSize"
| "LineHeight" | "LineHeight"
| "MarginHorizontal" | "MarginHorizontal"
| "MarginVertical"; | "MarginVertical";
type ViewType = { // type ViewType = {
active: boolean; // active: boolean;
spread: boolean; // spread: boolean;
}; // };
export default React.forwardRef(Option); export default React.forwardRef(Option);

@ -1,12 +1,12 @@
import * as React from "react"; import * as React from "react";
function SvgBookClose(props) { function SvgBookClose(color,props) {
return ( return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}>
<defs> <defs>
<style> <style>
{ {
".bookClose_svg__cls-3{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}" `.bookClose_svg__cls-3{fill:none;stroke:${color.color};stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}`
} }
</style> </style>
</defs> </defs>

@ -1,12 +1,12 @@
import * as React from "react"; import * as React from "react";
function SvgBookOpen(props) { function SvgBookOpen(color,props) {
return ( return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}>
<defs> <defs>
<style> <style>
{ {
".bookOpen_svg__cls-3{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}" `.bookOpen_svg__cls-3{fill:none;stroke:${color.color};stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}`
} }
</style> </style>
</defs> </defs>

@ -1,13 +1,11 @@
import * as React from "react"; import * as React from "react";
function SvgScrollVertical(props) { function SvgScrollVertical(color, props) {
return ( return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" {...props}>
<defs> <defs>
<style> <style>
{ {`.scrollVertical_svg__cls-3{fill:none;stroke:${color.color};stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}`}
".scrollVertical_svg__cls-3{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px}"
}
</style> </style>
</defs> </defs>
<g <g

@ -1,12 +1,11 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// types // types
import Book from 'types/book' import Book from "types/book";
import Page from 'types/page' import Page from "types/page";
import Toc from 'types/toc' import Toc from "types/toc";
import Highlight, { Color } from 'types/highlight' import Highlight, { Color } from "types/highlight";
// lib // lib
import palette from 'lib/styles/palette' import palette from "lib/styles/palette";
/* /*
Initial State Initial State
@ -14,110 +13,120 @@ import palette from 'lib/styles/palette'
/** 초기 Book 상태 */ /** 초기 Book 상태 */
const initialBook: Book = { const initialBook: Book = {
coverURL: '', coverURL: "",
title: '', title: "",
description: '', description: "",
published_date: '', published_date: "",
modified_date: '', modified_date: "",
author: '', author: "",
publisher: '', publisher: "",
language: '' language: "",
} };
/** 초기 CurrentPage 상태 */ /** 초기 CurrentPage 상태 */
const initialCurrentLocation: Page = { const initialCurrentLocation: Page = {
chapterName: "-", chapterName: "-",
currentPage: 0, currentPage: 0,
totalPage: 0, totalPage: 0,
startCfi: '', startCfi: "",
endCfi: '', endCfi: "",
base: '' base: "",
} };
/** 초기 색상표 상태 */ /** 초기 색상표 상태 */
const initialColorList: Color[] = [ const initialColorList: Color[] = [
{ name: 'قرمز', code: palette.red4 }, { name: "قرمز", code: palette.red4 },
{ name: 'نارنجی', code: palette.orange4 }, { name: "نارنجی", code: palette.orange4 },
{ name: 'زرد', code: palette.yellow4 }, { name: "زرد", code: palette.yellow4 },
{ name: 'سبز', code: palette.green4 }, { name: "سبز", code: palette.green4 },
{ name: 'آبی', code: palette.blue4 }, { name: "آبی", code: palette.blue4 },
{ name: 'بنفش', code: palette.purple4 } { name: "بنفش", code: palette.purple4 },
] ];
const initialState: BookState = { const initialState: BookState = {
book: initialBook, book: initialBook,
currentLocation: initialCurrentLocation, currentLocation: initialCurrentLocation,
toc: [], toc: [],
highlights: [], highlights: [],
colorList: initialColorList, colorList: initialColorList,
} };
/* /*
Slice Slice
*/ */
const bookSlice = createSlice({ const bookSlice = createSlice({
name: 'book', name: "book",
initialState, initialState,
reducers: { reducers: {
/** Book 갱신 @dispatch */ /** Book 갱신 @dispatch */
updateBook(state, action: PayloadAction<Book>) { updateBook(state, action: PayloadAction<Book>) {
state.book = action.payload; state.book = action.payload;
}, },
/** CurrentPage 갱신 @dispatch */ /** CurrentPage 갱신 @dispatch */
updateCurrentPage(state, action: PayloadAction<Page>) { updateCurrentPage(state, action: PayloadAction<Page>) {
state.currentLocation = action.payload; if (
}, state.currentLocation.currentPage == action.payload.currentPage &&
/** Book 초기화 @dispatch */ action.payload.chapterName
clearBook(state) { ) {
state.book = initialBook; console.log(JSON.parse(JSON.stringify(state)));
}, // let c = current(state)
/** 목차 갱신 @dispatch */ // let x = [...c.toc];
updateToc(state, action: PayloadAction<Toc[]>) { // console.log(x[1]);
state.toc = action.payload; alert("فصل بعد");
}, }
/** 목차 초기화 @dispatch */ state.currentLocation = action.payload;
clearToc(state) { },
state.toc = []; /** Book 초기화 @dispatch */
}, clearBook(state) {
/** 하이라이트 추가 */ state.book = initialBook;
pushHighlight(state, action: PayloadAction<Highlight>) { },
const check = state.highlights.filter(h => h.key === action.payload.key); /** 목차 갱신 @dispatch */
if (check.length > 0) return; updateToc(state, action: PayloadAction<Toc[]>) {
state.highlights.push(action.payload); state.toc = action.payload;
}, },
/** 하이라이트 갱신 */ /** 목차 초기화 @dispatch */
updateHighlight(state, action: PayloadAction<Highlight>) { clearToc(state) {
const new_idx = action.payload.key; state.toc = [];
const old_idx = state.highlights.map(h => h.key).indexOf(new_idx); },
state.highlights.splice(old_idx, 1, action.payload); /** 하이라이트 추가 */
}, pushHighlight(state, action: PayloadAction<Highlight>) {
/** 하이라이트 삭제 */ const check = state.highlights.filter(
popHighlight(state, action: PayloadAction<string>) { (h) => h.key === action.payload.key
const idx = state.highlights.map(h => h.key).indexOf(action.payload); );
state.highlights.splice(idx, 1); if (check.length > 0) return;
} state.highlights.push(action.payload);
} },
/** 하이라이트 갱신 */
updateHighlight(state, action: PayloadAction<Highlight>) {
const new_idx = action.payload.key;
const old_idx = state.highlights.map((h) => h.key).indexOf(new_idx);
state.highlights.splice(old_idx, 1, action.payload);
},
/** 하이라이트 삭제 */
popHighlight(state, action: PayloadAction<string>) {
const idx = state.highlights.map((h) => h.key).indexOf(action.payload);
state.highlights.splice(idx, 1);
},
},
}); });
export interface BookState { export interface BookState {
book: Book; book: Book;
currentLocation: Page; currentLocation: Page;
toc: Toc[]; toc: Toc[];
highlights: Highlight[]; highlights: Highlight[];
colorList: Color[]; colorList: Color[];
} }
export const { export const {
updateBook, updateBook,
clearBook, clearBook,
updateCurrentPage, updateCurrentPage,
updateToc, updateToc,
clearToc, clearToc,
pushHighlight, pushHighlight,
updateHighlight, updateHighlight,
popHighlight popHighlight,
} = bookSlice.actions; } = bookSlice.actions;
export default bookSlice.reducer export default bookSlice.reducer;

Loading…
Cancel
Save