From 1e3baa0ac4512ee859aa685c38f0ff3d4e8cca71 Mon Sep 17 00:00:00 2001 From: {Shore} <{kisidakazuyuki@gmail.com}> Date: Wed, 15 Nov 2023 14:15:59 +0900 Subject: [PATCH 1/7] save --- src/features/commands/TestCommand.ts | 8 ++++++++ src/features/commands/UnRedoCommand.ts | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/features/commands/TestCommand.ts create mode 100644 src/features/commands/UnRedoCommand.ts diff --git a/src/features/commands/TestCommand.ts b/src/features/commands/TestCommand.ts new file mode 100644 index 0000000..321d264 --- /dev/null +++ b/src/features/commands/TestCommand.ts @@ -0,0 +1,8 @@ +import { AbstractCommand } from 'react-command-lib/dist/esm'; + +export default class TestCommand implements AbstractCommand { + constructor() {} + execute(): void {} + undo(): void {} +} +// context.executor.execute(new TestCommand()); diff --git a/src/features/commands/UnRedoCommand.ts b/src/features/commands/UnRedoCommand.ts new file mode 100644 index 0000000..cade431 --- /dev/null +++ b/src/features/commands/UnRedoCommand.ts @@ -0,0 +1,15 @@ +import { AbstractCommand } from 'react-command-lib/dist/esm'; + +export default class UnRedoCommand implements AbstractCommand { + constructor(cssSelector: string, cssKey: string, id: string) { + this.cssSelector = cssSelector; + this.cssKey = cssKey; + this.id = id; + } + cssSelector: string; + cssKey: string; + id: string; + index: number | undefined; + execute(): void {} + undo(): void {} +} From 97f13ad80327b9f7c250fc429f7121d4358114bc Mon Sep 17 00:00:00 2001 From: {Shore} <{kisidakazuyuki@gmail.com}> Date: Wed, 15 Nov 2023 14:53:19 +0900 Subject: [PATCH 2/7] save --- src/components/Base.tsx | 23 ++-- src/components/ToolBar.tsx | 20 +++- src/contexts/PropsContext.ts | 49 ++++++--- src/features/commands/UnRedoCommand.ts | 12 +- src/hooks/useFormatUtils.ts | 146 ++++++++++++++----------- 5 files changed, 159 insertions(+), 91 deletions(-) diff --git a/src/components/Base.tsx b/src/components/Base.tsx index e515835..e92e9ac 100644 --- a/src/components/Base.tsx +++ b/src/components/Base.tsx @@ -26,7 +26,7 @@ import Scrollable from './tabitems/common/Scrollable'; import LayerCustomizer from './tabitems/layer/LayerCustomizer'; import { UIUpdaterContext, useUIUpdater } from '../contexts/UIUpdater'; import t from '../features/translator'; -import usePropsContext, { PropsContext } from '../contexts/PropsContext'; +import usePropsContext, { IPropsContext } from '../contexts/PropsContext'; const Wrapper = styled.div` width: 100%; @@ -69,7 +69,8 @@ const Base = ({}: /* categoryMap */ BaseProps) => { const elementSelection = useElementSelectionContext(); const updater = useUIUpdater(); const props = usePropsContext(); - const [fontPermissionGranted, setFontPermissionGranted] = useState(true); + const [fontPermissionGranted, setFontPermissionGranted] = + useState(true); const onChange = (key: string, value: string, id: number | string) => { if (elementSelection.selectedElement) { @@ -121,7 +122,7 @@ const Base = ({}: /* categoryMap */ BaseProps) => { } catch { setFontPermissionGranted(false); } - } + }; useEffect(() => { (async () => { @@ -135,19 +136,23 @@ const Base = ({}: /* categoryMap */ BaseProps) => { - { fontPermissionGranted && + {fontPermissionGranted && ( - } - { !fontPermissionGranted && + )} + {!fontPermissionGranted && ( <> - {t('need_to_grant_for_access_local_font')} - + + {t('need_to_grant_for_access_local_font')} + + - } + )} diff --git a/src/components/ToolBar.tsx b/src/components/ToolBar.tsx index e96bd5e..ac4de5b 100644 --- a/src/components/ToolBar.tsx +++ b/src/components/ToolBar.tsx @@ -14,7 +14,7 @@ import { } from '../features/root_manager'; import { pseudoClassOptions } from '../consts/menu'; import { ElementSelectionContext } from '../contexts/ElementSelectionContext'; -import { PropsContext } from '../contexts/PropsContext'; +import { IPropsContext } from '../contexts/PropsContext'; const Wrapper = styled.div` display: flex; @@ -73,18 +73,30 @@ const ToolBar = () => { type="ghost" size={'small'} disabled={!context.executor.isUndoable} - icon={} + icon={ + + } onClick={context.executor.undo} /> - , - , - ]} - > - - { style.author && {style.author}} - {t('open_style_link')} - - } - /> - - ))} - - ); -}; - -const ImportedStylesList = () => { - const [styles, setStyles] = useState([]); - - const onOpenStoreClick = () => { - window.open('https://resta-frontend.pages.dev/style/', '_blank'); - }; - - const updateTree = async () => { - const styles = getImportedFormats(); - setStyles(styles); - } - - useEffect(() => { - void updateTree(); - }, []); - - return ( - - {styles.length !== 0 && } - {styles.length === 0 && ( - <> - -

