Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion src/renderer/assets/styles/components/modals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
box-sizing: border-box;
border: 1px solid var(--color-gray-250);

@include mx.scrollbar_styling;

&.modal_dialog_full {
position: relative;
box-sizing: border-box;
Expand All @@ -53,7 +55,7 @@
height: calc(100vh - 100px);
}
}

background-color: var(--color-neutral-base);
color: var(--color-text-primary);

Expand Down Expand Up @@ -260,6 +262,74 @@
}
}

.imageViewerContent {
min-width: 700px;
min-height: 400px;
padding: 5px 10px;
width: unset;
max-width: calc(100% - 200px);
max-height: calc(100% - 100px);
overflow: hidden;

.close_button_bar {
display: flex;
align-items: center;
justify-content: end;
z-index: 103;
}

.image_content_container {
display: flex;
flex-direction: column;
padding: 5px 10px;
align-items: center;
flex: 1;
overflow: hidden;
}

.image_description_container {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: fit-content;
max-height: calc(100% - 50px);
transition: 200ms ease-in-out;
overflow: scroll;
background-color: var(--color-neutral-base);
border-radius: 10px;
z-index: 110;
overflow-y: scroll;
margin-bottom: -10px;
display: flex;
flex-direction: column;
}

.image_description_content {
padding: 10px;
margin-bottom: 60px;
overflow: auto;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;

@include mx.scrollbar_styling;
}

.image_description_toggle {
position: absolute;
bottom: 10px;
right: 10px;
color: var(--color-neutral-base);
padding: 2px 7px;
border-radius: 6px;
background-color: color-mix(in srgb, var(--color-brand-primary), transparent 20%);
font-weight: bold;
z-index: 110;
}
}

