Fix bug 75164

This commit is contained in:
nikita_bartoshuk
2025-08-28 15:00:57 +03:00
parent 90eeca5018
commit 9899d94bbd
4 changed files with 274 additions and 9 deletions

View File

@ -51,6 +51,7 @@
"textPasteImageUrl": "Paste an image URL",
"textPictureFromLibrary": "Picture from Library",
"textPictureFromURL": "Picture from URL",
"textRemovePicture": "Remove picture",
"textPosition": "Position",
"textRecommended": "Recommended",
"textRequired": "Required",

View File

@ -18,6 +18,7 @@ import LongActionsController from "./LongActions";
import PluginsController from '../../../../common/mobile/lib/controller/Plugins.jsx';
import EncodingController from "./Encoding";
import DropdownListController from "./DropdownList";
import AddFormImageController from './add/AddFormImage.jsx';
import { Device } from '../../../../common/mobile/utils/device';
import { processArrayScripts } from '../../../../common/mobile/utils/processArrayScripts.js';
import '../../../../common/main/lib/util/LanguageInfo.js'
@ -869,15 +870,7 @@ class MainController extends Component {
break;
case Asc.c_oAscContentControlSpecificType.Picture:
case Asc.c_oAscContentControlSpecificType.Signature:
if (obj.pr && obj.pr.get_Lock) {
let lock = obj.pr.get_Lock();
if (lock == Asc.c_oAscSdtLockType.SdtContentLocked || lock == Asc.c_oAscSdtLockType.ContentLocked)
return;
}
this.api.asc_addImage(obj);
setTimeout(() => {
this.api.asc_UncheckContentControlButtons();
}, 500);
this.onShowImageActions(obj, x, y);
break;
case Asc.c_oAscContentControlSpecificType.DropDownList:
case Asc.c_oAscContentControlSpecificType.ComboBox:
@ -1202,6 +1195,25 @@ class MainController extends Component {
}, 100)
}
onShowImageActions(obj, x, y) {
if(!Device.isPhone) {
const boxSdk = $$('#editor_sdk');
let dropdownListTarget = boxSdk.find('#dropdown-image-list-target');
if (dropdownListTarget.length < 1) {
dropdownListTarget = $$('<div id="dropdown-image-list-target" style="position: absolute;"></div>');
boxSdk.append(dropdownListTarget);
}
dropdownListTarget.css({left: `${x}px`, top: `${y}px`});
}
Common.Notifications.trigger('openFormImageList', obj);
setTimeout(() => {
this.api.asc_UncheckContentControlButtons();
}, 500);
}
onShowListActions(obj, x, y) {
if(!Device.isPhone) {
const boxSdk = $$('#editor_sdk');
@ -1636,6 +1648,7 @@ class MainController extends Component {
<PluginsController />
<EncodingController />
<DropdownListController />
<AddFormImageController />
</Fragment>
)
}

View File

@ -0,0 +1,94 @@
import React, { Component } from 'react';
import { Device } from '../../../../../common/mobile/utils/device';
import { f7 } from "framework7-react";
import { withTranslation } from "react-i18next";
import FormImageList from "../../view/add/AddFormImage";
class AddFormImageController extends Component {
constructor(props) {
super(props);
this.closeModal = this.closeModal.bind(this);
this.addPictureFromLibrary = this.addPictureFromLibrary.bind(this);
this.onInsertByUrl = this.onInsertByUrl.bind(this);
this.deletePicture = this.deletePicture.bind(this);
this.state = {
isOpen: false,
};
Common.Notifications.on('openFormImageList', obj => {
this.openModal(obj);
});
}
openModal(obj) {
this.setState({
isOpen: true,
});
}
closeModal() {
if(Device.isPhone) {
f7.popup.close('#dropdown-image-list-popup', true);
} else {
f7.popover.close('#dropdown-image-list-popover', true);
}
f7.views.current.router.back();
this.setState({isOpen: false});
}
addPictureFromLibrary() {
const api = Common.EditorApi.get();
if (obj.pr && obj.pr.get_Lock) {
let lock = obj.pr.get_Lock();
if (lock == Asc.c_oAscSdtLockType.SdtContentLocked || lock == Asc.c_oAscSdtLockType.ContentLocked)
return;
}
api.asc_addImage(obj);
this.closeModal();
}
onInsertByUrl (value) {
const { t } = this.props;
const _t = t("Add", { returnObjects: true });
const _value = value.replace(/ /g, '');
if (_value) {
if ((/((^https?)|(^ftp)):\/\/.+/i.test(_value))) {
const api = Common.EditorApi.get();
api.AddImageUrl([_value]);
} else {
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
}
} else {
f7.dialog.alert(_t.textEmptyImgUrl, _t.notcriticalErrorTitle);
}
}
deletePicture() {
const api = Common.EditorApi.get();
if (api) {
var props = api.asc_IsContentControl() ? api.asc_GetContentControlProperties() : null;
if (props) {
api.asc_ClearContentControl(props.get_InternalId());
this.closeModal();
}
}
}
render() {
return (
this.state.isOpen &&
<FormImageList
closeModal={this.closeModal}
addPictureFromLibrary={this.addPictureFromLibrary}
onInsertByUrl={this.onInsertByUrl}
deletePicture={this.deletePicture}
/>
);
}
}
export default withTranslation()(AddFormImageController);

View File

@ -0,0 +1,157 @@
import React, { useState, useEffect, Component } from 'react';
import { f7, Sheet, PageContent, Navbar, List, Page, View, ListItem, ListInput, ListButton, NavRight, Link, BlockTitle, Icon, Popup, Popover } from 'framework7-react';
import { useTranslation } from 'react-i18next';
import { Device } from '../../../../../common/mobile/utils/device';
import SvgIcon from '@common/lib/component/SvgIcon';
import IconImageLibraryIos from '@common-ios-icons/icon-image-library.svg?ios';
import IconImageLibraryAndroid from '@common-android-icons/icon-image-library.svg';
import IconLinkIos from '@common-ios-icons/icon-link.svg?ios';
import IconLinkAndroid from '@common-android-icons/icon-link.svg';
import IconExpandDownIos from '@common-ios-icons/icon-expand-down.svg?ios';
import IconExpandDownAndroid from '@common-android-icons/icon-expand-down.svg';
const AddImageFromUrlPage = ({ f7router, onInsertByUrl }) => {
const { t } = useTranslation();
const _t = t('Add', { returnObjects: true });
const [stateValue, setValue] = useState('');
return (
<Page>
<Navbar title={t('Add.textPasteImageUrl')} backLink={_t.textBack} />
<List>
<ListInput
type="text"
placeholder={_t.textImageURL}
value={stateValue}
onChange={(e) => setValue(e.target.value)}
/>
</List>
<List className="buttons-list">
<ListButton className={'button-fill button-raised' + (stateValue.length < 1 ? ' disabled' : '')}
title={_t.textInsertImage}
onClick={() => {
if (stateValue.length > 0) {
onInsertByUrl(stateValue);
f7router.back();
}
}}
/>
</List>
</Page>
);
};
const PageSheetAddImage = ({ closeModal, onInsertByUrl, addPictureFromLibrary, deletePicture, style }) => {
const { t } = useTranslation();
const _t = t('Add', { returnObjects: true });
const routes = [
{
path: '/add-form-image-from-url/',
component: AddImageFromUrlPage,
},
];
return (
<View style={style} routes={routes} url="/" stackPages iosSwipeBack={true} animate={true} pushState={false} transition="f7-push">
<Page>
<Navbar title={_t.textInsertImage}>
{Device.phone &&
<NavRight>
<Link onClick={closeModal}>
{Device.ios ?
<SvgIcon symbolId={IconExpandDownIos.id} className={'icon icon-svg'} /> :
<SvgIcon symbolId={IconExpandDownAndroid.id} className={'icon icon-svg white'} />
}
</Link>
</NavRight>
}
</Navbar>
<List>
<ListItem
title={_t.textPictureFromLibrary}
onClick={() => addPictureFromLibrary()}
>
{Device.ios ? (
<SvgIcon slot="media" symbolId={IconImageLibraryIos.id} className={'icon icon-svg'} />
) : (
<SvgIcon slot="media" symbolId={IconImageLibraryAndroid.id} className={'icon icon-svg'} />
)}
</ListItem>
<ListItem
title={_t.textPictureFromURL}
link={'/add-form-image-from-url/'}
routeProps={{
onInsertByUrl: onInsertByUrl
}}
>
{Device.ios ? (
<SvgIcon slot="media" symbolId={IconLinkIos.id} className={'icon icon-svg'} />
) : (
<SvgIcon slot="media" symbolId={IconLinkAndroid.id} className={'icon icon-svg'} />
)}
</ListItem>
<List className="buttons-list">
<ListButton title={_t.textRemovePicture} onClick={() => deletePicture()} className='button-red button-fill button-raised'></ListButton>
</List>
</List>
</Page>
</View>
);
};
class SheetAddImageListView extends Component {
constructor(props) {
super(props);
}
render() {
return (
Device.isPhone ?
<Sheet id="dropdown-image-list-popup" className="dropdown-image-list-popup" closeByOutsideClick={true} swipeToClose={true} onPopupClosed={() => this.props.closeModal()}>
<PageSheetAddImage
closeModal={this.props.closeModal}
addPictureFromLibrary={this.props.addPictureFromLibrary}
onInsertByUrl={this.props.onInsertByUrl}
deletePicture={this.props.deletePicture}
style={{height: '260px'}}
/>
</Sheet>
:
<Popover id="dropdown-image-list-popover" className="popover__titled" closeByOutsideClick={true} onPopoverClosed={() => this.props.closeModal()}>
<PageSheetAddImage
closeModal={this.props.closeModal}
addPictureFromLibrary={this.props.addPictureFromLibrary}
onInsertByUrl={this.props.onInsertByUrl}
deletePicture={this.props.deletePicture}
style={{height: '260px'}}
/>
</Popover>
);
}
}
const FormImageList = props => {
useEffect(() => {
if(Device.isPhone) {
f7.popup.open('#dropdown-image-list-popup', true);
} else {
f7.popover.open('#dropdown-image-list-popover', '#dropdown-image-list-target');
}
return () => {}
});
return (
<SheetAddImageListView
closeModal={props.closeModal}
addPictureFromLibrary={props.addPictureFromLibrary}
onInsertByUrl={props.onInsertByUrl}
deletePicture={props.deletePicture}
/>
);
};
export default FormImageList;