Ver Fonte

fix some issue

* add loading status
* fit screen when switch to edit mode
* increase default font size of free text tool
RoyLiu há 4 anos atrás
pai
commit
62870bff44

+ 25 - 31
actions/pdf.ts

@@ -1,39 +1,33 @@
 import * as types from '../constants/actionTypes';
 import {
-  ProgressType, ViewportType, AnnotationType, ActionType, WatermarkType,
+  ProgressType,
+  ViewportType,
+  AnnotationType,
+  ActionType,
+  WatermarkType,
 } from '../constants/type';
 
 const actions: ActionType = dispatch => ({
-  setTotalPage: (page: number): void => (
-    dispatch({ type: types.SET_TOTAL_PAGE, payload: page })
-  ),
-  setCurrentPage: (page: number): void => (
-    dispatch({ type: types.SET_CURRENT_PAGE, payload: page })
-  ),
-  setPdf: (pdf: Record<string, any>): void => (
-    dispatch({ type: types.SET_PDF, payload: pdf })
-  ),
-  setProgress: (progress: ProgressType): void => (
-    dispatch({ type: types.SET_PROGRESS, payload: progress })
-  ),
-  setViewport: (viewport: ViewportType): void => (
-    dispatch({ type: types.SET_VIEWPORT, payload: viewport })
-  ),
-  changeScale: (scale: number | string): void => (
-    dispatch({ type: types.CHANGE_SCALE, payload: scale })
-  ),
-  changeRotate: (rotation: number): void => (
-    dispatch({ type: types.CHANGE_ROTATE, payload: rotation })
-  ),
-  addAnnots: (annotations: AnnotationType[], init: boolean): void => (
-    dispatch({ type: types.ADD_ANNOTS, payload: { annotations, init } })
-  ),
-  updateAnnots: (annotations: AnnotationType[]): void => (
-    dispatch({ type: types.UPDATE_ANNOTS, payload: annotations })
-  ),
-  updateWatermark: (watermark: WatermarkType): void => (
-    dispatch({ type: types.UPDATE_WATERMARK, payload: watermark })
-  ),
+  setTotalPage: (page: number): void =>
+    dispatch({ type: types.SET_TOTAL_PAGE, payload: page }),
+  setCurrentPage: (page: number): void =>
+    dispatch({ type: types.SET_CURRENT_PAGE, payload: page }),
+  setPdf: (pdf: Record<string, any>): void =>
+    dispatch({ type: types.SET_PDF, payload: pdf }),
+  setProgress: (progress: ProgressType): void =>
+    dispatch({ type: types.SET_PROGRESS, payload: progress }),
+  setViewport: (viewport: ViewportType): void =>
+    dispatch({ type: types.SET_VIEWPORT, payload: viewport }),
+  changeScale: (scale: number | string): void =>
+    dispatch({ type: types.CHANGE_SCALE, payload: scale }),
+  changeRotate: (rotation: number): void =>
+    dispatch({ type: types.CHANGE_ROTATE, payload: rotation }),
+  addAnnots: (annotations: AnnotationType[], init: boolean): void =>
+    dispatch({ type: types.ADD_ANNOTS, payload: { annotations, init } }),
+  updateAnnots: (annotations: AnnotationType[]): void =>
+    dispatch({ type: types.UPDATE_ANNOTS, payload: annotations }),
+  updateWatermark: (watermark: WatermarkType): void =>
+    dispatch({ type: types.UPDATE_WATERMARK, payload: watermark }),
 });
 
 export default actions;

+ 4 - 13
components/Box/index.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 
 import { Wrapper } from './styled';
 
