[DE mobile] Add insert, open link handler in context menu

This commit is contained in:
JuliaSvinareva 2021-03-18 20:37:29 +03:00
parent cb62ade641
commit bf7f2e43f9
7 changed files with 210 additions and 133 deletions

View file

@ -106,6 +106,21 @@ class ContextMenu extends ContextMenuController {
this.props.openOptions('edit');
}, 0);
break;
case 'addlink':
setTimeout(() => {
this.props.openOptions('add', 'link');
}, 400)
break;
case 'openlink':
const stack = Common.EditorApi.get().getSelectedElements();
let value;
stack.forEach((item) => {
if (item.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
value = item.get_ObjectValue().get_Value();
}
});
value && this.openLink(value);
break;
}
console.log("click context menu item: " + action);
@ -185,6 +200,15 @@ class ContextMenu extends ContextMenuController {
});
}
openLink(url) {
if (Common.EditorApi.get().asc_getUrlType(url) > 0) {
const newDocumentPage = window.open(url, '_blank');
if (newDocumentPage) {
newDocumentPage.focus();
}
}
}
onDocumentReady() {
super.onDocumentReady();
@ -323,12 +347,12 @@ class ContextMenu extends ContextMenuController {
});
}
// if ( !_.isEmpty(api.can_AddHyperlink()) && !lockedHeader) {
// arrItems.push({
// caption: _t.menuAddLink,
// event: 'addlink'
// });
// }
if ( !!api.can_AddHyperlink() && !lockedHeader) {
itemsText.push({
caption: _t.menuAddLink,
event: 'addlink'
});
}
if ( canReview ) {
if (this.inRevisionChange) {

View file

@ -0,0 +1,67 @@
import React, {Component} from 'react';
import { f7 } from 'framework7-react';
import {Device} from '../../../../../common/mobile/utils/device';
import { withTranslation} from 'react-i18next';
import {PageAddLink} from '../../view/add/AddLink';
class AddLinkController extends Component {
constructor (props) {
super(props);
this.onInsertLink = this.onInsertLink.bind(this);
}
closeModal () {
if ( Device.phone ) {
f7.sheet.close('.add-popup', true);
} else {
f7.popover.close('#add-popover');
}
}
getDisplayLinkText () {
const api = Common.EditorApi.get();
return api.can_AddHyperlink();
}
onInsertLink (url, display, tip) {
const api = Common.EditorApi.get();
const { t } = this.props;
const _t = t("Add", { returnObjects: true });
const urltype = api.asc_getUrlType(url.trim());
const isEmail = (urltype == 2);
if (urltype < 1) {
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
return;
}
let _url = url.replace(/^\s+|\s+$/g,'');
if (! /(((^https?)|(^ftp)):\/\/)|(^mailto:)/i.test(_url) )
_url = (isEmail ? 'mailto:' : 'http://' ) + _url;
_url = _url.replace(new RegExp("%20",'g')," ");
const props = new Asc.CHyperlinkProperty();
props.put_Value(_url);
props.put_Text(!display ? _url : display);
props.put_ToolTip(tip);
api.add_Hyperlink(props);
this.closeModal();
}
render () {
return (
<PageAddLink closeModal={this.closeModal} onInsertLink={this.onInsertLink} getDisplayLinkText={this.getDisplayLinkText} noNavbar={this.props.noNavbar}/>
)
}
}
const AddLinkWithTranslation = withTranslation()(AddLinkController);
export {AddLinkWithTranslation as AddLinkController};

View file

@ -66,7 +66,6 @@ const _Rometo10 = (str) => {
class AddOtherController extends Component {
constructor (props) {
super(props);
this.onInsertLink = this.onInsertLink.bind(this);
this.onInsertPageNumber = this.onInsertPageNumber.bind(this);
this.onPageBreak = this.onPageBreak.bind(this);
this.onColumnBreak = this.onColumnBreak.bind(this);
@ -86,42 +85,6 @@ class AddOtherController extends Component {
}
}
getDisplayLinkText () {
const api = Common.EditorApi.get();
return api.can_AddHyperlink();
}
onInsertLink (url, display, tip) {
const api = Common.EditorApi.get();
const { t } = this.props;
const _t = t("Add", { returnObjects: true });
const urltype = api.asc_getUrlType(url.trim());
const isEmail = (urltype == 2);
if (urltype < 1) {
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
return;
}
let _url = url.replace(/^\s+|\s+$/g,'');
if (! /(((^https?)|(^ftp)):\/\/)|(^mailto:)/i.test(_url) )
_url = (isEmail ? 'mailto:' : 'http://' ) + _url;
_url = _url.replace(new RegExp("%20",'g')," ");
const props = new Asc.CHyperlinkProperty();
props.put_Value(_url);
props.put_Text(!display ? _url : display);
props.put_ToolTip(tip);
api.add_Hyperlink(props);
this.closeModal();
}
onInsertPageNumber (type) {
const api = Common.EditorApi.get();
@ -280,8 +243,6 @@ class AddOtherController extends Component {
render () {
return (
<AddOther closeModal={this.closeModal}
onInsertLink={this.onInsertLink}
getDisplayLinkText={this.getDisplayLinkText}
onInsertPageNumber={this.onInsertPageNumber}
onPageBreak={this.onPageBreak}
onColumnBreak={this.onColumnBreak}

View file

@ -18,25 +18,29 @@ export default class MainPage extends Component {
this.state = {
editOptionsVisible: false,
addOptionsVisible: false,
addShowOptions: null,
settingsVisible: false,
collaborationVisible: false
};
}
handleClickToOpenOptions = (opts, page) => {
handleClickToOpenOptions = (opts, showOpts) => {
ContextMenu.closeContextMenu();
this.setState(state => {
if ( opts == 'edit' )
return {editOptionsVisible: true};
else if ( opts == 'add' )
return {addOptionsVisible: true};
return {
addOptionsVisible: true,
addShowOptions: showOpts
};
else if ( opts == 'settings' )
return {settingsVisible: true};
else if ( opts == 'coauth' )
return {
collaborationVisible: true,
collaborationPage: page
collaborationPage: showOpts
};
});
};
@ -90,7 +94,7 @@ export default class MainPage extends Component {
}
{
!this.state.addOptionsVisible ? null :
<AddOptions onclosed={this.handleOptionsViewClosed.bind(this, 'add')} />
<AddOptions onclosed={this.handleOptionsViewClosed.bind(this, 'add')} showOptions={this.state.addShowOptions} />
}
{
!this.state.settingsVisible ? null :

View file

@ -1,5 +1,5 @@
import React, {Component, useEffect} from 'react';
import {View,Page,Navbar,NavRight,Link,Popup,Popover,Icon,Tabs,Tab} from 'framework7-react';
import React, {Component, useEffect, Fragment} from 'react';
import {View,Page,Navbar,NavRight, NavTitle, Link,Popup,Popover,Icon,Tabs,Tab} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import {f7} from 'framework7-react';
import { observer, inject } from "mobx-react";
@ -8,10 +8,11 @@ import {Device} from '../../../../../common/mobile/utils/device';
import {AddTableController} from "../../controller/add/AddTable";
import AddShapeController from "../../controller/add/AddShape";
import {AddImageController} from "../../controller/add/AddImage";
import {AddLinkController} from "../../controller/add/AddLink";
import {AddOtherController} from "../../controller/add/AddOther";
import {PageImageLinkSettings} from "../add/AddImage";
import {PageAddLink, PageAddNumber, PageAddBreak, PageAddSectionBreak, PageAddFootnote} from "../add/AddOther";
import {PageAddNumber, PageAddBreak, PageAddSectionBreak, PageAddFootnote} from "../add/AddOther";
const routes = [
// Image
@ -22,7 +23,7 @@ const routes = [
// Other
{
path: '/add-link/',
component: PageAddLink,
component: AddLinkController,
},
{
path: '/add-page-number/',
@ -44,15 +45,20 @@ const routes = [
const AddLayoutNavbar = ({ tabs, inPopover }) => {
const isAndroid = Device.android;
const { t } = useTranslation();
const _t = t('Add', {returnObjects: true});
return (
<Navbar>
<div className='tab-buttons tabbar'>
{tabs.map((item, index) =>
<Link key={"de-link-" + item.id} tabLink={"#" + item.id} tabLinkActive={index === 0}>
<Icon slot="media" icon={item.icon}></Icon>
</Link>)}
{isAndroid && <span className='tab-link-highlight' style={{width: 100 / tabs.lenght + '%'}}></span>}
</div>
{tabs.length > 1 ?
<div className='tab-buttons tabbar'>
{tabs.map((item, index) =>
<Link key={"de-link-" + item.id} tabLink={"#" + item.id} tabLinkActive={index === 0}>
<Icon slot="media" icon={item.icon}></Icon>
</Link>)}
{isAndroid && <span className='tab-link-highlight' style={{width: 100 / tabs.lenght + '%'}}></span>}
</div> :
<NavTitle>{ tabs[0].caption }</NavTitle>
}
{ !inPopover && <NavRight><Link icon='icon-expand-down' popupClose=".add-popup"></Link></NavRight> }
</Navbar>
)
@ -73,31 +79,41 @@ const AddLayoutContent = ({ tabs }) => {
const AddTabs = props => {
const { t } = useTranslation();
const _t = t('Add', {returnObjects: true});
const showPanels = props.showPanels;
const tabs = [];
tabs.push({
caption: _t.textTable,
id: 'add-table',
icon: 'icon-add-table',
component: <AddTableController />
});
tabs.push({
caption: _t.textShape,
id: 'add-shape',
icon: 'icon-add-shape',
component: <AddShapeController />
});
tabs.push({
caption: _t.textImage,
id: 'add-image',
icon: 'icon-add-image',
component: <AddImageController />
});
tabs.push({
caption: _t.textOther,
id: 'add-other',
icon: 'icon-add-other',
component: <AddOtherController />
});
if (!showPanels) {
tabs.push({
caption: _t.textTable,
id: 'add-table',
icon: 'icon-add-table',
component: <AddTableController/>
});
tabs.push({
caption: _t.textShape,
id: 'add-shape',
icon: 'icon-add-shape',
component: <AddShapeController/>
});
tabs.push({
caption: _t.textImage,
id: 'add-image',
icon: 'icon-add-image',
component: <AddImageController/>
});
tabs.push({
caption: _t.textOther,
id: 'add-other',
icon: 'icon-add-other',
component: <AddOtherController/>
});
}
if (showPanels && showPanels === 'link') {
tabs.push({
caption: _t.textAddLink,
id: 'add-link',
component: <AddLinkController noNavbar={true}/>
});
}
return (
<View style={props.style} stackPages={true} routes={routes}>
<Page pageContent={false}>
@ -122,10 +138,10 @@ class AddView extends Component {
return (
show_popover ?
<Popover id="add-popover" className="popover__titled" onPopoverClosed={() => this.props.onclosed()}>
<AddTabs inPopover={true} onOptionClick={this.onoptionclick} style={{height: '410px'}} />
<AddTabs inPopover={true} onOptionClick={this.onoptionclick} style={{height: '410px'}} showPanels={this.props.showPanels} />
</Popover> :
<Popup className="add-popup" onPopupClosed={() => this.props.onclosed()}>
<AddTabs onOptionClick={this.onoptionclick} />
<AddTabs onOptionClick={this.onoptionclick} showPanels={this.props.showPanels} />
</Popup>
)
}
@ -145,7 +161,7 @@ const Add = props => {
if ( props.onclosed )
props.onclosed();
};
return <AddView usePopover={!Device.phone} onclosed={onviewclosed} />
return <AddView usePopover={!Device.phone} onclosed={onviewclosed} showPanels={props.showOptions} />
};
export default Add;

View file

@ -0,0 +1,51 @@
import React, {useState} from 'react';
import {List, Page, Navbar, Icon, ListButton, ListInput} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import {Device} from "../../../../../common/mobile/utils/device";
const PageLink = props => {
const { t } = useTranslation();
const _t = t('Add', {returnObjects: true});
let display = props.getDisplayLinkText();
display = typeof display === 'string' ? display : '';
const [stateLink, setLink] = useState('');
const [stateDisplay, setDisplay] = useState(display);
const [stateTip, setTip] = useState('');
return (
<Page>
{!props.noNavbar && <Navbar title={_t.textAddLink} backLink={_t.textBack}></Navbar>}
<List inlineLabels className='inputs-list'>
<ListInput
label={_t.textLink}
type="text"
placeholder={_t.textLink}
value={stateLink}
onChange={(event) => {setLink(event.target.value)}}
></ListInput>
<ListInput
label={_t.textDisplay}
type="text"
placeholder={_t.textDisplay}
value={stateDisplay}
onChange={(event) => {setDisplay(event.target.value)}}
></ListInput>
<ListInput
label={_t.textScreenTip}
type="text"
placeholder={_t.textScreenTip}
value={stateTip}
onChange={(event) => {setTip(event.target.value)}}
></ListInput>
</List>
<List>
<ListButton className={'button-fill button-raised' + (stateLink.length < 1 ? ' disabled' : '')} title={_t.textInsert} onClick={() => {
props.onInsertLink(stateLink, stateDisplay, stateTip)
}}></ListButton>
</List>
</Page>
)
};
export {PageLink as PageAddLink};

View file

@ -4,51 +4,6 @@ import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, BlockTitle, S
import { useTranslation } from 'react-i18next';
import {Device} from "../../../../../common/mobile/utils/device";
const PageLink = props => {
const { t } = useTranslation();
const _t = t('Add', {returnObjects: true});
let display = props.getDisplayLinkText();
display = typeof display === 'string' ? display : '';
const [stateLink, setLink] = useState('');
const [stateDisplay, setDisplay] = useState(display);
const [stateTip, setTip] = useState('');
return (
<Page>
<Navbar title={_t.textAddLink} backLink={_t.textBack}></Navbar>
<List inlineLabels className='inputs-list'>
<ListInput
label={_t.textLink}
type="text"
placeholder={_t.textLink}
value={stateLink}
onChange={(event) => {setLink(event.target.value)}}
></ListInput>
<ListInput
label={_t.textDisplay}
type="text"
placeholder={_t.textDisplay}
value={stateDisplay}
onChange={(event) => {setDisplay(event.target.value)}}
></ListInput>
<ListInput
label={_t.textScreenTip}
type="text"
placeholder={_t.textScreenTip}
value={stateTip}
onChange={(event) => {setTip(event.target.value)}}
></ListInput>
</List>
<List>
<ListButton className={'button-fill button-raised' + (stateLink.length < 1 ? ' disabled' : '')} title={_t.textInsert} onClick={() => {
props.onInsertLink(stateLink, stateDisplay, stateTip)
}}></ListButton>
</List>
</Page>
)
};
const PageNumber = props => {
const { t } = useTranslation();
const _t = t('Add', {returnObjects: true});
@ -240,7 +195,6 @@ const AddOther = props => {
const AddOtherContainer = inject("storeComments")(observer(AddOther));
export {AddOtherContainer as AddOther,
PageLink as PageAddLink,
PageNumber as PageAddNumber,
PageBreak as PageAddBreak,
PageSectionBreak as PageAddSectionBreak,