{t('no_imported_styles')}

-
- - - )} -
- ); -}; - -export default ImportedStylesList; +import React, { useContext, useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { + applyPageFormat, + deleteImportedFormat, + getImportedFormats, + ImportedFormatAbstract, +} from '../../../features/importStyle'; +import t from '../../../features/translator'; +import { Button, Card, Popconfirm } from 'antd'; +import { PropsContext } from '../../../contexts/PropsContext'; + +const Wrapper = styled.div``; + +const DescriptionWrapper = styled.div` + padding-bottom: 12px; +`; + +const Author = styled.p` + padding-bottom: 8px; +`; + +const ThumbnailWrapper = styled.div` + width: 100%; + height: 150px; +`; + +const Thumbnail = styled.div<{ src: string }>` + width: 100%; + height: 100%; + background-image: ${(prop) => `url("${prop.src}")`}; + background-size: cover; + background-position: center center; + border-radius: 8px 8px 0 0; +`; + +interface CardsProps { + styles: ImportedFormatAbstract[]; + updateFunc: () => Promise; +} + +const Cards = ({ styles, updateFunc }: CardsProps) => { + const { Meta } = Card; + const prop = useContext(PropsContext); + + const onApplyClick = (style: ImportedFormatAbstract) => { + applyPageFormat(style.id, prop); + }; + + const onDeleteClick = (style: ImportedFormatAbstract) => { + deleteImportedFormat(style.id); + void updateFunc(); + }; + + return ( + <> + {styles.map((style) => ( + + + + } + actions={[ + onDeleteClick(style)} + okText={t('yes')} + cancelText={t('no')} + > + + , + , + ]} + > + + {style.author && {style.author}} + + {t('open_style_link')} + + + } + /> + + ))} + + ); +}; + +const ImportedStylesList = () => { + const [styles, setStyles] = useState([]); + + const onOpenStoreClick = () => { + window.open('https://resta-frontend.pages.dev/style/', '_blank'); + }; + + const updateTree = async () => { + const styles = getImportedFormats(); + setStyles(styles); + }; + + useEffect(() => { + void updateTree(); + }, []); + + return ( + + {styles.length !== 0 && } + {styles.length === 0 && ( + <> + +

{t('no_imported_styles')}

+
+ + + )} +
+ ); +}; + +export default ImportedStylesList; diff --git a/src/features/commands/UnRedoCommand.ts b/src/features/commands/CssCommand.ts similarity index 85% rename from src/features/commands/UnRedoCommand.ts rename to src/features/commands/CssCommand.ts index 3e6471c..85907f0 100644 --- a/src/features/commands/UnRedoCommand.ts +++ b/src/features/commands/CssCommand.ts @@ -1,7 +1,7 @@ import { AbstractCommand } from 'react-command-lib/dist/esm'; import { IPropsContext } from '../../contexts/PropsContext'; -export default class CSSCommand implements AbstractCommand { +export default class CssCommand implements AbstractCommand { constructor( props: IPropsContext, cssSelector: string, diff --git a/src/features/importStyle.ts b/src/features/importStyle.ts index 3a75b8f..727cf12 100644 --- a/src/features/importStyle.ts +++ b/src/features/importStyle.ts @@ -3,6 +3,7 @@ import * as prop from './prop'; import { error, log } from './resta_console'; import { StyleRule, StyleValue } from './style_sheet'; import { setFormatsAndPushToAry } from './formatter'; +import { IPropsContext } from '../contexts/PropsContext'; export const importFormat = async ( downloadUrl: string, @@ -10,21 +11,25 @@ export const importFormat = async ( style: string, id: string, imageUrl: string | undefined, - author: string| undefined + author: string | undefined, ) => { if (prop.importedFormat.find((e) => e.id === id)) { // すでに登録されている場合は取り出す prop.setImportedFormat(prop.importedFormat.filter((e) => e.id !== id)); } prop.importedFormat.push({ - id, title, downloadUrl, imageUrl, author, + id, + title, + downloadUrl, + imageUrl, + author, style: JSON.parse(style) as CompressedStyle[], }); await chrome.storage.local.set({ imported_style: prop.importedFormat }); }; -export const applyPageFormat = (id: string) => { - const format = prop.importedFormat.find((e) => e.id === id); +export const applyPageFormat = (id: string, prop: IPropsContext) => { + const format = prop.importedFormats.find((e) => e.id === id); if (!format) { error('applyPageFormat', 'format not found'); return; @@ -44,7 +49,7 @@ export const applyPageFormat = (id: string) => { values: styleValues, }); } - setFormatsAndPushToAry(styleRule); + setFormatsAndPushToAry(styleRule, prop); }; export const deleteImportedFormat = (id: string) => { @@ -63,13 +68,13 @@ export const getImportedFormats = ( log('getImportedFormats', prop.importedFormat); if (all) { return prop.importedFormat.map((e) => { - return {...e}; + return { ...e }; }); } else { return prop.importedFormat .filter((e) => prop.matchUrl(prop.currentUrl, e.style[0].url)) .map((e) => { - return {...e}; + return { ...e }; }); } }; diff --git a/src/hooks/useFormatUtils.ts b/src/hooks/useFormatUtils.ts index 38cb9ff..9cb9e00 100644 --- a/src/hooks/useFormatUtils.ts +++ b/src/hooks/useFormatUtils.ts @@ -1,8 +1,8 @@ import { useCallback, useContext } from 'react'; -import { IPropsContext } from '../contexts/PropsContext'; import { Format } from '../types/Format'; import * as resta_console from '../features/resta_console'; import { removeStyleRule, setStyleRule } from '../features/style_sheet'; +import { PropsContext } from '../contexts/PropsContext'; type ReturnType = { removeAllFormats: VoidFunction; From f23c4cf8e455900d446e17931d77a0bb3044736b Mon Sep 17 00:00:00 2001 From: {Shore} <{kisidakazuyuki@gmail.com}> Date: Tue, 5 Dec 2023 23:15:57 +0900 Subject: [PATCH 5/7] compile passed, but bugs --- .../tabitems/layer/LayerCustomizer.tsx | 3 +- .../tabitems/settings/PageSettingTabItem.tsx | 28 ++- .../tabitems/template/ImportedStylesList.tsx | 5 +- .../tabitems/template/TemplateCard.tsx | 195 +++++++-------- src/consts/debug.ts | 4 +- src/features/commands/CssCommand.ts | 21 +- src/features/commands/TemplateCommand.ts | 19 ++ src/features/format_manager.ts | 34 ++- src/features/formatter.ts | 231 ++++++++++++------ src/features/importStyle.ts | 32 +-- src/features/output_style.ts | 22 +- src/features/prop.ts | 73 ++---- src/features/style_compresser.ts | 24 +- src/features/style_layer.ts | 7 +- src/features/style_sheet.ts | 27 +- src/features/unredo.ts | 204 ---------------- src/features/upload_import_manager.tsx | 229 ++++++++--------- src/hooks/useFormatUtils.ts | 11 +- src/types/UnRedoCommands.ts | 22 -- 19 files changed, 540 insertions(+), 651 deletions(-) create mode 100644 src/features/commands/TemplateCommand.ts delete mode 100644 src/features/unredo.ts delete mode 100644 src/types/UnRedoCommands.ts diff --git a/src/components/tabitems/layer/LayerCustomizer.tsx b/src/components/tabitems/layer/LayerCustomizer.tsx index d6573c0..955b582 100644 --- a/src/components/tabitems/layer/LayerCustomizer.tsx +++ b/src/components/tabitems/layer/LayerCustomizer.tsx @@ -45,6 +45,7 @@ const LayerCustomizer = () => { selectable: false, children: getStyleLayer( getAbsoluteCSSSelector(elementSelection.selectedElement!) + value, + prop, ).children.map((child, index) => ({ title: ( @@ -88,7 +89,7 @@ const LayerCustomizer = () => { ) => { (async () => { deleteFromAry(selector, cssKey, id, prop); - updateFormat(selector, cssKey); + updateFormat(selector, cssKey, prop); await saveFormat(); updater.formatChanged(); })(); diff --git a/src/components/tabitems/settings/PageSettingTabItem.tsx b/src/components/tabitems/settings/PageSettingTabItem.tsx index e0c3b1f..63feef4 100644 --- a/src/components/tabitems/settings/PageSettingTabItem.tsx +++ b/src/components/tabitems/settings/PageSettingTabItem.tsx @@ -2,13 +2,13 @@ import styled from 'styled-components'; import t from '../../../features/translator'; import React, { ChangeEvent, useContext, useState } from 'react'; import { Button, Checkbox, Input, Modal, Popconfirm, Progress } from 'antd'; -import * as prop from '../../../features/prop'; import { saveFormatImmediately } from '../../../features/format_manager'; import { ElementSelectionContext } from '../../../contexts/ElementSelectionContext'; import { getAbsoluteCSSSelector } from '../../../utils/CSSUtils'; import Section from '../common/Section'; import SubTitle from '../common/SubTitle'; import { DEBUG_MODE } from '../../../consts/debug'; +import { PropsContext } from '../../../contexts/PropsContext'; const Wrapper = styled.div``; @@ -24,15 +24,22 @@ const DeveloperTools = styled.div` const { TextArea } = Input; const PageSettingTabItem = () => { + const prop = useContext(PropsContext); const onClickInitPageFormat = () => { - prop.removeCurrentFormat(); - saveFormatImmediately(); + // editedUrlと一致するものを削除 + prop.setFormatsArray( + prop.formatsArray.filter((f) => f.url !== prop.editedUrl), + ); + saveFormatImmediately(prop); window.location.reload(); }; const onClickInitAllPageFormat = () => { - prop.removeAllFormats(); - saveFormatImmediately(); + // FormatsArrayを空にする + prop.setFormatsArray([]); + // localStorageのformatsを上書き + saveFormatImmediately(prop); + // ページをリロード window.location.reload(); }; @@ -66,7 +73,7 @@ const PageSettingTabItem = () => { {t('change_eddited_url_description')}