Proof of concept JS-side communication between map component and plugin

pull/384/head
Piero Toffanin 2018-01-30 17:41:32 -05:00
rodzic d0b4a058bf
commit e5a6628f4b
11 zmienionych plików z 81 dodań i 7 usunięć

Wyświetl plik

@ -88,7 +88,6 @@ def boot():
# Unlock any Task that might have been locked
Task.objects.filter(processing_lock=True).update(processing_lock=False)
# Register plugins
register_plugins()
if not settings.TESTING:

Wyświetl plik

@ -24,8 +24,19 @@ class PluginBase(ABC):
def get_module_name(self):
return self.__class__.__module__
def get_include_js_urls(self):
return ["/plugins/{}/{}".format(self.get_name(), js_file) for js_file in self.include_js_files()]
def has_public_path(self):
return os.path.isdir(self.get_path("public"))
def include_js_files(self):
"""
Should be overriden by plugins to communicate
which JS files should be included in the WebODM interface
All paths are relative to a plugin's /public folder.
"""
return []
def __str__(self):
return "[{}]".format(self.get_module_name())

Wyświetl plik

@ -0,0 +1,26 @@
import { EventEmitter } from 'fbemitter';
import Utils from './Utils';
const { assert } = Utils;
if (!window.PluginsAPI){
const events = new EventEmitter();
window.PluginsAPI = {
Map: {
AddPanel: (callback) => {
events.addListener('Map::Loaded', callback);
},
Loaded: (params) => {
assert(params.map !== undefined);
events.emit('Map::Loaded', params);
}
},
events
};
}
export default window.PluginsAPI;

Wyświetl plik

@ -63,6 +63,16 @@ export default {
parser.href = href;
return `${parser.protocol}//${parser.host}/${path}`;
},
assert: function(condition, message) {
if (!condition) {
message = message || "Assertion failed";
if (typeof Error !== "undefined") {
throw new Error(message);
}
throw message; // Fallback
}
}
};

Wyświetl plik

@ -1,6 +1,4 @@
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import ReactDOM from 'react-dom';
import '../css/Map.scss';
import 'leaflet/dist/leaflet.css';
import Leaflet from 'leaflet';
@ -17,6 +15,7 @@ import SwitchModeButton from './SwitchModeButton';
import ShareButton from './ShareButton';
import AssetDownloads from '../classes/AssetDownloads';
import PropTypes from 'prop-types';
import PluginsAPI from '../classes/PluginsAPI';
class Map extends React.Component {
static defaultProps = {
@ -236,6 +235,13 @@ class Map extends React.Component {
}
});
});
// PluginsAPI.events.addListener('Map::AddPanel', (e) => {
// console.log("Received response: " + e);
// });
PluginsAPI.Map.Loaded({
map: this.map
});
}
componentDidUpdate(prevProps) {

Wyświetl plik

@ -1,9 +1,10 @@
import '../css/main.scss';
import './django/csrf';
import ReactDOM from 'react-dom';
import PluginsAPI from './classes/PluginsAPI';
// Main is always executed first in the page
// We share the ReactDOM object to avoid having to include it
// as a dependency in each component (adds too much space overhead)
window.ReactDOM = ReactDOM;
window.ReactDOM = ReactDOM;

Wyświetl plik

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% load i18n static settings compress %}
{% load i18n static settings compress plugins %}
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
@ -22,6 +22,10 @@
{% load render_bundle from webpack_loader %}
{% render_bundle 'main' %}
{% autoescape off %}
{% get_plugins_js_includes %}
{% endautoescape %}
<title>{{title|default:"Login"}} - {{ SETTINGS.app_name }}</title>
{% compress css %}

Wyświetl plik

@ -0,0 +1,11 @@
from django import template
from app.plugins import get_active_plugins
import itertools
register = template.Library()
@register.simple_tag(takes_context=False)
def get_plugins_js_includes():
# Flatten all urls for all plugins
js_urls = list(itertools.chain(*[plugin.get_include_js_urls() for plugin in get_active_plugins()]))
return "\n".join(map(lambda url: "<script src='{}'></script>".format(url), js_urls))

Wyświetl plik

@ -35,6 +35,7 @@
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"extract-text-webpack-plugin": "^3.0.0",
"fbemitter": "^2.1.1",
"file-loader": "^0.9.0",
"gl-matrix": "^2.3.2",
"history": "^4.7.2",

Wyświetl plik

@ -3,4 +3,7 @@ from app.plugins import PluginBase
class Plugin(PluginBase):
def register(self):
print("I'm registering!!!")
print("I'm registering!!!")
def include_js_files(self):
return ['hello.js']

Wyświetl plik

@ -1 +1,3 @@
console.log("HI!!");
PluginsAPI.Map.AddPanel(function(params){
console.log("GOT: ", params.map);
});