mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-15 01:17:16 -05:00
webui:
- added better live reload. It uses the Retroshare built in server. Grunt is not required anymore. - removed unused buttons - started ChatHandler git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8185 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
90d6ac6697
commit
b05ee805e4
@ -255,10 +255,13 @@ public:
|
|||||||
ApiServer::ApiServer():
|
ApiServer::ApiServer():
|
||||||
mMtx("ApiServer mMtx"),
|
mMtx("ApiServer mMtx"),
|
||||||
mStateTokenServer(),
|
mStateTokenServer(),
|
||||||
|
mLivereloadhandler(&mStateTokenServer),
|
||||||
mMainModules(0)
|
mMainModules(0)
|
||||||
{
|
{
|
||||||
mRouter.addResourceHandler("statetokenservice", dynamic_cast<ResourceRouter*>(&mStateTokenServer),
|
mRouter.addResourceHandler("statetokenservice", dynamic_cast<ResourceRouter*>(&mStateTokenServer),
|
||||||
&StateTokenServer::handleRequest);
|
&StateTokenServer::handleRequest);
|
||||||
|
mRouter.addResourceHandler("livereload", dynamic_cast<ResourceRouter*>(&mLivereloadhandler),
|
||||||
|
&LivereloadHandler::handleRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiServer::~ApiServer()
|
ApiServer::~ApiServer()
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "StateTokenServer.h"
|
#include "StateTokenServer.h"
|
||||||
#include "FileSearchHandler.h"
|
#include "FileSearchHandler.h"
|
||||||
#include "TransfersHandler.h"
|
#include "TransfersHandler.h"
|
||||||
|
#include "LivereloadHandler.h"
|
||||||
|
|
||||||
namespace resource_api{
|
namespace resource_api{
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ private:
|
|||||||
RsMutex mMtx;
|
RsMutex mMtx;
|
||||||
StateTokenServer mStateTokenServer; // goes first, as others may depend on it
|
StateTokenServer mStateTokenServer; // goes first, as others may depend on it
|
||||||
// is always loaded, because it has no dependencies
|
// is always loaded, because it has no dependencies
|
||||||
|
LivereloadHandler mLivereloadhandler;
|
||||||
|
|
||||||
// only pointers here, to load/unload modules at runtime
|
// only pointers here, to load/unload modules at runtime
|
||||||
ApiServerMainModules* mMainModules; // loaded when RS is started
|
ApiServerMainModules* mMainModules; // loaded when RS is started
|
||||||
|
1
libresapi/src/api/ChatHandler.cpp
Normal file
1
libresapi/src/api/ChatHandler.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "ChatHandler.h"
|
50
libresapi/src/api/ChatHandler.h
Normal file
50
libresapi/src/api/ChatHandler.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ResourceRouter.h"
|
||||||
|
#include "StateTokenServer.h"
|
||||||
|
#include <retroshare/rsnotify.h>
|
||||||
|
|
||||||
|
class RsMsgs;
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
class ChatHandler: public ResourceRouter, NotifyClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChatHandler(StateTokenServer* sts, RsNotify* notify, RsMsgs* msgs);
|
||||||
|
virtual ~ChatHandler();
|
||||||
|
|
||||||
|
// from NotifyClient
|
||||||
|
// note: this may get called from the own and from foreign threads
|
||||||
|
virtual void notifyChatMessage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleWildcard(Request& req, Response& resp);
|
||||||
|
|
||||||
|
StateTokenServer* mStateTokenServer;
|
||||||
|
RsNotify* mNotify;
|
||||||
|
RsMsgs* mRsMsgs;
|
||||||
|
|
||||||
|
RsMutex mMtx;
|
||||||
|
StateToken mStateToken; // mutex protected
|
||||||
|
|
||||||
|
// msgs flow like this:
|
||||||
|
// chatservice -> rawMsgs -> processedMsgs -> deletion
|
||||||
|
|
||||||
|
std::map<ChatId, std::list<ChatMessage> > mRawMsgs;
|
||||||
|
|
||||||
|
class Msg{
|
||||||
|
public:
|
||||||
|
bool incoming;
|
||||||
|
bool was_send;
|
||||||
|
//std::string chat_type;
|
||||||
|
std::string author_id; // peer or gxs id or "system" for system messages
|
||||||
|
std::string author_name;
|
||||||
|
std::string msg; // plain text only!
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<ChatId, std::list<Msg> > mProcessedMsgs;
|
||||||
|
|
||||||
|
};
|
||||||
|
} // namespace resource_api
|
25
libresapi/src/api/LivereloadHandler.cpp
Normal file
25
libresapi/src/api/LivereloadHandler.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "LivereloadHandler.h"
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
LivereloadHandler::LivereloadHandler(StateTokenServer *sts):
|
||||||
|
mStateTokenServer(sts), mStateToken(sts->getNewToken())
|
||||||
|
{
|
||||||
|
addResourceHandler("*", this, &LivereloadHandler::handleWildcard);
|
||||||
|
addResourceHandler("trigger", this, &LivereloadHandler::handleTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LivereloadHandler::handleWildcard(Request &/*req*/, Response &resp)
|
||||||
|
{
|
||||||
|
resp.mStateToken = mStateToken;
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LivereloadHandler::handleTrigger(Request &/*req*/, Response &resp)
|
||||||
|
{
|
||||||
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
|
resp.mStateToken = mStateToken;
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace resource_api
|
23
libresapi/src/api/LivereloadHandler.h
Normal file
23
libresapi/src/api/LivereloadHandler.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ResourceRouter.h"
|
||||||
|
#include "StateTokenServer.h"
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
// very simple livereload system, integrated into the existing state token system
|
||||||
|
// the response to / is only a statetoken
|
||||||
|
// if /trigger is called, then the state token is invalidaten and replaced wiht a new one
|
||||||
|
class LivereloadHandler: public ResourceRouter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LivereloadHandler(StateTokenServer* sts);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleWildcard(Request& req, Response& resp);
|
||||||
|
void handleTrigger(Request& req, Response& resp);
|
||||||
|
StateTokenServer* mStateTokenServer;
|
||||||
|
StateToken mStateToken;
|
||||||
|
};
|
||||||
|
} // namespace resource_api
|
@ -35,7 +35,9 @@ SOURCES += \
|
|||||||
api/FileSearchHandler.cpp \
|
api/FileSearchHandler.cpp \
|
||||||
api/TransfersHandler.cpp \
|
api/TransfersHandler.cpp \
|
||||||
api/RsControlModule.cpp \
|
api/RsControlModule.cpp \
|
||||||
api/GetPluginInterfaces.cpp
|
api/GetPluginInterfaces.cpp \
|
||||||
|
api/ChatHandler.cpp \
|
||||||
|
api/LivereloadHandler.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
api/ApiServer.h \
|
api/ApiServer.h \
|
||||||
@ -54,4 +56,6 @@ HEADERS += \
|
|||||||
api/FileSearchHandler.h \
|
api/FileSearchHandler.h \
|
||||||
api/TransfersHandler.h \
|
api/TransfersHandler.h \
|
||||||
api/RsControlModule.h \
|
api/RsControlModule.h \
|
||||||
api/GetPluginInterfaces.h
|
api/GetPluginInterfaces.h \
|
||||||
|
api/ChatHandler.h \
|
||||||
|
api/LivereloadHandler.h
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
module.exports = function(grunt) {
|
|
||||||
grunt.initConfig({
|
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
|
||||||
watch: {
|
|
||||||
// important: exclude node_modules
|
|
||||||
files: ['dist/**','!**/node_modules/**'],
|
|
||||||
options: {
|
|
||||||
livereload: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
|
||||||
};
|
|
@ -6,9 +6,13 @@ HTML = index.html
|
|||||||
JSGUI = gui.jsx
|
JSGUI = gui.jsx
|
||||||
CSS = green-black.css
|
CSS = green-black.css
|
||||||
|
|
||||||
all: dist $(JSEXTLIBS) $(addprefix dist/, $(JSLIBS)) $(addprefix dist/, $(HTML)) $(addprefix dist/, $(JSGUI)) $(addprefix dist/, $(CSS))
|
all: dist $(JSEXTLIBS) $(addprefix dist/, $(JSLIBS)) $(addprefix dist/, $(HTML)) $(addprefix dist/, $(JSGUI)) $(addprefix dist/, $(CSS)) dist/livereload
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
|
dist/livereload: dist $(JSEXTLIBS) $(addprefix dist/, $(JSLIBS)) $(addprefix dist/, $(HTML)) $(addprefix dist/, $(JSGUI)) $(addprefix dist/, $(CSS))
|
||||||
|
wget -qO- http://localhost:9090/api/v2/livereload/trigger
|
||||||
|
touch dist/livereload
|
||||||
|
|
||||||
dist/react.js:
|
dist/react.js:
|
||||||
cd dist && wget --no-check-certificate --output-document react.js http://fb.me/react-$(REACT_VERSION).js
|
cd dist && wget --no-check-certificate --output-document react.js http://fb.me/react-$(REACT_VERSION).js
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ DEVELOPMENT
|
|||||||
- Windows: download and install nodejs from http://nodejs.org
|
- Windows: download and install nodejs from http://nodejs.org
|
||||||
- Download development tools with the nodejs package manager (short npm)
|
- Download development tools with the nodejs package manager (short npm)
|
||||||
npm install
|
npm install
|
||||||
- during development, run these two commands at the same time
|
- run Retroshare with webinterface on port 9090
|
||||||
|
- during development, run this command (use MinGW shell on Windows)
|
||||||
while true; do make --silent; sleep 1; done
|
while true; do make --silent; sleep 1; done
|
||||||
grunt watch
|
- the command will copy the source files to the "dist" directory if they change
|
||||||
- command one will copy the source files to the "dist" directory if they change
|
- it will trigger livereload at http://localhost:9090/api/v2/livereload/trigger
|
||||||
- command two will tell the browser to reload if a file changes
|
|
||||||
|
|
||||||
API DOCUMENTATION
|
API DOCUMENTATION
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -5,6 +5,18 @@ RS.start();
|
|||||||
var api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/api/v2/";
|
var api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/api/v2/";
|
||||||
var filestreamer_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/fstream/";
|
var filestreamer_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/fstream/";
|
||||||
|
|
||||||
|
// livereload
|
||||||
|
function start_live_reload()
|
||||||
|
{
|
||||||
|
RS.request({path: "livereload"}, function(resp){
|
||||||
|
RS.register_token_listener(function(){
|
||||||
|
// Reload the current page, without using the cache
|
||||||
|
document.location.reload(true);
|
||||||
|
},resp.statetoken);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
start_live_reload();
|
||||||
|
|
||||||
// implements automatic update using the state token system
|
// implements automatic update using the state token system
|
||||||
// components using this mixin should have a member "getPath()" to specify the resource
|
// components using this mixin should have a member "getPath()" to specify the resource
|
||||||
var AutoUpdateMixin =
|
var AutoUpdateMixin =
|
||||||
@ -612,6 +624,49 @@ var Menu = React.createClass({
|
|||||||
<div className="btn2" onClick={function(){outer.emit("change_url", {url: "search"});}}>
|
<div className="btn2" onClick={function(){outer.emit("change_url", {url: "search"});}}>
|
||||||
Search
|
Search
|
||||||
</div>
|
</div>
|
||||||
|
{/*<div className="btn2" onClick={function(){outer.emit("change_url", {url: "testwidget"});}}>
|
||||||
|
TestWidget
|
||||||
|
</div>*/}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var TestWidget = React.createClass({
|
||||||
|
mixins: [SignalSlotMixin],
|
||||||
|
getInitialState: function(){
|
||||||
|
return {s:"one"};
|
||||||
|
},
|
||||||
|
componentWillMount: function()
|
||||||
|
{
|
||||||
|
},
|
||||||
|
one: function(){
|
||||||
|
this.setState({s:"one"});
|
||||||
|
},
|
||||||
|
two: function(){
|
||||||
|
this.setState({s:"two"});
|
||||||
|
},
|
||||||
|
render: function(){
|
||||||
|
var outer = this;
|
||||||
|
var outercontainerstyle = {borderStyle: "solid", borderColor: "darksalmon", overflow: "hidden", width: "100%"};
|
||||||
|
var transx = "0px";
|
||||||
|
if(this.state.s === "two")
|
||||||
|
transx = "-45%";
|
||||||
|
var innercontainerstyle = {width: "200%", transform: "translatex("+transx+")", WebkitTransform: "translatex("+transx+")", transition: "all 0.5s ease-in-out", WebkitTransition: "all 0.5s ease-in-out"};
|
||||||
|
var innerstyle = {float:"left", width: "45%"};
|
||||||
|
var two = <div></div>;
|
||||||
|
if(this.state.s === "two")
|
||||||
|
two = <div style={innerstyle} className="btn2" onClick={function(){outer.one();}}>
|
||||||
|
two
|
||||||
|
</div>;
|
||||||
|
return (
|
||||||
|
<div style={outercontainerstyle}>
|
||||||
|
<div style={innercontainerstyle}>
|
||||||
|
<div style={innerstyle} className="btn2" onClick={function(){outer.two();}}>
|
||||||
|
one
|
||||||
|
</div>
|
||||||
|
{two}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -665,18 +720,11 @@ var MainWidget = React.createClass({
|
|||||||
The component system makes this very simple.
|
The component system makes this very simple.
|
||||||
Updating the GUI is also very simple: one React mixin can handle updating for all components.
|
Updating the GUI is also very simple: one React mixin can handle updating for all components.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="btn2">Div Button</div>
|
|
||||||
<div className="btn2">Div Button</div>
|
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
if(this.state.page === "friends")
|
if(this.state.page === "friends")
|
||||||
{
|
{
|
||||||
mainpage =
|
mainpage = <Peers2 />;
|
||||||
<div>
|
|
||||||
<p>the list updates itself when something changes. Lots of magic happens here!</p>
|
|
||||||
<Peers2 />
|
|
||||||
</div>;
|
|
||||||
}
|
}
|
||||||
if(this.state.page === "downloads")
|
if(this.state.page === "downloads")
|
||||||
{
|
{
|
||||||
@ -698,6 +746,10 @@ var MainWidget = React.createClass({
|
|||||||
{
|
{
|
||||||
mainpage = <Menu/>;
|
mainpage = <Menu/>;
|
||||||
}
|
}
|
||||||
|
if(this.state.page === "testwidget")
|
||||||
|
{
|
||||||
|
mainpage = <TestWidget/>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var menubutton = <div onClick={function(){outer.emit("change_url", {url: "menu"});}} className="btn2"><- menu</div>;
|
var menubutton = <div onClick={function(){outer.emit("change_url", {url: "menu"});}} className="btn2"><- menu</div>;
|
||||||
@ -707,25 +759,6 @@ var MainWidget = React.createClass({
|
|||||||
<div>
|
<div>
|
||||||
<PasswordWidget/>
|
<PasswordWidget/>
|
||||||
<AudioPlayerWidget/>
|
<AudioPlayerWidget/>
|
||||||
{/*
|
|
||||||
<ul className="nav">
|
|
||||||
<li onClick={function(){outer.emit("change_url", {url: "main"});}}>
|
|
||||||
Start
|
|
||||||
</li>
|
|
||||||
<li onClick={function(){outer.emit("change_url", {url: "login"});}}>
|
|
||||||
Login
|
|
||||||
</li>
|
|
||||||
<li onClick={function(){outer.emit("change_url", {url: "friends"});}}>
|
|
||||||
Friends
|
|
||||||
</li>
|
|
||||||
<li onClick={function(){outer.emit("change_url", {url: "downloads"});}}>
|
|
||||||
Downloads
|
|
||||||
</li>
|
|
||||||
<li onClick={function(){outer.emit("change_url", {url: "search"});}}>
|
|
||||||
Search
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
*/}
|
|
||||||
{menubutton}
|
{menubutton}
|
||||||
{mainpage}
|
{mainpage}
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,12 +11,6 @@
|
|||||||
|
|
||||||
<script type="text/jsx" src="gui.jsx"></script>
|
<script type="text/jsx" src="gui.jsx"></script>
|
||||||
|
|
||||||
<!-- automatic page reload -->
|
|
||||||
<!--<script src="http://localhost:9091"></script>-->
|
|
||||||
<!-- load this last, because it contains errors -->
|
|
||||||
<!--<script src="http://localhost:35729/livereload.js"></script>-->
|
|
||||||
<script src="http://192.168.1.102:35720/livereload.js"></script>
|
|
||||||
|
|
||||||
<link href="green-black.css" rel="stylesheet">
|
<link href="green-black.css" rel="stylesheet">
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -4,17 +4,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^0.4.5",
|
|
||||||
"grunt-contrib-watch": "^0.6.1",
|
|
||||||
"live-reload": "^1.1.0",
|
|
||||||
"onchange": "^1.0.0",
|
|
||||||
"parallelshell": "^1.1.1"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"comment": "rem stuff below does not work, except the livereload",
|
|
||||||
"watch": "parallelshell \"npm run build\" \"npm run build:watch\" \"npm run livereload\"",
|
|
||||||
"watch:build": "onchange '**.html' -- 'npm run build'",
|
|
||||||
"build": "copy /Y index.html build",
|
|
||||||
"livereload": "live-reload --port 9091 build/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user