[PE mobile] Make Link Settings

This commit is contained in:
SergeyEzhin 2021-01-29 22:52:14 +03:00
parent 338776c1a0
commit f9e91266a5
6 changed files with 338 additions and 5 deletions

View file

@ -228,7 +228,22 @@
"textStyleOptions": "Style Options",
"textRemoveTable": "Remove Table",
"textCellMargins": "Cell Margins",
"textRemoveChart": "Remove Chart"
"textRemoveChart": "Remove Chart",
"textLinkType": "Link Type",
"textExternalLink": "External Link",
"textSlideInThisPresentation": "Slide in this Presentation",
"textLink": "Link",
"textLinkTo": "Link to",
"textNextSlide": "Next Slide",
"textPreviousSlide": "Previous Slide",
"textFirstSlide": "First Slide",
"textLastSlide": "Last Slide",
"textSlideNumber": "Slide Number",
"textEditLink": "Edit Link",
"textRemoveLink": "Remove Link",
"textDisplay": "Display",
"textScreenTip": "Screen Tip",
"textDefault": "Selected text"
}
},
"Common": {

View file

@ -5,7 +5,7 @@ import { f7 } from "framework7-react";
import { withTranslation } from 'react-i18next';
import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx'
@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings")
@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings", "storeLinkSettings")
class MainController extends Component {
constructor(props) {
super(props)
@ -316,6 +316,14 @@ class MainController extends Component {
storeChartSettings.updateChartStyles(this.api.asc_getChartPreviews(storeFocusObjects.chartObject.getType()));
}
});
// Link settings
const storeLinkSettings = this.props.storeLinkSettings;
this.api.asc_registerCallback('asc_onCanAddHyperlink', (value) => {
storeLinkSettings.canAddHyperlink(value);
});
}
_onDocumentContentReady() {

View file

@ -0,0 +1,114 @@
import React, { Component } from 'react';
import { f7 } from 'framework7-react';
import { Device } from '../../../../../common/mobile/utils/device';
import {observer, inject} from "mobx-react";
import { withTranslation } from 'react-i18next';
import { EditLink } from '../../view/edit/EditLink';
class EditLinkController extends Component {
constructor (props) {
super(props);
this.onEditLink = this.onEditLink.bind(this);
this.onRemoveLink = this.onRemoveLink.bind(this);
}
closeModal () {
if ( Device.phone ) {
f7.sheet.close('#edit-sheet', true);
} else {
f7.popover.close('#edit-popover');
}
}
onEditLink(type, linkInfo) {
const api = Common.EditorApi.get();
const { t } = this.props;
const _t = t("View.Edit", { returnObjects: true });
const c_oHyperlinkType = {
InternalLink: 0,
WebLink: 1
};
const display = linkInfo.display;
const tip = linkInfo.tip;
const props = new Asc.CHyperlinkProperty();
let def_display = '';
if (type == c_oHyperlinkType.WebLink) {
let url = linkInfo.url;
const urltype = api.asc_getUrlType(url.trim());
const isEmail = (urltype == 2);
if (urltype < 1) {
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
return;
}
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'), " ");
props.put_Value(url);
props.put_ToolTip(tip);
def_display = url;
} else {
let url = "ppaction://hlink";
let slidetip = '';
switch (linkInfo.linkTo) {
case 0:
url = url + "showjump?jump=nextslide";
slidetip = _t.textNextSlide;
break;
case 1:
url = url + "showjump?jump=previousslide";
slidetip = _t.textPrevSlide;
break;
case 2:
url = url + "showjump?jump=firstslide";
slidetip = _t.textFirstSlide;
break;
case 3:
url = url + "showjump?jump=lastslide";
slidetip = _t.textLastSlide;
break;
case 4:
url = url + "sldjumpslide" + linkInfo.numberTo;
slidetip = _t.textSlide + ' ' + (linkInfo.numberTo + 1);
break;
}
props.put_Value(url);
props.put_ToolTip(!tip ? slidetip : tip);
def_display = slidetip;
}
if (!linkInfo.displayDisabled) {
props.put_Text(!display ? def_display : display);
} else
props.put_Text(null);
api.change_Hyperlink(props);
this.closeModal();
}
onRemoveLink() {
const api = Common.EditorApi.get();
api.remove_Hyperlink();
this.closeModal();
}
render () {
return (
<EditLink
onEditLink={this.onEditLink}
onRemoveLink={this.onRemoveLink}
/>
)
}
}
const EditLinkWithTranslation = withTranslation()(EditLinkController);
export {EditLinkWithTranslation as EditLinkController};

View file

@ -172,4 +172,19 @@ export class storeFocusObjects {
getTopObject(charts);
getTopObject(shapes);
}
@computed get linkObject() {
const links = [];
for (let object of this._focusObjects) {
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
links.push(object);
}
}
if (links.length > 0) {
const object = links[links.length - 1]; // get top
return object.get_ObjectValue();
} else {
return undefined;
}
}
}