-const properties: {[index: string]: string} = {
+const properties: { [index: string]: string } = {
   m: 'margin',
   p: 'padding',
   d: 'display',
@@ -13,7 +13,7 @@ const properties: {[index: string]: string} = {
   h: 'height',
 };
 
-const directions: {[index: string]: string} = {
+const directions: { [index: string]: string } = {
   t: 'Top',
   r: 'Right',
   b: 'Bottom',
@@ -25,10 +25,7 @@ type Props = {
   children: React.ReactNode;
 };
 
-const Box: React.FC<Props> = ({
-  children,
-  ...rest
-}: Props) => {
+const Box: React.FC<Props> = ({ children, ...rest }: Props) => {
   const args = Object.keys(rest);
 
   if (!rest.width) {
@@ -45,13 +42,7 @@ const Box: React.FC<Props> = ({
     return `${property}: ${rest[ele]};`;
   });
 
-  return (
-    <Wrapper
-      styles={styles}
-    >
-      {children}
-    </Wrapper>
-  );
+  return <Wrapper styles={styles}>{children}</Wrapper>;
 };
 
 export default Box;

+ 3 - 1
components/Box/styled.ts

@@ -1,5 +1,7 @@
 import styled from 'styled-components';
 
-export const Wrapper = styled('div')<{styles?: string[]}>`
+export const Wrapper = styled('div')<{ styles?: string[] }>`
   ${props => props.styles}
 `;
+
+export default Wrapper;

+ 2 - 2
components/FreeText/index.tsx

@@ -27,7 +27,7 @@ const FreeText: React.SFC<AnnotationElementPropsType> = ({
 
   const handleChange = (event: React.FormEvent<HTMLInputElement>): void => {
     const textValue = event.currentTarget.value;
-    const fontWidth = textValue.length * (fontsize || 1);
+    const fontWidth = textValue.length * ((fontsize as number) * 0.9 || 1);
     const newPosition = { ...(position as PositionType) };
     newPosition.right = newPosition.left + fontWidth;
 
@@ -81,7 +81,7 @@ const FreeText: React.SFC<AnnotationElementPropsType> = ({
         top={`${annotRect.top}px`}
         left={`${annotRect.left}px`}
         width={`${annotRect.width + 2}px`}
-        height={`${annotRect.height + 4}px`}
+        height={`${annotRect.height + 8}px`}
       >
         {isEdit ? (
           <Input

+ 1 - 1
components/FreeText/styled.ts

@@ -14,6 +14,6 @@ export const Input = styled.input`
   margin: 0;
   width: 95%;
   outline: none;
-  height: 93%;
+  height: 94%;
   display: inline-block;
 `;

+ 34 - 29
components/PdfSkeleton/index.tsx

@@ -1,41 +1,46 @@
 import React from 'react';
+import { useTranslation } from 'react-i18next';
 
 import Box from '../Box';
 import Skeleton from '../Skeleton';
 
-import { Container } from './styled';
+import { Container, Text } from './styled';
 
-const PdfSkeleton: React.FC = () => (
-  <Container>
-    <Skeleton variant="rect" width="50%" height="36px" />
-    <Skeleton variant="rect" width="45%" height="12px" />
-    <Skeleton variant="rect" width="40%" height="12px" />
+const PdfSkeleton: React.SFC = () => {
+  const { t } = useTranslation('toast');
+  return (
+    <Container>
+      <Skeleton variant="rect" width="50%" height="36px" />
+      <Skeleton variant="rect" width="45%" height="12px" />
+      <Skeleton variant="rect" width="40%" height="12px" />
 
-    <Box mt="30">
-      <Skeleton variant="rect" width="100%" height="14px" />
-      <Skeleton variant="rect" width="100%" height="14px" />
-      <Skeleton variant="rect" width="100%" height="14px" />
-      <Skeleton variant="rect" width="90%" height="14px" />
-    </Box>
+      <Box mt="30">
+        <Skeleton variant="rect" width="100%" height="14px" />
+        <Skeleton variant="rect" width="100%" height="14px" />
+        <Skeleton variant="rect" width="100%" height="14px" />
+        <Skeleton variant="rect" width="90%" height="14px" />
+      </Box>
 
-    <Box mt="5" d="flex">
-      <Skeleton variant="rect" width="100%" height="120px" />
-      <Box ml="15">
-        <Skeleton variant="rect" width="70%" height="16px" />
-        <Skeleton variant="rect" width="100%" height="12px" />
-        <Skeleton variant="rect" width="100%" height="12px" />
-        <Skeleton variant="rect" width="100%" height="12px" />
-        <Skeleton variant="rect" width="80%" height="12px" />
+      <Box mt="5" d="flex">
+        <Skeleton variant="rect" width="100%" height="120px" />
+        <Box ml="15">
+          <Skeleton variant="rect" width="70%" height="16px" />
+          <Skeleton variant="rect" width="100%" height="12px" />
+          <Skeleton variant="rect" width="100%" height="12px" />
+          <Skeleton variant="rect" width="100%" height="12px" />
+          <Skeleton variant="rect" width="80%" height="12px" />
+        </Box>
       </Box>
-    </Box>
 
-    <Box mt="15">
-      <Skeleton variant="rect" width="100%" height="14px" />
-      <Skeleton variant="rect" width="100%" height="14px" />
-      <Skeleton variant="rect" width="90%" height="14px" />
-      <Skeleton variant="rect" width="85%" height="14px" />
-    </Box>
-  </Container>
-);
+      <Box mt="15">
+        <Skeleton variant="rect" width="100%" height="14px" />
+        <Skeleton variant="rect" width="100%" height="14px" />
+        <Skeleton variant="rect" width="90%" height="14px" />
+        <Skeleton variant="rect" width="85%" height="14px" />
+      </Box>
+      <Text>{t('processing')}</Text>
+    </Container>
+  );
+};
 
 export default PdfSkeleton;

+ 11 - 0
components/PdfSkeleton/styled.ts

@@ -15,3 +15,14 @@ export const Container = styled.div`
   flex-direction: column;
   z-index: 1;
 `;
+
+export const Text = styled.p`
+  text-align: center;
+  font-size: 16px;
+  color: #757575;
+`;
+
+export default {
+  Container,
+  Text,
+};

+ 26 - 30
components/SelectBox/index.tsx

@@ -79,7 +79,8 @@ const SelectBox: React.FC<Props> = ({
     if (!isCollapse && selectRef.current) {
       const position = selectRef.current.getBoundingClientRect();
       if (optionRef.current) {
-        optionRef.current.style.top = `${selectRef.current.clientHeight + position.top}px`;
+        optionRef.current.style.top = `${selectRef.current.clientHeight +
+          position.top}px`;
         optionRef.current.style.left = `${position.left}px`;
       }
     }
@@ -94,38 +95,33 @@ const SelectBox: React.FC<Props> = ({
         tabIndex={0}
         data-testid="selected"
       >
-        {
-          useInput && (typeof value === 'string' || typeof value === 'number') ? (
-            <InputContent
-              value={value}
-              onChange={handleChange}
-              onKeyDown={handleKeyDown}
-            />
-          ) : (
-            <Content>
-              {value}
-            </Content>
-          )
-        }
+        {useInput &&
+        (typeof value === 'string' || typeof value === 'number') ? (
+          <InputContent
+            value={value}
+            onChange={handleChange}
+            onKeyDown={handleKeyDown}
+          />
+        ) : (
+          <Content>{value}</Content>
+        )}
         {isDivide ? <Divider /> : null}
         <Icon glyph="down-arrow" />
       </Selected>
-      {
-        !isCollapse ? (
-          <OptionWrapper ref={optionRef} data-testid="option-list">
-            {
-              options.map((option: SelectOptionType, index: number) => (
-                <Option
-                  key={option.key}
-                  onMouseDown={(): void => { handleSelect(index); }}
-                >
-                  {option.content}
-                </Option>
-              ))
-            }
-          </OptionWrapper>
-        ) : null
-      }
+      {!isCollapse ? (
+        <OptionWrapper ref={optionRef} data-testid="option-list">
+          {options.map((option: SelectOptionType, index: number) => (
+            <Option
+              key={option.key}
+              onMouseDown={(): void => {
+                handleSelect(index);
+              }}
+            >
+              {option.content}
+            </Option>
+          ))}
+        </OptionWrapper>
+      ) : null}
     </Container>
   );
 };

+ 49 - 15
components/Toolbar/index.tsx

@@ -51,9 +51,11 @@ const Toolbar: React.FC<Props> = ({
     changeRotate(r);
   };
 
-  const handleScaleSelect = async (selected: SelectOptionType): Promise<any> => {
+  const handleScaleSelect = async (
+    selected: SelectOptionType
+  ): Promise<any> => {
     if (selected.child === 'fit') {
-      const screenWidth = window.document.body.offsetWidth - 276;
+      const screenWidth = window.document.body.offsetWidth - 288;
       const originPdfWidth = viewport.width / scale;
       const rate = screenWidth / originPdfWidth;
       changeScale(rate);
@@ -73,11 +75,27 @@ const Toolbar: React.FC<Props> = ({
   return (
     <>
       <Container isHidden={displayMode === 'full'}>
-        <Pagination totalPage={totalPage} currentPage={currentPage} onChange={setCurrentPage} />
+        <Pagination
+          totalPage={totalPage}
+          currentPage={currentPage}
+          onChange={setCurrentPage}
+        />
         <Divider />
-        <Icon glyph="hand" style={{ width: '30px' }} onClick={handleHandClick} />
-        <Icon glyph="zoom-in" style={{ width: '30px' }} onClick={handleZoomIn} />
-        <Icon glyph="zoom-out" style={{ width: '30px' }} onClick={handleZoomOut} />
+        <Icon
+          glyph="hand"
+          style={{ width: '30px' }}
+          onClick={handleHandClick}
+        />
+        <Icon
+          glyph="zoom-in"
+          style={{ width: '30px' }}
+          onClick={handleZoomIn}
+        />
+        <Icon
+          glyph="zoom-out"
+          style={{ width: '30px' }}
+          onClick={handleZoomOut}
+        />
         <SelectBox
           options={data.scaleOptions}
           style={{ width: '94px' }}
@@ -87,17 +105,33 @@ const Toolbar: React.FC<Props> = ({
           defaultValue={`${Math.round(scale * 100)} %`}
         />
         <Divider />
-        <Icon glyph="rotate-left" style={{ width: '30px' }} onClick={handleCounterclockwiseRotation} />
-        <Icon glyph="rotate-right" style={{ width: '30px' }} onClick={handleClockwiseRotation} />
+        <Icon
+          glyph="rotate-left"
+          style={{ width: '30px' }}
+          onClick={handleCounterclockwiseRotation}
+        />
+        <Icon
+          glyph="rotate-right"
+          style={{ width: '30px' }}
+          onClick={handleClockwiseRotation}
+        />
       </Container>
       <ToggleButton>
-        {
-          displayMode === 'normal' ? (
-            <Icon glyph="tool-close" onClick={(): void => { toggleDisplayMode('full'); }} />
-          ) : (
-            <Icon glyph="tool-open" onClick={(): void => { toggleDisplayMode('normal'); }} />
-          )
-        }
+        {displayMode === 'normal' ? (
+          <Icon
+            glyph="tool-close"
+            onClick={(): void => {
+              toggleDisplayMode('full');
+            }}
+          />
+        ) : (
+          <Icon
+            glyph="tool-open"
+            onClick={(): void => {
+              toggleDisplayMode('normal');
+            }}
+          />
+        )}
       </ToggleButton>
     </>
   );

+ 2 - 2
containers/FreeTextTools.tsx

@@ -25,7 +25,7 @@ const HighlightTools: React.FC<Props> = ({
 }: Props) => {
   const [data, setData] = useState({
     fontName: 'Helvetica',
-    fontSize: 12,
+    fontSize: 18,
     align: 'left',
     fontStyle: '',
     color: '#FCFF36',
@@ -64,7 +64,7 @@ const HighlightTools: React.FC<Props> = ({
         position: {
           top: coordinate.y,
           left: coordinate.x,
-          bottom: coordinate.y + fontSize,
+          bottom: coordinate.y + fontSize * scale,
           right: coordinate.x + 30,
         },
         transparency: opacity,

+ 4 - 0
custom.d.ts

@@ -2,3 +2,7 @@ declare module '*.svg' {
   const content: string;
   export default content;
 }
+
+declare module 'query-string';
+declare module 'react-toast-notifications';
+declare module 'react-color';

+ 16 - 8
global/otherStyled.ts

@@ -4,7 +4,7 @@ export const Separator = styled.div`
   flex: 1 1 auto;
 `;
 
-export const SidebarWrapper = styled('div')<{isHidden: boolean}>`
+export const SidebarWrapper = styled('div')<{ isHidden: boolean }>`
   position: fixed;
   top: 60px;
   bottom: 0px;
@@ -15,18 +15,26 @@ export const SidebarWrapper = styled('div')<{isHidden: boolean}>`
 
   transition: left 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
 
-  ${props => (props.isHidden ? css`
-    left: -267px;
-  ` : css`
-    left: 0;
-  `)}
+  ${props =>
+    props.isHidden
+      ? css`
+          left: -267px;
+        `
+      : css`
+          left: 0;
+        `}
 `;
 
-export const AnnotationContainer = styled('div')<{top: string; left: string; width: string; height: string}>`
+export const AnnotationContainer = styled('div')<{
+  top: string;
+  left: string;
+  width: string;
+  height: string;
+}>`
   position: absolute;
   overflow: hidden;
   cursor: pointer;
-  
+
   ${props => css`
     top: ${props.top};
     left: ${props.left};

+ 0 - 3
modules.d.ts

@@ -1,3 +0,0 @@
-declare module 'query-string';
-declare module 'react-toast-notifications';
-declare module 'react-color';

+ 2 - 4
pages/_app.js

@@ -5,12 +5,10 @@ import { StoreProvider } from '../store';
 
 import '../i18n';
 import { GlobalStyle } from '../global/styled';
+
 class MainApp extends App {
   render() {
-    const {
-      Component,
-      pageProps,
-    } = this.props;
+    const { Component, pageProps } = this.props;
 
     return (
       <StoreProvider>

+ 2 - 1
public/static/locales/en/toast.json

@@ -1,4 +1,5 @@
 {
   "saving": "Saving...",
-  "saved": "Saved"
+  "saved": "Saved",
+  "processing": "Processing..."
 }

+ 2 - 1
public/static/locales/zh-tw/toast.json

@@ -1,4 +1,5 @@
 {
   "saving": "儲存中...",
-  "saved": "儲存成功"
+  "saved": "儲存成功",
+  "processing": "處理中..."
 }

+ 4 - 1
reducers/middleware/index.ts

@@ -19,7 +19,10 @@ const applyMiddleware = (state: any, dispatch: Dispatch<any>) => (action: {
         const rate = (screenWidth / originPdfWidth).toFixed(2);
         dispatch({ type: CHANGE_SCALE, payload: rate });
       } else {
-        dispatch({ type: CHANGE_SCALE, payload: 1 });
+        const screenWidth = window.document.body.offsetWidth - 288;
+        const originPdfWidth = state.viewport.width / state.scale;
+        const rate = screenWidth / originPdfWidth;
+        dispatch({ type: CHANGE_SCALE, payload: rate });
       }
       break;
     }