[PE mobile] added app sources
This commit is contained in:
parent
239e2a9e55
commit
9f7a6b9e7c
|
@ -1,274 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
<title>ONLYOFFICE Presentations</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:400,300,500,700" rel="stylesheet" type="text/css">
|
||||
<!-- App styles -->
|
||||
|
||||
<!-- splash -->
|
||||
|
||||
<style type="text/css">
|
||||
.loadmask {
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
background-color: #f4f4f4;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
height: 68px;
|
||||
background-color: #e2e2e2;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel.android {
|
||||
height: 80px;
|
||||
background: #aa5252;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel > div {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel .loading-logo {
|
||||
max-width: 200px;
|
||||
height: 20px;
|
||||
margin: 0 auto;
|
||||
margin-top: 12px;
|
||||
line-height: 14px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel .loading-logo > img {
|
||||
display: inline-block;
|
||||
max-width: 100px;
|
||||
max-height: 20px;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel .circle {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 14px;
|
||||
margin: 0 16px;
|
||||
margin-bottom: 10px;
|
||||
align-self: flex-end;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel.android .circle {
|
||||
margin-bottom: 12px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.loadmask > .placeholder {
|
||||
background: #f5f5f5;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder.android {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder .slide-h {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
flex-grow: 1;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.loadmask > .placeholder .slide-v {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
padding-bottom: 56.1333%;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder .slide-container {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #fbfbfb;
|
||||
border: 1px solid #dfdfdf;
|
||||
|
||||
-webkit-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
-moz-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
-o-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
animation: flickerAnimation 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder .slide-container > .line {
|
||||
height: 20%;
|
||||
margin: 0 120px;
|
||||
border-radius: 6px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder .slide-container > .line.empty {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder .slide-container > .line:nth-child(1) {
|
||||
height: 30%;
|
||||
margin: 10% 80px 0;
|
||||
}
|
||||
|
||||
@keyframes flickerAnimation {
|
||||
0% { opacity:1; }
|
||||
50% { opacity:0.3; }
|
||||
100% { opacity:1; }
|
||||
}
|
||||
@-o-keyframes flickerAnimation{
|
||||
0% { opacity:1; }
|
||||
50% { opacity:0.3; }
|
||||
100% { opacity:1; }
|
||||
}
|
||||
@-moz-keyframes flickerAnimation{
|
||||
0% { opacity:1; }
|
||||
50% { opacity:0.3; }
|
||||
100% { opacity:1; }
|
||||
}
|
||||
@-webkit-keyframes flickerAnimation{
|
||||
0% { opacity:1; }
|
||||
50% { opacity:0.3; }
|
||||
100% { opacity:1; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading-mask" class="loadmask">
|
||||
<div class="brendpanel">
|
||||
<div>
|
||||
<div class="circle"></div>
|
||||
<div class="loading-logo">
|
||||
</div>
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="placeholder">
|
||||
<div class="slide-h">
|
||||
<div class="slide-v">
|
||||
<div class="slide-container">
|
||||
<div class="line"></div>
|
||||
<div class="line empty"></div>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
function getUrlParams() {
|
||||
var e,
|
||||
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||
r = /([^&=]+)=?([^&]*)/g,
|
||||
d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
|
||||
q = window.location.search.substring(1),
|
||||
urlParams = {};
|
||||
|
||||
while (e = r.exec(q))
|
||||
urlParams[d(e[1])] = d(e[2]);
|
||||
|
||||
return urlParams;
|
||||
}
|
||||
|
||||
function encodeUrlParam(str) {
|
||||
return str.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
var params = getUrlParams(),
|
||||
lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
|
||||
logo = /*params["headerlogo"] ? encodeUrlParam(params["headerlogo"]) : */null;
|
||||
var logoOO = null;
|
||||
if (!logo) {
|
||||
logoOO = /Android/.test(navigator.userAgent) ? "../../common/mobile/resources/img/header/header-logo-android.png" : "../../common/mobile/resources/img/header/header-logo-ios.png";
|
||||
}
|
||||
|
||||
window.frameEditorId = params["frameEditorId"];
|
||||
window.parentOrigin = params["parentOrigin"];
|
||||
|
||||
var brendpanel = document.getElementsByClassName('brendpanel')[0];
|
||||
if (brendpanel) {
|
||||
if (/Android/.test(navigator.userAgent)) {
|
||||
brendpanel.classList.add('android');
|
||||
}
|
||||
brendpanel.classList.add('visible');
|
||||
var elem = document.querySelector('.loading-logo');
|
||||
if (elem) {
|
||||
logo && (elem.innerHTML = '<img src=' + logo + '>');
|
||||
logoOO && (elem.innerHTML = '<img src=' + logoOO + '>');
|
||||
elem.style.opacity = 1;
|
||||
}
|
||||
}
|
||||
var placeholder = document.getElementsByClassName('placeholder')[0];
|
||||
if (placeholder && /Android/.test(navigator.userAgent)) {
|
||||
placeholder.classList.add('android');
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/xregexp/xregexp-all-min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../../../../sdkjs/develop/sdkjs/slide/scripts.js"></script>
|
||||
<script>
|
||||
var ua = navigator.userAgent;
|
||||
|
||||
if (/Sailfish/.test(ua) || /Jolla/.test(ua)) {
|
||||
document.write('<script type="text/javascript" src="../../../vendor/iscroll/iscroll.min.js"><\/script>');
|
||||
|
||||
if (!/Android/.test(ua)) {
|
||||
var ua = navigator.userAgent + ';Android 5.0;';
|
||||
Object.defineProperty(navigator, 'userAgent', {
|
||||
get: function () { return ua; }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.sdk_scripts.forEach(function(item){
|
||||
document.write('<script type="text/javascript" src="' + item + '"><\/script>');
|
||||
});
|
||||
|
||||
window.requireTimeourError = function(){
|
||||
var reqerr;
|
||||
|
||||
if ( lang == 'de') reqerr = 'Die Verbindung ist zu langsam, einige Komponenten konnten nicht geladen werden. Aktualisieren Sie bitte die Seite.';
|
||||
else if ( lang == 'es') reqerr = 'La conexión es muy lenta, algunos de los componentes no han podido cargar. Por favor recargue la página.';
|
||||
else if ( lang == 'fr') reqerr = 'La connexion est trop lente, certains des composants n\'ons pas pu être chargé. Veuillez recharger la page.';
|
||||
else if ( lang == 'ru') reqerr = 'Слишком медленное соединение, не удается загрузить некоторые компоненты. Пожалуйста, обновите страницу.';
|
||||
else reqerr = 'The connection is too slow, some of the components could not be loaded. Please reload the page.';
|
||||
|
||||
return reqerr;
|
||||
};
|
||||
</script>
|
||||
<!-- application -->
|
||||
<script data-main="app-dev" src="../../../vendor/requirejs/require.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
42
apps/presentationeditor/mobile/src/app.js
Normal file
42
apps/presentationeditor/mobile/src/app.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Import React and ReactDOM
|
||||
import React, { Suspense } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
// Import Framework7
|
||||
import Framework7 from 'framework7/framework7-lite.esm.bundle.js';
|
||||
|
||||
// Import Framework7-React Plugin
|
||||
import Framework7React from 'framework7-react';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
window.jQuery = jQuery;
|
||||
window.$ = jQuery;
|
||||
|
||||
// Import Framework7 Styles
|
||||
import 'framework7/css/framework7.bundle.css';
|
||||
|
||||
// Import App Custom Styles
|
||||
import './less/app.less';
|
||||
|
||||
// Import App Component
|
||||
import App from './page/app';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import i18n from './lib/i18n.js';
|
||||
|
||||
import { Provider } from 'mobx-react'
|
||||
import { stores } from './store/mainStore'
|
||||
|
||||
// Init F7 React Plugin
|
||||
Framework7.use(Framework7React)
|
||||
|
||||
// Mount React App
|
||||
ReactDOM.render(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<Provider {...stores}>
|
||||
<Suspense fallback="loading">
|
||||
<App />
|
||||
</Suspense>
|
||||
</Provider>
|
||||
</I18nextProvider>,
|
||||
document.getElementById('app'),
|
||||
);
|
205
apps/presentationeditor/mobile/src/controller/Main.jsx
Normal file
205
apps/presentationeditor/mobile/src/controller/Main.jsx
Normal file
|
@ -0,0 +1,205 @@
|
|||
|
||||
import React, { Component } from 'react'
|
||||
import { inject } from "mobx-react";
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx'
|
||||
|
||||
class MainController extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
initSdk() {
|
||||
const script = document.createElement("script");
|
||||
script.src = "../../../../sdkjs/develop/sdkjs/slide/scripts.js";
|
||||
script.async = true;
|
||||
script.onload = () => {
|
||||
let dep_scripts = [
|
||||
'../../../vendor/xregexp/xregexp-all-min.js',
|
||||
'../../../vendor/sockjs/sockjs.min.js'];
|
||||
dep_scripts.push(...sdk_scripts);
|
||||
|
||||
const promise_get_script = (scriptpath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = scriptpath;
|
||||
script.onload = () => {
|
||||
resolve('ok');
|
||||
};
|
||||
script.onerror = () => {
|
||||
reject('error');
|
||||
};
|
||||
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
};
|
||||
|
||||
const loadConfig = data => {
|
||||
let me = this;
|
||||
console.log('load config');
|
||||
|
||||
me.editorConfig = Object.assign({}, this.editorConfig, data.config);
|
||||
me.appOptions.user = Common.Utils.fillUserInfo(me.editorConfig.user, me.editorConfig.lang, "Local.User"/*me.textAnonymous*/);
|
||||
};
|
||||
|
||||
const loadDocument = data => {
|
||||
this.permissions = {};
|
||||
this.document = data.doc;
|
||||
|
||||
let docInfo = {};
|
||||
|
||||
if (data.doc) {
|
||||
this.permissions = Object.assign(this.permissions, data.doc.permissions);
|
||||
|
||||
let _permissions = Object.assign({}, data.doc.permissions),
|
||||
_user = new Asc.asc_CUserInfo();
|
||||
_user.put_Id(this.appOptions.user.id);
|
||||
_user.put_FullName(this.appOptions.user.fullname);
|
||||
|
||||
docInfo = new Asc.asc_CDocInfo();
|
||||
docInfo.put_Id(data.doc.key);
|
||||
docInfo.put_Url(data.doc.url);
|
||||
docInfo.put_Title(data.doc.title);
|
||||
docInfo.put_Format(data.doc.fileType);
|
||||
docInfo.put_VKey(data.doc.vkey);
|
||||
docInfo.put_Options(data.doc.options);
|
||||
docInfo.put_UserInfo(_user);
|
||||
docInfo.put_CallbackUrl(this.editorConfig.callbackUrl);
|
||||
docInfo.put_Token(data.doc.token);
|
||||
docInfo.put_Permissions(_permissions);
|
||||
docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys);
|
||||
|
||||
// var enable = !this.editorConfig.customization || (this.editorConfig.customization.macros!==false);
|
||||
// docInfo.asc_putIsEnabledMacroses(!!enable);
|
||||
// enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false);
|
||||
// docInfo.asc_putIsEnabledPlugins(!!enable);
|
||||
}
|
||||
|
||||
this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions);
|
||||
// this.api.asc_registerCallback('asc_onLicenseChanged', _.bind(this.onLicenseChanged, this));
|
||||
// this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this));
|
||||
this.api.asc_setDocInfo(docInfo);
|
||||
this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId);
|
||||
|
||||
// Common.SharedSettings.set('document', data.doc);
|
||||
|
||||
// if (data.doc) {
|
||||
// DE.getController('Toolbar').setDocumentTitle(data.doc.title);
|
||||
// if (data.doc.info) {
|
||||
// data.doc.info.author && console.log("Obsolete: The 'author' parameter of the document 'info' section is deprecated. Please use 'owner' instead.");
|
||||
// data.doc.info.created && console.log("Obsolete: The 'created' parameter of the document 'info' section is deprecated. Please use 'uploaded' instead.");
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
const onEditorPermissions = params => {
|
||||
let me = this;
|
||||
const licType = params.asc_getLicenseType();
|
||||
|
||||
me.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
|
||||
// me.appOptions.canEdit = (me.permissions.edit !== false || me.permissions.review === true) && // can edit or review
|
||||
// (me.editorConfig.canRequestEditRights || me.editorConfig.mode !== 'view') && // if mode=="view" -> canRequestEditRights must be defined
|
||||
// (!me.appOptions.isReviewOnly || me.appOptions.canLicense) && // if isReviewOnly==true -> canLicense must be true
|
||||
// me.isSupportEditFeature();
|
||||
// me.appOptions.isEdit = me.appOptions.canLicense && me.appOptions.canEdit && me.editorConfig.mode !== 'view';
|
||||
|
||||
// me.api.asc_setViewMode(!me.appOptions.isEdit);
|
||||
me.api.asc_setViewMode(false);
|
||||
me.api.asc_LoadDocument();
|
||||
};
|
||||
|
||||
const _process_array = (array, fn) => {
|
||||
let results = [];
|
||||
return array.reduce(function(p, item) {
|
||||
return p.then(function() {
|
||||
return fn(item).then(function(data) {
|
||||
results.push(data);
|
||||
return results;
|
||||
});
|
||||
});
|
||||
}, Promise.resolve());
|
||||
};
|
||||
|
||||
_process_array(dep_scripts, promise_get_script)
|
||||
.then ( result => {
|
||||
const {t} = this.props;
|
||||
this.api = new Asc.asc_docs_api({
|
||||
'id-view': 'editor_sdk',
|
||||
'mobile': true,
|
||||
'translate': t('Controller.Main.SDK', {returnObjects:true})
|
||||
});
|
||||
|
||||
this.appOptions = {};
|
||||
this.bindEvents();
|
||||
|
||||
let value = null /*Common.localStorage.getItem("pe-settings-fontrender")*/;
|
||||
if (value===null) value = window.devicePixelRatio > 1 ? '1' : '3';
|
||||
this.api.SetFontRenderingMode(parseInt(value));
|
||||
this.api.SetDrawingFreeze(true);
|
||||
this.api.SetThemesPath("../../../../sdkjs/slide/themes/");
|
||||
// Common.Utils.Metric.setCurrentMetric(1); //pt
|
||||
|
||||
Common.Gateway.on('init', loadConfig);
|
||||
// Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me));
|
||||
Common.Gateway.on('opendocument', loadDocument);
|
||||
Common.Gateway.appReady();
|
||||
|
||||
Common.Notifications.trigger('engineCreated', this.api);
|
||||
Common.EditorApi = {get: () => this.api};
|
||||
}, error => {
|
||||
console.log('promise failed ' + error);
|
||||
});
|
||||
};
|
||||
|
||||
script.onerror = () => {
|
||||
console.log('error');
|
||||
};
|
||||
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
const me = this;
|
||||
// me.api.asc_registerCallback('asc_onError', _.bind(me.onError, me));
|
||||
me.api.asc_registerCallback('asc_onDocumentContentReady', me._onDocumentContentReady.bind(me));
|
||||
me.api.asc_registerCallback('asc_onOpenDocumentProgress', me._onOpenDocumentProgress.bind(me));
|
||||
// me.api.asc_registerCallback('asc_onDocumentUpdateVersion', _.bind(me.onUpdateVersion, me));
|
||||
// me.api.asc_registerCallback('asc_onServerVersion', _.bind(me.onServerVersion, me));
|
||||
// me.api.asc_registerCallback('asc_onAdvancedOptions', _.bind(me.onAdvancedOptions, me));
|
||||
// me.api.asc_registerCallback('asc_onDocumentName', _.bind(me.onDocumentName, me));
|
||||
// me.api.asc_registerCallback('asc_onPrintUrl', _.bind(me.onPrintUrl, me));
|
||||
// me.api.asc_registerCallback('asc_onThumbnailsShow', _.bind(me.onThumbnailsShow, me));
|
||||
// me.api.asc_registerCallback('asc_onMeta', _.bind(me.onMeta, me));
|
||||
}
|
||||
|
||||
_onDocumentContentReady() {
|
||||
const me = this;
|
||||
me.api.SetDrawingFreeze(false);
|
||||
|
||||
me.api.Resize();
|
||||
me.api.zoomFitToPage();
|
||||
// me.api.asc_GetDefaultTableStyles && _.defer(function () {me.api.asc_GetDefaultTableStyles()});
|
||||
|
||||
Common.Gateway.documentReady();
|
||||
}
|
||||
|
||||
_onOpenDocumentProgress(progress) {
|
||||
// if (this.loadMask) {
|
||||
// var $title = $$(this.loadMask).find('.modal-title'),
|
||||
// const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount());
|
||||
|
||||
// $title.text(this.textLoadingDocument + ': ' + Math.min(Math.round(proc * 100), 100) + '%');
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
return <CollaborationController />
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.initSdk();
|
||||
}
|
||||
}
|
||||
|
||||
const translated = withTranslation()(MainController);
|
||||
export {translated as MainController};
|
95
apps/presentationeditor/mobile/src/index_dev.html
Normal file
95
apps/presentationeditor/mobile/src/index_dev.html
Normal file
|
@ -0,0 +1,95 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
Customize this policy to fit your own app's needs. For more guidance, see:
|
||||
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
|
||||
Some notes:
|
||||
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||
-->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
|
||||
|
||||
<meta name="theme-color" content="#007aff">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<title>Presentation Editor</title>
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="static/icons/apple-touch-icon.png">
|
||||
<link rel="icon" href="static/icons/favicon.png">
|
||||
|
||||
|
||||
<!-- built styles file will be auto injected -->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
const isAndroid = /Android/.test(navigator.userAgent);
|
||||
if ( isAndroid && navigator.platform == 'Win32' )
|
||||
// Framework7 doesn't set Device.android flag when navigator.platform == 'Win32', change it for debug
|
||||
navigator.__defineGetter__('platform', () => 'Win32Debug');
|
||||
|
||||
const getUrlParams = () => {
|
||||
let e,
|
||||
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||
r = /([^&=]+)=?([^&]*)/g,
|
||||
d = s => decodeURIComponent(s.replace(a, " ")),
|
||||
q = window.location.search.substring(1),
|
||||
urlParams = {};
|
||||
|
||||
while (e = r.exec(q))
|
||||
urlParams[d(e[1])] = d(e[2]);
|
||||
|
||||
return urlParams;
|
||||
}
|
||||
|
||||
const encodeUrlParam = str => str.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
|
||||
let params = getUrlParams(),
|
||||
lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
|
||||
logo = /*params["headerlogo"] ? encodeUrlParam(params["headerlogo"]) : */null,
|
||||
logoOO = null;
|
||||
if (!logo) {
|
||||
logoOO = isAndroid ? "../../common/mobile/resources/img/header/header-logo-android.png" : "../../common/mobile/resources/img/header/header-logo-ios.png";
|
||||
}
|
||||
|
||||
window.frameEditorId = params["frameEditorId"];
|
||||
window.parentOrigin = params["parentOrigin"];
|
||||
window.Common = {Locale: {currentLang: lang}};
|
||||
|
||||
let brendpanel = document.getElementsByClassName('brendpanel')[0];
|
||||
if (brendpanel) {
|
||||
if ( isAndroid ) {
|
||||
brendpanel.classList.add('android');
|
||||
}
|
||||
brendpanel.classList.add('visible');
|
||||
|
||||
let elem = document.querySelector('.loading-logo');
|
||||
if (elem) {
|
||||
logo && (elem.innerHTML = '<img src=' + logo + '>');
|
||||
logoOO && (elem.innerHTML = '<img src=' + logoOO + '>');
|
||||
elem.style.opacity = 1;
|
||||
}
|
||||
var placeholder = document.getElementsByClassName('placeholder')[0];
|
||||
if (placeholder && isAndroid) {
|
||||
placeholder.classList.add('android');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- built script files will be auto injected -->
|
||||
|
||||
</body>
|
||||
</html>
|
5
apps/presentationeditor/mobile/src/less/app-ios.less
Normal file
5
apps/presentationeditor/mobile/src/less/app-ios.less
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
.device-ios {
|
||||
|
||||
|
||||
}
|
24
apps/presentationeditor/mobile/src/less/app-material.less
Normal file
24
apps/presentationeditor/mobile/src/less/app-material.less
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
// Colors
|
||||
@themeColorLight: #a2bdde;
|
||||
@navBarIconColor: #fff;
|
||||
|
||||
|
||||
.device-android {
|
||||
--f7-navbar-bg-color: @themeColor;
|
||||
--f7-navbar-link-color: @navBarIconColor;
|
||||
--f7-navbar-text-color: @navBarIconColor;
|
||||
|
||||
// Main Toolbar
|
||||
#editor-navbar.navbar .right {
|
||||
padding-right: 4px;
|
||||
}
|
||||
#editor-navbar.navbar .right a.link,
|
||||
#editor-navbar.navbar .left a.link {
|
||||
padding: 0 13px;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
}
|
||||
}
|
47
apps/presentationeditor/mobile/src/less/app.less
Normal file
47
apps/presentationeditor/mobile/src/less/app.less
Normal file
|
@ -0,0 +1,47 @@
|
|||
@themeColor: #446995;
|
||||
|
||||
@import '../../../../common/mobile/resources/less/_mixins.less';
|
||||
@import '../../../../common/mobile/resources/less/collaboration.less';
|
||||
@import '../../../../common/mobile/resources/less/common.less';
|
||||
@import '../../../../common/mobile/resources/less/common-ios.less';
|
||||
@import '../../../../common/mobile/resources/less/common-material.less';
|
||||
@import './app-material.less';
|
||||
@import './app-ios.less';
|
||||
@import './icons-ios.less';
|
||||
@import './icons-material.less';
|
||||
|
||||
/* Left Panel right border when it is visible by breakpoint */
|
||||
.panel-left.panel-in-breakpoint:before {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
content: '';
|
||||
z-index: 6000;
|
||||
}
|
||||
|
||||
/* Hide navbar link which opens left panel when it is visible by breakpoint */
|
||||
.panel-left.panel-in-breakpoint ~ .view .navbar .panel-open[data-panel="left"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Extra borders for main view and left panel for iOS theme when it behaves as panel (before breakpoint size)
|
||||
*/
|
||||
.ios .panel-left:not(.panel-in-breakpoint).panel-in ~ .view-main:before,
|
||||
.ios .panel-left:not(.panel-in-breakpoint).panel-closing ~ .view-main:before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
content: '';
|
||||
z-index: 6000;
|
||||
}
|
||||
|
||||
:root {
|
||||
--f7-popover-width: 360px;
|
||||
}
|
17
apps/presentationeditor/mobile/src/lib/i18n.js
Normal file
17
apps/presentationeditor/mobile/src/lib/i18n.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import i18n from 'i18next'
|
||||
import {initReactI18next} from 'react-i18next'
|
||||
import Fetch from 'i18next-fetch-backend'
|
||||
|
||||
i18n.use(initReactI18next)
|
||||
.use(Fetch)
|
||||
.init({
|
||||
lng: Common.Locale.currentLang,
|
||||
fallbackLng: "en",
|
||||
escapeValue: false,
|
||||
backend: {
|
||||
loadPath: './locale/{{lng}}.json'
|
||||
},
|
||||
interpolation: { escapeValue: false },
|
||||
});
|
||||
|
||||
export default i18n;
|
44
apps/presentationeditor/mobile/src/page/app.jsx
Normal file
44
apps/presentationeditor/mobile/src/page/app.jsx
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React from 'react';
|
||||
|
||||
import {App,Panel,Views,View,Popup,Page,Navbar,Toolbar,NavRight,Link,Block,BlockTitle,List,ListItem,ListInput,ListButton,BlockFooter} from 'framework7-react';
|
||||
|
||||
import routes from '../router/routes.js';
|
||||
|
||||
import '../../../../common/Gateway.js';
|
||||
import '../../../../common/main/lib/util/utils.js';
|
||||
import Notifications from '../../../../common/mobile/utils/notifications.js'
|
||||
import {MainController} from '../controller/Main';
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
// Framework7 Parameters
|
||||
f7params: {
|
||||
name: 'Presentation Editor', // App name
|
||||
theme: 'auto', // Automatic theme detection
|
||||
|
||||
// App routes
|
||||
routes: routes,
|
||||
},
|
||||
}
|
||||
|
||||
Common.Notifications = new Notifications();
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<App params={ this.state.f7params } >
|
||||
{/* Your main view, should have "view-main" class */}
|
||||
<View main className="safe-areas" url="/" />
|
||||
<MainController />
|
||||
</App>
|
||||
)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.$f7ready((f7) => {
|
||||
// Call F7 APIs here
|
||||
});
|
||||
}
|
||||
}
|
80
apps/presentationeditor/mobile/src/page/main.jsx
Normal file
80
apps/presentationeditor/mobile/src/page/main.jsx
Normal file
|
@ -0,0 +1,80 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Page, View, Navbar, NavLeft, NavRight, Link, Icon } from 'framework7-react';
|
||||
|
||||
// import EditOptions from '../view/edit/Edit';
|
||||
// import Settings from '../view/settings/Settings';
|
||||
import CollaborationView from '../../../../common/mobile/lib/view/Collaboration.jsx'
|
||||
|
||||
export default class MainPage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
editOptionsVisible: false,
|
||||
settingsVisible: false,
|
||||
collaborationVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
handleClickToOpenOptions = opts => {
|
||||
this.setState(state => {
|
||||
if ( opts == 'edit' )
|
||||
return {editOptionsVisible: true};
|
||||
else
|
||||
if ( opts == 'settings' )
|
||||
return {settingsVisible: true};
|
||||
else
|
||||
if ( opts == 'coauth' )
|
||||
return {collaborationVisible: true}
|
||||
});
|
||||
};
|
||||
|
||||
handleOptionsViewClosed = opts => {
|
||||
(async () => {
|
||||
await 1 && this.setState(state => {
|
||||
if ( opts == 'edit' )
|
||||
return {editOptionsVisible: false};
|
||||
else
|
||||
if ( opts == 'settings' )
|
||||
return {settingsVisible: false};
|
||||
else
|
||||
if ( opts == 'coauth' )
|
||||
return {collaborationVisible: false}
|
||||
})
|
||||
})();
|
||||
};
|
||||
|
||||
render() {
|
||||
console.log(this.$f7router)
|
||||
return (
|
||||
<Page name="home">
|
||||
{/* Top Navbar */}
|
||||
<Navbar id='editor-navbar'>
|
||||
<div slot="before-inner" className="main-logo"><Icon icon="icon-logo"></Icon></div>
|
||||
<NavLeft>
|
||||
<Link icon='icon-undo'></Link>
|
||||
<Link icon='icon-redo'></Link>
|
||||
</NavLeft>
|
||||
<NavRight>
|
||||
<Link id='btn-edit' icon='icon-edit-settings' href={false} onClick={e => this.handleClickToOpenOptions('edit')}></Link>
|
||||
<Link href={false} icon='icon-collaboration' onClick={e => this.handleClickToOpenOptions('coauth')}></Link>
|
||||
<Link id='btn-settings' icon='icon-settings' href={false} onClick={e => this.handleClickToOpenOptions('settings')}></Link>
|
||||
</NavRight>
|
||||
</Navbar>
|
||||
{/* Page content */}
|
||||
<View id="editor_sdk" />
|
||||
{/*{*/}
|
||||
{/*!this.state.editOptionsVisible ? null :*/}
|
||||
{/*<EditOptions onclosed={this.handleOptionsViewClosed.bind(this, 'edit')} />*/}
|
||||
{/*}*/}
|
||||
{/*{*/}
|
||||
{/*!this.state.settingsVisible ? null :*/}
|
||||
{/*<Settings onclosed={this.handleOptionsViewClosed.bind(this, 'settings')} />*/}
|
||||
{/*}*/}
|
||||
{
|
||||
!this.state.collaborationVisible ? null :
|
||||
<CollaborationView onclosed={this.handleOptionsViewClosed.bind(this, 'coauth')} />
|
||||
}
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
};
|
17
apps/presentationeditor/mobile/src/router/routes.js
Normal file
17
apps/presentationeditor/mobile/src/router/routes.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
import MainPage from '../page/main';
|
||||
|
||||
import { PageCollaboration, PageUsers } from '../../../../common/mobile/lib/view/Collaboration.jsx';
|
||||
|
||||
var routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: MainPage,
|
||||
},
|
||||
{
|
||||
path: '/users/',
|
||||
component: PageUsers
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
23
apps/presentationeditor/mobile/src/store/mainStore.js
Normal file
23
apps/presentationeditor/mobile/src/store/mainStore.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
// import {storeDocumentSettings} from './documentSettings';
|
||||
// import {storeFocusObjects} from "./focusObjects";
|
||||
import {storeUsers} from '../../../../common/mobile/lib/store/users';
|
||||
// import {storeTextSettings} from "./textSettings";
|
||||
// import {storeParagraphSettings} from "./paragraphSettings";
|
||||
// import {storeShapeSettings} from "./shapeSettings";
|
||||
// import {storeImageSettings} from "./imageSettings";
|
||||
// import {storeTableSettings} from "./tableSettings";
|
||||
// import {storeChartSettings} from "./chartSettings";
|
||||
|
||||
export const stores = {
|
||||
// storeFocusObjects: new storeFocusObjects(),
|
||||
// storeDocumentSettings: new storeDocumentSettings(),
|
||||
users: new storeUsers(),
|
||||
// storeTextSettings: new storeTextSettings(),
|
||||
// storeParagraphSettings: new storeParagraphSettings(),
|
||||
// storeShapeSettings: new storeShapeSettings(),
|
||||
// storeChartSettings: new storeChartSettings(),
|
||||
// storeImageSettings: new storeImageSettings(),
|
||||
// storeTableSettings: new storeTableSettings()
|
||||
};
|
||||
|
Loading…
Reference in a new issue