mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-07 20:31:33 +08:00
Merge pull request #238 from toeverything/bugfix/image-click-select
fix:image click select
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
|
BlockPendantProvider,
|
||||||
useCurrentView,
|
useCurrentView,
|
||||||
useOnSelect,
|
useOnSelect,
|
||||||
BlockPendantProvider,
|
|
||||||
} from '@toeverything/components/editor-core';
|
} from '@toeverything/components/editor-core';
|
||||||
import { styled } from '@toeverything/components/ui';
|
import { styled } from '@toeverything/components/ui';
|
||||||
import { services } from '@toeverything/datasource/db-service';
|
import { services } from '@toeverything/datasource/db-service';
|
||||||
@@ -41,6 +41,18 @@ const ImageBlock = styled('div')({
|
|||||||
},
|
},
|
||||||
'.progress': {},
|
'.progress': {},
|
||||||
});
|
});
|
||||||
|
const ImageShade = styled('div')(({ theme }) => {
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
zIndex: 2,
|
||||||
|
right: 0,
|
||||||
|
background: 'transparent',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const KanbanImageContainer = styled('div')<{ isSelected: boolean }>(
|
const KanbanImageContainer = styled('div')<{ isSelected: boolean }>(
|
||||||
({ theme, isSelected }) => {
|
({ theme, isSelected }) => {
|
||||||
return {
|
return {
|
||||||
@@ -56,73 +68,72 @@ const KanbanImageContainer = styled('div')<{ isSelected: boolean }>(
|
|||||||
);
|
);
|
||||||
export const ImageView = ({ block, editor }: ImageView) => {
|
export const ImageView = ({ block, editor }: ImageView) => {
|
||||||
const workspace = editor.workspace;
|
const workspace = editor.workspace;
|
||||||
const [imgUrl, set_image_url] = useState<string>();
|
const [imgUrl, setImageUrl] = useState<string>();
|
||||||
const [imgWidth, setImgWidth] = useState<number>(0);
|
const [imgWidth, setImgWidth] = useState<number>(0);
|
||||||
const [ratio, set_ratio] = useState<number>(0);
|
const [ratio, setRatio] = useState<number>(0);
|
||||||
const resize_box = useRef(null);
|
const resizeBox = useRef(null);
|
||||||
const [currentView] = useCurrentView();
|
const [currentView] = useCurrentView();
|
||||||
const [isSelect, setIsSelect] = useState<boolean>();
|
const [isSelect, setIsSelect] = useState<boolean>();
|
||||||
useOnSelect(block.id, (isSelect: boolean) => {
|
useOnSelect(block.id, (isSelect: boolean) => {
|
||||||
setIsSelect(isSelect);
|
setIsSelect(isSelect);
|
||||||
});
|
});
|
||||||
|
|
||||||
const img_load = (url: string) => {
|
const imgLoad = (url: string) => {
|
||||||
const boxWidth = resize_box.current.offsetWidth;
|
const boxWidth = resizeBox.current.offsetWidth;
|
||||||
|
|
||||||
const imageStyle = block.getProperty('image_style');
|
const imageStyle = block.getProperty('image_style');
|
||||||
if (imageStyle?.width) {
|
if (imageStyle?.width) {
|
||||||
set_ratio(imageStyle.width / imageStyle.height);
|
setRatio(imageStyle.width / imageStyle.height);
|
||||||
setImgWidth(imageStyle.width);
|
setImgWidth(imageStyle.width);
|
||||||
set_image_url(url);
|
setImageUrl(url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = url;
|
img.src = url;
|
||||||
// load complete execution
|
// load complete execution
|
||||||
img.onload = async () => {
|
img.onload = async () => {
|
||||||
const img_radio = img.width / img.height;
|
const imgRadio = img.width / img.height;
|
||||||
|
|
||||||
if (img.width >= boxWidth - 20) {
|
if (img.width >= boxWidth - 20) {
|
||||||
img.width = boxWidth - 20;
|
img.width = boxWidth - 20;
|
||||||
}
|
}
|
||||||
img.height = img.width / img_radio;
|
img.height = img.width / imgRadio;
|
||||||
|
|
||||||
block.setProperty('image_style', {
|
block.setProperty('image_style', {
|
||||||
width: img.width,
|
width: img.width,
|
||||||
height: img.height,
|
height: img.height,
|
||||||
});
|
});
|
||||||
setImgWidth(img.width);
|
setImgWidth(img.width);
|
||||||
set_image_url(url);
|
setImageUrl(url);
|
||||||
set_ratio(img_radio);
|
setRatio(imgRadio);
|
||||||
};
|
};
|
||||||
img.onerror = e => {
|
img.onerror = e => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const style = window.getComputedStyle(block?.dom);
|
const imageInfo = block.getProperty('image');
|
||||||
const image_info = block.getProperty('image');
|
const imageBlockId = imageInfo?.value;
|
||||||
const image_block_id = image_info?.value;
|
const imageInfoUrl = imageInfo?.url;
|
||||||
const image_info_url = image_info?.url;
|
|
||||||
|
|
||||||
if (image_info_url) {
|
if (imageInfoUrl) {
|
||||||
img_load(image_info_url);
|
imgLoad(imageInfoUrl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (image_block_id) {
|
if (imageBlockId) {
|
||||||
services.api.file.get(image_block_id, workspace).then(file_info => {
|
services.api.file.get(imageBlockId, workspace).then(fileInfo => {
|
||||||
img_load(file_info.url);
|
imgLoad(fileInfo.url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [workspace]);
|
}, [workspace]);
|
||||||
|
|
||||||
const down_ref = useRef(null);
|
const downRef = useRef(null);
|
||||||
const on_file_change = async (file: File) => {
|
const onFileChange = async (file: File) => {
|
||||||
const result = await services.api.file.create({
|
const result = await services.api.file.create({
|
||||||
workspace: editor.workspace,
|
workspace: editor.workspace,
|
||||||
file: file,
|
file: file,
|
||||||
});
|
});
|
||||||
img_load(result.url);
|
imgLoad(result.url);
|
||||||
block.setProperty('image', {
|
block.setProperty('image', {
|
||||||
value: result.id,
|
value: result.id,
|
||||||
name: file.name,
|
name: file.name,
|
||||||
@@ -130,11 +141,11 @@ export const ImageView = ({ block, editor }: ImageView) => {
|
|||||||
type: file.type,
|
type: file.type,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const delete_file = () => {
|
const deleteFile = () => {
|
||||||
block.remove();
|
block.remove();
|
||||||
};
|
};
|
||||||
const sava_link = (link: string) => {
|
const savaLink = (link: string) => {
|
||||||
img_load(link);
|
imgLoad(link);
|
||||||
block.setProperty('image', {
|
block.setProperty('image', {
|
||||||
value: '',
|
value: '',
|
||||||
url: link,
|
url: link,
|
||||||
@@ -143,27 +154,25 @@ export const ImageView = ({ block, editor }: ImageView) => {
|
|||||||
type: 'link',
|
type: 'link',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handle_click = async (e: React.MouseEvent<HTMLDivElement>) => {
|
const handleClick = async (e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
//TODO clear active selection
|
|
||||||
// document.getElementsByTagName('body')[0].click();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.nativeEvent.stopPropagation();
|
|
||||||
await editor.selectionManager.setSelectedNodesIds([block.id]);
|
await editor.selectionManager.setSelectedNodesIds([block.id]);
|
||||||
await editor.selectionManager.activeNodeByNodeId(block.id, 'end');
|
await editor.selectionManager.activeNodeByNodeId(block.id, 'end');
|
||||||
};
|
};
|
||||||
const down_file = () => {
|
const down_file = () => {
|
||||||
if (down_ref) {
|
if (downRef) {
|
||||||
down_ref.current.click();
|
downRef.current.click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BlockPendantProvider block={block}>
|
<BlockPendantProvider block={block}>
|
||||||
<ImageBlock>
|
<ImageBlock>
|
||||||
<div ref={resize_box}>
|
<div style={{ position: 'relative' }} ref={resizeBox}>
|
||||||
|
{!isSelect ? (
|
||||||
|
<ImageShade onClick={handleClick}></ImageShade>
|
||||||
|
) : null}
|
||||||
{imgUrl ? (
|
{imgUrl ? (
|
||||||
<div
|
<div
|
||||||
onClick={handle_click}
|
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
// e.nativeEvent.stopPropagation();
|
// e.nativeEvent.stopPropagation();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -175,7 +184,7 @@ export const ImageView = ({ block, editor }: ImageView) => {
|
|||||||
viewStyle={{
|
viewStyle={{
|
||||||
width: imgWidth,
|
width: imgWidth,
|
||||||
maxWidth:
|
maxWidth:
|
||||||
resize_box.current.offsetWidth - 20,
|
resizeBox.current.offsetWidth - 20,
|
||||||
minWidth: 32,
|
minWidth: 32,
|
||||||
ratio: ratio,
|
ratio: ratio,
|
||||||
}}
|
}}
|
||||||
@@ -193,9 +202,9 @@ export const ImageView = ({ block, editor }: ImageView) => {
|
|||||||
<Upload
|
<Upload
|
||||||
firstCreate={block.firstCreateFlag}
|
firstCreate={block.firstCreateFlag}
|
||||||
uploadType={'image'}
|
uploadType={'image'}
|
||||||
fileChange={on_file_change}
|
fileChange={onFileChange}
|
||||||
deleteFile={delete_file}
|
deleteFile={deleteFile}
|
||||||
savaLink={sava_link}
|
savaLink={savaLink}
|
||||||
isSelected={isSelect}
|
isSelected={isSelect}
|
||||||
defaultAddBtnText={MESSAGES.ADD_AN_IMAGE}
|
defaultAddBtnText={MESSAGES.ADD_AN_IMAGE}
|
||||||
accept={
|
accept={
|
||||||
@@ -215,14 +224,14 @@ export const ImageView = ({ block, editor }: ImageView) => {
|
|||||||
}}
|
}}
|
||||||
></DownloadIcon>
|
></DownloadIcon>
|
||||||
<DeleteSweepOutlinedIcon
|
<DeleteSweepOutlinedIcon
|
||||||
onClick={delete_file}
|
onClick={deleteFile}
|
||||||
className="delete-icon"
|
className="delete-icon"
|
||||||
fontSize="small"
|
fontSize="small"
|
||||||
sx={{ color: '#000', cursor: 'pointer' }}
|
sx={{ color: '#000', cursor: 'pointer' }}
|
||||||
></DeleteSweepOutlinedIcon>
|
></DeleteSweepOutlinedIcon>
|
||||||
<a
|
<a
|
||||||
href={imgUrl}
|
href={imgUrl}
|
||||||
ref={down_ref}
|
ref={downRef}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
download="text.png"
|
download="text.png"
|
||||||
></a>
|
></a>
|
||||||
|
|||||||
Reference in New Issue
Block a user