View file

@ -11,6 +11,7 @@ import EditShapeController from "../../controller/edit/EditShape";
import EditImageController from "../../controller/edit/EditImage";
import EditTableController from "../../controller/edit/EditTable";
import EditChartController from "../../controller/edit/EditChart";
import { EditLinkController } from "../../controller/edit/EditLink";
import { Theme, Layout, Transition, Type, Effect, StyleFillColor, CustomFillColor } from './EditSlide';
import { PageTextFonts, PageTextFontColor, PageTextCustomFontColor, PageTextAddFormatting, PageTextBullets, PageTextNumbers, PageTextLineSpacing } from './EditText';
@ -18,7 +19,7 @@ import { PageShapeStyle, PageShapeStyleNoFill, PageReplaceContainer, PageReorder
import { PageImageReplace, PageImageReorder, PageImageAlign, PageLinkSettings } from './EditImage';
import { PageTableStyle, PageTableStyleOptions, PageTableCustomFillColor, PageTableBorderColor, PageTableCustomBorderColor, PageTableReorder, PageTableAlign } from './EditTable';
import { PageChartStyle, PageChartCustomFillColor, PageChartBorderColor, PageChartCustomBorderColor, PageChartReorder, PageChartAlign } from './EditChart'
//import EditLinkController from "../../controller/edit/EditLink";
import { PageLinkTo, PageTypeLink } from './EditLink'
const routes = [
@ -194,6 +195,17 @@ const routes = [
{
path: '/edit-chart-custom-fill-color/',
component: PageChartCustomFillColor
},
// Link
{
path: '/edit-link-type/',
component: PageTypeLink
},
{
path: '/edit-link-to/',
component: PageLinkTo
}
];
@ -303,14 +315,13 @@ const EditTabs = props => {
component: <EditChartController />
})
}
/*
if (settings.indexOf('hyperlink') > -1) {
editors.push({
caption: _t.textHyperlink,
id: 'edit-link',
component: <EditLinkController />
})
}*/
}
}
return (

View file

@ -0,0 +1,170 @@
import React, {useState} from 'react';
import {observer, inject} from "mobx-react";
import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, Segmented, Button} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import {Device} from "../../../../../common/mobile/utils/device";
const PageTypeLink = props => {
const { t } = useTranslation();
const _t = t('View.Edit', {returnObjects: true});
const [typeLink, setTypeLink] = useState(props.curType);
return (
<Page>
<Navbar title={_t.textLinkType} backLink={_t.textBack}/>
<List>
<ListItem title={_t.textExternalLink} radio checked={typeLink === 1} onClick={() => {setTypeLink(1); props.changeType(1);}}></ListItem>
<ListItem title={_t.textSlideInThisPresentation} radio checked={typeLink === 0} onClick={() => {setTypeLink(0); props.changeType(0);}}></ListItem>
</List>
</Page>
)
};
const PageLinkTo = props => {
const isAndroid = Device.android;
const { t } = useTranslation();
const _t = t('View.Edit', {returnObjects: true});
const api = Common.EditorApi.get();
const slidesCount = api.getCountPages();
console.log(slidesCount);
const [stateTypeTo, setTypeTo] = useState(props.curTo);
const changeTypeTo = (type) => {
setTypeTo(type);
props.changeTo(type);
};
const [stateNumberTo, setNumberTo] = useState(0);
const changeNumber = (curNumber, isDecrement) => {
setTypeTo(4);
let value;
if (isDecrement) {
value = curNumber < slidesCount ? 0 : curNumber - 1;
} else {
value = curNumber >= slidesCount ? slidesCount : curNumber;
}
setNumberTo(value);
props.changeTo(4, value);
};
return (
<Page>
<Navbar title={_t.textLinkTo} backLink={_t.textBack}/>
<List>
<ListItem title={_t.textNextSlide} radio checked={stateTypeTo === 0} onClick={() => {changeTypeTo(0)}}></ListItem>
<ListItem title={_t.textPreviousSlide} radio checked={stateTypeTo === 1} onClick={() => {changeTypeTo(1)}}></ListItem>
<ListItem title={_t.textFirstSlide} radio checked={stateTypeTo === 2} onClick={() => {changeTypeTo(2)}}></ListItem>
<ListItem title={_t.textLastSlide} radio checked={stateTypeTo === 3} onClick={() => {changeTypeTo(3)}}></ListItem>
<ListItem title={_t.textSlideNumber}>
{!isAndroid && <div slot='after-start'>{stateNumberTo + 1}</div>}
<div slot='after'>
<Segmented>
<Button outline className='decrement item-link' onClick={() => {changeNumber(stateNumberTo, true);}}>
{isAndroid ? <Icon icon="icon-expand-down"></Icon> : ' - '}
</Button>
{isAndroid && <label>{stateNumberTo + 1}</label>}
<Button outline className='increment item-link' onClick={() => {changeNumber(stateNumberTo, false);}}>
{isAndroid ? <Icon icon="icon-expand-up"></Icon> : ' + '}
</Button>
</Segmented>
</div>
</ListItem>
</List>
</Page>
)
};
const EditLink = props => {
const { t } = useTranslation();
const _t = t('View.Edit', {returnObjects: true});
const storeFocusObjects = props.storeFocusObjects;
const linkObject = storeFocusObjects.linkObject;
const valueLinkObject = linkObject.get_Value();
const tooltipLinkObject = linkObject.get_ToolTip();
const [typeLink, setTypeLink] = useState(1);
const textType = typeLink === 1 ? _t.textExternalLink : _t.textSlideInThisPresentation;
const changeType = (newType) => {
setTypeLink(newType);
};
const [link, setLink] = useState(valueLinkObject ? [valueLinkObject.replace(new RegExp(" ", 'g'), "%20")] : '');
const [linkTo, setLinkTo] = useState(0);
const [displayTo, setDisplayTo] = useState(_t.textNextSlide);
const [numberTo, setNumberTo] = useState(0);
const changeTo = (type, number) => {
setLinkTo(type);
switch (type) {
case 0 : setDisplayTo(_t.textNextSlide); break;
case 1 : setDisplayTo(_t.textPreviousSlide); break;
case 2 : setDisplayTo(_t.textFirstSlide); break;
case 3 : setDisplayTo(_t.textLastSlide); break;
case 4 : setDisplayTo(`${_t.textSlide} ${number + 1}`); setNumberTo(number); break;
}
};
const display = linkObject.get_Text();
const displayDisabled = display !== false && display === null;
const [stateDisplay, setDisplay] = useState(display !== false ? ((display !== null) ? display : _t.textDefault) : "");
const [screenTip, setScreenTip] = useState(tooltipLinkObject);
return (
<Page>
<Navbar title={_t.textLink} backLink={_t.textBack}/>
<List inlineLabels className='inputs-list'>
<ListItem link={'/edit-link-type/'} title={_t.textLinkType} after={textType} routeProps={{
changeType: changeType,
curType: typeLink
}}/>
{typeLink === 1 ?
<ListInput label={_t.textLink}
type="text"
placeholder={_t.textLink}
value={link}
onChange={(event) => {setLink(event.target.value)}}
/> :
<ListItem link={'/edit-link-to/'} title={_t.textLinkTo} after={displayTo} routeProps={{
changeTo: changeTo,
curTo: linkTo
}}/>
}
<ListInput label={_t.textDisplay}
type="text"
placeholder={_t.textDisplay}
value={stateDisplay}
disabled={displayDisabled}
onChange={(event) => {setDisplay(event.target.value)}}
/>
<ListInput label={_t.textScreenTip}
type="text"
placeholder={_t.textScreenTip}
value={screenTip}
onChange={(event) => {setScreenTip(event.target.value)}}
/>
</List>
<List>
<ListButton title={_t.textEditLink} className={`button-fill button-raised${typeLink === 1 && link.length < 1 && ' disabled'}`} onClick={() => {
props.onEditLink(typeLink, (typeLink === 1 ?
{url: link, display: stateDisplay, tip: screenTip, displayDisabled: displayDisabled } :
{linkTo: linkTo, numberTo: numberTo, display: stateDisplay, tip: screenTip, displayDisabled: displayDisabled}));
}} />
<ListButton title={_t.textRemoveLink} onClick={props.onRemoveLink} className='button-fill button-red' />
</List>
</Page>
)
};
const PageEditLink = inject("storeFocusObjects")(observer(EditLink));
export {
PageEditLink as EditLink,
PageLinkTo,
PageTypeLink
}