.CSS_END_components_modals {
display: none;
}
6 changes: 6 additions & 0 deletions src/renderer/assets/styles/components/modals.scss.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ export declare const add_dialog: string;
export declare const button_secondary_blue: string;
export declare const c_dialog__box: string;
export declare const close_button: string;
export declare const close_button_bar: string;
export declare const CSS_END_components_modals: string;
export declare const CSS_START_components_modals: string;
export declare const display_options_item: string;
export declare const field: string;
export declare const guidedTour_buttons: string;
export declare const guidedTour_content: string;
export declare const guidedTour_tab: string;
export declare const image_content_container: string;
export declare const image_description_container: string;
export declare const image_description_content: string;
export declare const image_description_toggle: string;
export declare const imageViewerContent: string;
export declare const lcp_hint: string;
export declare const modal_dialog: string;
export declare const modal_dialog_body: string;
Expand Down
86 changes: 75 additions & 11 deletions src/renderer/reader/components/ImageClickManagerViewerOnly.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ const Controls = () => {
<style>{`

.imgViewerControls {
position: absolute;
// position: absolute;
align-items: center;
justify-content: center;
z-index: 105;
transform: translate(-50%, 50%);
// transform: translate(-50%, 50%);
display: flex;
// opacity: 0;
transition: 200ms;
gap: 10px;
margin-top: 10px;
}

.imgViewerControls button {
Expand Down Expand Up @@ -82,7 +83,7 @@ const Controls = () => {

export const ImageClickManagerImgViewerOnly: React.FC = () => {

const { open, isSVGFragment, HTMLImgSrc_SVGImageHref_SVGFragmentMarkup, altAttributeOf_HTMLImg_SVGImage_SVGFragment, titleAttributeOf_HTMLImg_SVGImage_SVGFragment, ariaLabelAttributeOf_HTMLImg_SVGImage_SVGFragment, naturalWidthOf_HTMLImg_SVGImage, naturalHeightOf_HTMLImg_SVGImage } = useSelector((state: IReaderRootState) => state.img);
const { open, isSVGFragment, HTMLImgSrc_SVGImageHref_SVGFragmentMarkup, altAttributeOf_HTMLImg_SVGImage_SVGFragment, titleAttributeOf_HTMLImg_SVGImage_SVGFragment, ariaLabelAttributeOf_HTMLImg_SVGImage_SVGFragment, naturalWidthOf_HTMLImg_SVGImage, naturalHeightOf_HTMLImg_SVGImage, dom_describedbyText, dom_detailsText, dom_figcaptionText, dom_labelledByText } = useSelector((state: IReaderRootState) => state.img);
const dispatch = useDispatch();
const [__] = useTranslator();

Expand All @@ -91,32 +92,78 @@ export const ImageClickManagerImgViewerOnly: React.FC = () => {
let scale = Math.min(scaleX, scaleY);
if (scale > 1) scale = 1;

const descriptions = [
{ label: __("reader.imgViewer.description.details"), value: dom_detailsText },
{ label: __("reader.imgViewer.description.figcaption"), value: dom_figcaptionText },
{ label: __("reader.imgViewer.description.describedby"), value: dom_describedbyText },
{ label: __("reader.imgViewer.description.labelledby"), value: dom_labelledByText },
];

const [toggleAlt, setToggleAlt] = React.useState(false);

const hasAlt = !!altAttributeOf_HTMLImg_SVGImage_SVGFragment;
const activeDescriptions = descriptions.filter(d => !!d.value);
const hasOtherDescriptions = activeDescriptions.length > 0;

// const imageHasDescription = hasAlt || hasOtherDescriptions;
const imageHasOnlyAltDescription = hasAlt && !hasOtherDescriptions;

// const DescriptionList = (
// <details style={{ fontSize: "14px", cursor: "pointer" }}>
// <summary>
// {altAttributeOf_HTMLImg_SVGImage_SVGFragment || __("reader.imgViewer.description.about")}
// </summary>
// <ul style={{ marginTop: "10px", listStyleType: "none", paddingLeft: 0 }}>
// {activeDescriptions.map(({ label, value }) => (
// <li key={label} style={{ marginBottom: "10px" }}>
// <strong>{label}: </strong> {value}
// </li>
// ))}
// </ul>
// </details>
// );

const DescriptionList = (
<ul style={{ marginTop: "10px", listStyleType: "none", paddingLeft: 0, fontSize: "14px" }}>
<li style={{ marginBottom: "10px" }}>{altAttributeOf_HTMLImg_SVGImage_SVGFragment || __("reader.imgViewer.description.about")}</li>
{activeDescriptions.map(({ label, value }) => (
<li key={label} style={{ marginBottom: "10px" }}>
<strong>{label}: </strong> {value}
</li>
))}
</ul>
);

const imageDescription = imageHasOnlyAltDescription
? altAttributeOf_HTMLImg_SVGImage_SVGFragment
: DescriptionList;

return (<>

<Dialog.Root open={open} onOpenChange={(openState: boolean) => {
if (openState == false) {
dispatch(readerLocalActionSetImageClick.build());
setToggleAlt(false);
}
}}
>
<Dialog.Portal>
<div className={stylesModals.modal_dialog_overlay}></div>
<Dialog.Content className={classNames(stylesModals.modal_dialog)} aria-describedby={undefined} style={{ minWidth: "700px", minHeight: "400px", padding: "5px 10px", width: "unset", maxWidth: "calc(100% - 200px)", maxHeight: "calc(100% - 100px)" }} >
<div className={stylesModals.modal_dialog_overlay} style={{backgroundColor: toggleAlt ? "rgba(0, 0, 0, 0.7)" : "rgba(0, 0, 0, 0.5)"}}></div>
<Dialog.Content className={classNames(stylesModals.modal_dialog, stylesModals.imageViewerContent)} aria-describedby={undefined}>
<VisuallyHidden>
<Dialog.DialogTitle>{__("reader.imgViewer.title")}</Dialog.DialogTitle>
</VisuallyHidden>
<div style={{ display: "flex", alignItems: "center", justifyContent: "end" }}>
<div className={stylesModals.close_button_bar}>
<Dialog.Close asChild>
<button style={{ zIndex: 105 }} className={stylesButtons.button_transparency_icon} aria-label={__("accessibility.closeDialog")}>
<SVG ariaHidden={true} svg={QuitIcon} />
</button>
</Dialog.Close>
</div>
<div style={{ display: "flex", flexDirection: "column", padding: "5px 10px", alignItems: "center", flex: 1 }}>
<div style={{ position: "relative", display: "flex", gap: 10, width: "100%", height: "100%", paddingLeft: 5, flex: 1 }}>
<div className={stylesModals.image_content_container}>
<div style={{ position: "relative", display: "flex", gap: 10, width: "100%", height: "100%", paddingLeft: 5, flex: 1, flexDirection: "column"}}>
<TransformWrapper initialScale={scale} minScale={scale / 2} maxScale={4 * scale}>
<Controls />
<TransformComponent wrapperStyle={{ display: "flex", width: "100%", height: "100%", minHeight: "350px", flex: "1", position: "relative" }} >
<TransformComponent wrapperStyle={{ display: "flex", width: "100%", height: "100%", minHeight: "350px", flex: "1", position: "relative", transition: "600ms ease-in-out"}} >
<img
style={{ height: "100%", width: "100%", maxHeight: "calc(100vh - 250px)", backgroundColor: "white", color: "black", fill: "currentcolor", stroke: "currentcolor" }}
src={isSVGFragment ? ("data:image/svg+xml;base64," + Buffer.from(HTMLImgSrc_SVGImageHref_SVGFragmentMarkup).toString("base64")) : HTMLImgSrc_SVGImageHref_SVGFragmentMarkup}
Expand All @@ -126,8 +173,25 @@ export const ImageClickManagerImgViewerOnly: React.FC = () => {
tabIndex={0}
/>
</TransformComponent>
{
toggleAlt ?
<div className={stylesModals.modal_dialog_overlay} style={{top: "40px"}}></div>
: <></>
}
<Controls />
</TransformWrapper>
</div>
</div>
<div className={stylesModals.image_description_container} style={{transform: toggleAlt ? "translateY(0)" : "translateY(1000px)"}}>
<div className={stylesModals.image_description_content}>{imageDescription}</div>
</div>
{imageDescription ?
<button className={stylesModals.image_description_toggle}
onClick={() => setToggleAlt(!toggleAlt)}
>
ALT
</button>
: <></>
}
</div>
</Dialog.Content>
</Dialog.Portal>
Expand Down
Loading