mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-06 08:05:18 -04:00
merged to upstream/master
This commit is contained in:
commit
8e2ff56f9a
395 changed files with 15613 additions and 45420 deletions
14
.travis.yml
14
.travis.yml
|
@ -1,16 +1,13 @@
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- echo $LANG
|
|
||||||
- echo $LC_ALL
|
|
||||||
- sudo apt-get update
|
- sudo apt-get update
|
||||||
- sudo apt-get install build-essential checkinstall cmake g++ git libavutil-dev libavcodec-dev libavformat-dev libbz2-dev libcurl4-openssl-dev libdc1394-22-dev libglib2.0-dev libcv-dev libopencv-highgui-dev libhighgui-dev
|
- sudo apt-get install -y build-essential checkinstall cmake libavutil-dev libavcodec-dev libavformat-dev libbz2-dev libcurl4-openssl-dev libcv-dev libopencv-highgui-dev libhighgui-dev libgnome-keyring-dev libgstreamer-plugins-base0.10-dev libgstreamer0.10-dev libjasper-dev libjpeg-dev libmicrohttpd-dev libopencv-dev libprotobuf-dev libqt4-dev libspeex-dev libspeexdsp-dev libsqlite3-dev libssl-dev libswscale-dev libtbb-dev libtiff4-dev libupnp-dev libv4l-dev libxine-dev libxslt1-dev libxss-dev pkg-config protobuf-compiler python-dev qtmobility-dev
|
||||||
- sudo apt-get install libgnome-keyring-dev libgstreamer-plugins-base0.10-dev libgstreamer0.10-dev libjasper-dev libjpeg-dev libmicrohttpd-dev libopencv-dev libprotobuf-dev libqt4-dev
|
|
||||||
- sudo apt-get install libspeex-dev libspeexdsp-dev libsqlite3-dev libssl-dev libswscale-dev
|
|
||||||
- sudo apt-get install libtbb-dev libtiff4-dev libupnp-dev libv4l-dev libxine-dev libxslt1-dev libxss-dev make pkg-config protobuf-compiler python-dev python-numpy subversion git yasm qtmobility-dev
|
|
||||||
# - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get update && sudo apt-get install -y llvm-3.4 llvm-3.4-dev; fi
|
# - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get update && sudo apt-get install -y llvm-3.4 llvm-3.4-dev; fi
|
||||||
# - rvm use $RVM --install --binary --fuzzy
|
# - rvm use $RVM --install --binary --fuzzy
|
||||||
# - gem update --system
|
# - gem update --system
|
||||||
|
@ -32,7 +29,7 @@ addons:
|
||||||
branch_pattern: coverity_scan
|
branch_pattern: coverity_scan
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- qmake CONFIG+=NO_SQLCIPHER CONFIG+=tests
|
- qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=NO_SQLCIPHER CONFIG+=tests
|
||||||
|
|
||||||
#script: make
|
#script: make
|
||||||
script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi
|
script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi
|
||||||
|
@ -64,6 +61,3 @@ notifications:
|
||||||
|
|
||||||
#env:
|
#env:
|
||||||
# - RVM=2.0.0 LANG="en_US.UTF-8"
|
# - RVM=2.0.0 LANG="en_US.UTF-8"
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -2,6 +2,22 @@ RetroShare
|
||||||
==============================
|
==============================
|
||||||
RetroShare is a decentralized, private and secure commmunication and sharing platform. RetroShare provides filesharing, chat, messages, forums and channels.
|
RetroShare is a decentralized, private and secure commmunication and sharing platform. RetroShare provides filesharing, chat, messages, forums and channels.
|
||||||
|
|
||||||
|
Build Status
|
||||||
|
------------
|
||||||
|
|
||||||
|
| Platform | Build Status |
|
||||||
|
| :------------- | :------------- |
|
||||||
|
| GNU/Linux, MacOS, (via travis-ci) | [](https://travis-ci.org/RetroShare/RetroShare) |
|
||||||
|
| Windows, `MSys2` (via appveyor) | [](https://ci.appveyor.com/project/PhenomRetroShare/retroshare) |
|
||||||
|
|
||||||
|
Compilation on Windows
|
||||||
|
----------------------------
|
||||||
|
Follow this file : [WindowsMSys2_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/WindowsMSys2_InstallGuide.txt)
|
||||||
|
|
||||||
|
Compilation on MacOSX
|
||||||
|
----------------------------
|
||||||
|
Follow this file : [MacOS_X_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/MacOS_X_InstallGuide.txt)
|
||||||
|
|
||||||
Compilation on Linux
|
Compilation on Linux
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
210
appveyor.yml
Normal file
210
appveyor.yml
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
# Notes:
|
||||||
|
# - Minimal appveyor.yml file is an empty file. All sections are optional.
|
||||||
|
# - Indent each level of configuration with 2 spaces. Do not use tabs!
|
||||||
|
# - All section names are case-sensitive.
|
||||||
|
# - Section names should be unique on each level.
|
||||||
|
# from example:
|
||||||
|
# https://github.com/Phonations/Joker/blob/master/appveyor.yml
|
||||||
|
# https://github.com/unicorn-engine/autobuild/blob/master/.appveyor.yml
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# general configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# version format
|
||||||
|
version: RetroShare 6.0.{build}-{branch}
|
||||||
|
|
||||||
|
# you can use {branch} name in version format too
|
||||||
|
# version: 1.0.{build}-{branch}
|
||||||
|
|
||||||
|
# branches to build
|
||||||
|
branches:
|
||||||
|
# whitelist
|
||||||
|
#only:
|
||||||
|
# - master
|
||||||
|
|
||||||
|
# blacklist
|
||||||
|
except:
|
||||||
|
- /^skipthisbranch$/
|
||||||
|
|
||||||
|
# Do not build on tags (GitHub only)
|
||||||
|
skip_tags: true
|
||||||
|
|
||||||
|
# Skipping commits with particular message or from user
|
||||||
|
skip_commits:
|
||||||
|
message: /Created.*\.(png|jpg|jpeg|bmp|gif)/ # Regex for matching commit message
|
||||||
|
#author: Anonymous # Commit author's username, name, email or regexp maching one of these.
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# environment configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# Operating system (build VM template)
|
||||||
|
#os: Windows Server 2012
|
||||||
|
|
||||||
|
# scripts that are called at very beginning, before repo cloning
|
||||||
|
init:
|
||||||
|
- git config --global core.autocrlf input
|
||||||
|
#To get RDP while compiling
|
||||||
|
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
on_finish:
|
||||||
|
#To get RDP running after compiling
|
||||||
|
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
|
||||||
|
# clone directory
|
||||||
|
clone_folder: c:\projects\RetroShare
|
||||||
|
|
||||||
|
# fetch repository as zip archive
|
||||||
|
#shallow_clone: true # default is "false"
|
||||||
|
|
||||||
|
# set clone depth
|
||||||
|
clone_depth: 1 # clone entire repository history if not defined
|
||||||
|
|
||||||
|
environment:
|
||||||
|
global:
|
||||||
|
#Qt: https://www.appveyor.com/docs/installed-software#qt
|
||||||
|
QTDIR: C:\Qt\5.4\mingw491_32
|
||||||
|
MSYS2_ARCH: i686
|
||||||
|
TARGET: i686_32-pc-msys
|
||||||
|
|
||||||
|
|
||||||
|
# build cache to preserve files/folders between builds
|
||||||
|
cache:
|
||||||
|
- c:\projects\libs
|
||||||
|
# - packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
|
||||||
|
# - projectA\libs
|
||||||
|
# - node_modules # local npm modules
|
||||||
|
# - %APPDATA%\npm-cache # npm cache
|
||||||
|
|
||||||
|
# scripts that run after cloning repository
|
||||||
|
#install:
|
||||||
|
# # by default, all script lines are interpreted as batch
|
||||||
|
# - echo This is batch
|
||||||
|
# # to run script as a PowerShell command prepend it with ps:
|
||||||
|
# - ps: Write-Host 'This is PowerShell'
|
||||||
|
# # batch commands start from cmd:
|
||||||
|
# - cmd: echo This is batch again
|
||||||
|
# - cmd: set MY_VAR=12345
|
||||||
|
install:
|
||||||
|
# Configuring MSys2
|
||||||
|
- set PATH=C:\msys64\usr\bin;%PATH%
|
||||||
|
- set PATH=C:\msys64\mingw32\bin;%PATH%
|
||||||
|
# Configuring Qt
|
||||||
|
- set PATH=%QTDIR%\bin;C:\Qt\Tools\mingw491_32\bin;%PATH%
|
||||||
|
# Install all default programms
|
||||||
|
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy base-devel git mercurial cvs wget p7zip gcc perl ruby python2" #Already installed
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy openssl-devel"
|
||||||
|
# Install toolchain
|
||||||
|
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain" #Already installed
|
||||||
|
# Install other binutils
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-miniupnpc mingw-w64-x86_64-miniupnpc"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-sqlite3 mingw-w64-x86_64-sqlite3"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-speex mingw-w64-x86_64-speex"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-opencv mingw-w64-x86_64-opencv"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-ffmpeg mingw-w64-x86_64-ffmpeg"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libmicrohttpd mingw-w64-x86_64-libmicrohttpd"
|
||||||
|
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libxslt mingw-w64-x86_64-libxslt"
|
||||||
|
|
||||||
|
# Hack for new MSys2
|
||||||
|
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ar.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ar.exe
|
||||||
|
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ranlib.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ranlib.exe
|
||||||
|
- copy C:\msys64\mingw32\bin\windres.exe C:\msys64\mingw32\bin\i686-w64-mingw32-windres.exe
|
||||||
|
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ar.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ar.exe
|
||||||
|
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ranlib.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ranlib.exe
|
||||||
|
- copy C:\msys64\mingw64\bin\windres.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-windres.exe
|
||||||
|
# Build missing Libs
|
||||||
|
- C:\msys64\mingw32_shell.bat -lc "cd /c/projects/RetroShare/msys2_build_libs/ && make"
|
||||||
|
# Clone RetroShare
|
||||||
|
#- git clone -q --branch={branch} https://github.com/RetroShare/RetroShare.git C:\projects\RetroShare
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# build configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
|
||||||
|
platform: x86
|
||||||
|
|
||||||
|
# to add several platforms to build matrix:
|
||||||
|
#platform:
|
||||||
|
# - x86
|
||||||
|
# - Any CPU
|
||||||
|
|
||||||
|
# build Configuration, i.e. Debug, Release, etc.
|
||||||
|
configuration: Release
|
||||||
|
|
||||||
|
# to add several configurations to build matrix:
|
||||||
|
#configuration:
|
||||||
|
# - Debug
|
||||||
|
# - Release
|
||||||
|
|
||||||
|
# scripts to run before build
|
||||||
|
before_build:
|
||||||
|
|
||||||
|
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
||||||
|
before_package:
|
||||||
|
|
||||||
|
# scripts to run after build
|
||||||
|
after_build:
|
||||||
|
|
||||||
|
# to run your custom scripts instead of automatic MSBuild
|
||||||
|
build_script:
|
||||||
|
- cd C:\projects\RetroShare
|
||||||
|
- qmake
|
||||||
|
- make
|
||||||
|
|
||||||
|
# to disable automatic builds
|
||||||
|
#build: off
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# artifacts configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
#artifacts:
|
||||||
|
#
|
||||||
|
# # pushing a single file
|
||||||
|
# - path: test.zip
|
||||||
|
#
|
||||||
|
# # pushing a single file with environment variable in path and "Deployment name" specified
|
||||||
|
# - path: MyProject\bin\$(configuration)
|
||||||
|
# name: myapp
|
||||||
|
#
|
||||||
|
# # pushing entire folder as a zip archive
|
||||||
|
# - path: logs
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# deployment configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
#No deployment under unknown computer!!!
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# global handlers #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# on successful build
|
||||||
|
#on_success:
|
||||||
|
# - do something
|
||||||
|
|
||||||
|
# on build failure
|
||||||
|
#on_failure:
|
||||||
|
# - do something
|
||||||
|
|
||||||
|
# after build failure or success
|
||||||
|
#on_finish:
|
||||||
|
# - do something
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# notifications #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
|
||||||
|
# Email
|
||||||
|
- provider: Email
|
||||||
|
to:
|
||||||
|
- retrosharephenom@gmail.com
|
||||||
|
subject: 'Build {{status}}' # optional
|
||||||
|
message: "{{message}}, {{commitId}}, ..." # optional
|
||||||
|
on_build_status_changed: true
|
|
@ -1,5 +1,364 @@
|
||||||
retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
|
retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
|
||||||
|
|
||||||
|
cbef014 csoler Sun, 29 May 2016 16:09:56 -0400 added regular test of circle auto-subscribe from cache, and auto-subscribe w
|
||||||
|
2bde81f csoler Sat, 28 May 2016 21:09:44 -0400 removed more debug info, improved tooltips
|
||||||
|
ccd72cb csoler Sat, 28 May 2016 20:58:28 -0400 removed some debug info. Added information tooltips on circles and ids in ci
|
||||||
|
9a328f6 csoler Sat, 28 May 2016 20:25:15 -0400 extended auto-subscribe to circles with admin flag
|
||||||
|
d114b83 csoler Sat, 28 May 2016 20:17:19 -0400 extended auto-subscribe to circles with requested membership
|
||||||
|
8b5e43f csoler Sat, 28 May 2016 17:18:25 -0400 remove subitems in circles member list when they are gone from cache
|
||||||
|
dafb2e6 csoler Fri, 27 May 2016 17:35:23 -0400 Merge pull request #396 from csoler/v0.6-Circles
|
||||||
|
cfdaa2c csoler Fri, 27 May 2016 17:09:13 -0400 removed debug info in p3gxscircles
|
||||||
|
d03d733 csoler Fri, 27 May 2016 12:44:14 -0400 Merge pull request #395 from hasufell/master
|
||||||
|
ed867c5 Julian Ospald Fri, 27 May 2016 18:07:28 +0200 Don't hardcode g++ in the toolchain settings
|
||||||
|
74b4d66 csoler Thu, 26 May 2016 21:16:21 -0400 added ifdef to allow to remove the sorting of circles into member/not member. To be tested for final decision
|
||||||
|
59aef8a csoler Thu, 26 May 2016 20:33:24 -0400 added packet slicing for large broadcast chat items, and output warning when chat of serialised item is too big. Als
|
||||||
|
ae5929e csoler Thu, 26 May 2016 18:58:48 -0400 fixed possible crash due to using a deleted item
|
||||||
|
a32bcba csoler Wed, 25 May 2016 21:17:09 -0400 changed Members to Invited members in circle creation dialog
|
||||||
|
d1f4e13 csoler Wed, 25 May 2016 19:04:45 -0400 removed display of circle members in left ID list
|
||||||
|
cfeed5c csoler Wed, 25 May 2016 18:47:06 -0400 fixed column width and titles in circles
|
||||||
|
605763d csoler Wed, 25 May 2016 18:34:12 -0400 added all IDs in circle to display tree
|
||||||
|
219dd01 csoler Wed, 25 May 2016 17:51:23 -0400 improved GUI display in circle list
|
||||||
|
5b69fa0 csoler Tue, 24 May 2016 21:23:35 -0400 fixed re-draw of subitem in circle tree when flags changed
|
||||||
|
2e91ab6 csoler Tue, 24 May 2016 21:07:50 -0400 added proper notify for subscription message reception in circles
|
||||||
|
5bc83d9 csoler Mon, 23 May 2016 21:09:06 -0400 fixed unsubscription of external circles
|
||||||
|
1b5d31f csoler Sun, 22 May 2016 21:15:18 -0400 attempt to fix the wrong display of uploaded size for files > 4Gb (to be confirmed)
|
||||||
|
55cb15c csoler Sun, 22 May 2016 20:35:51 -0400 fixed updating of membership when loading circle cache entry
|
||||||
|
fac1fb8 csoler Sun, 22 May 2016 18:50:18 -0400 enabled message publish for circle subscription requests
|
||||||
|
69573d1 csoler Sun, 22 May 2016 18:49:54 -0400 fixed serialisation of circle subscription requests
|
||||||
|
68e618b csoler Sun, 22 May 2016 18:21:48 -0400 fixed GUI for circle invites
|
||||||
|
6554832 csoler Sun, 22 May 2016 18:21:26 -0400 added isOwnId handle in rsidentity
|
||||||
|
be3be9f csoler Sun, 22 May 2016 18:21:00 -0400 put loading circles in cache as soon as we get the data for them. The cache entry might be incomplete.
|
||||||
|
d60e99e csoler Sat, 21 May 2016 16:50:50 -0400 added subwidgets for invited GXS ids in circles
|
||||||
|
82ad7d6 csoler Sat, 21 May 2016 15:51:49 -0400 improved debugoutput in p3gxscircles
|
||||||
|
4c5c09c csoler Thu, 19 May 2016 10:11:15 -0400 Merge pull request #390 from PhenomRetroShare/Fix_MutexInPqiPersonGrp
|
||||||
|
3a2b9e8 csoler Wed, 18 May 2016 21:47:34 -0400 added some debug info in new circle code
|
||||||
|
abe0e02 anon tahoe Wed, 18 May 2016 14:46:42 +0200 replaced mktemp by mkstemp (cherry-picked from anontahoe repository)
|
||||||
|
722609a csoler Wed, 18 May 2016 21:13:54 -0400 finished implementing the backend part for the subscription system
|
||||||
|
af5129c Phenom Wed, 18 May 2016 19:15:37 +0200 Fix Mutex in pqipersongrp for pqilistener by adding local Mutex.
|
||||||
|
9f56069 csoler Tue, 17 May 2016 11:21:03 -0400 Merge pull request #389 from PhenomRetroShare/Fix_ClearWebAPIWhenClearChatHistory
|
||||||
|
07191a7 Phenom Tue, 17 May 2016 16:50:59 +0200 Fix Clear WebAPI when clear chat history in GUI and server is not running.
|
||||||
|
f3aed81 csoler Tue, 17 May 2016 10:39:56 -0400 added test over signature size to avoid possible memory corruption (Anonymous source)
|
||||||
|
89472d6 csoler Tue, 17 May 2016 00:00:15 -0400 put some notes and comments in the code for what is to be done
|
||||||
|
116e742 csoler Mon, 16 May 2016 12:25:51 -0400 Merge pull request #388 from PhenomRetroShare/Fix_OpenExistingFileAsWarning
|
||||||
|
a2a0582 Phenom Mon, 16 May 2016 17:20:53 +0200 Change Open existing file link from Question to Warning.
|
||||||
|
2064870 csoler Mon, 16 May 2016 10:29:58 -0400 Merge pull request #385 from PhenomRetroShare/Fix_RsCollectionFileLoadCall
|
||||||
|
1f8f413 Phenom Mon, 16 May 2016 11:32:17 +0200 Fix RsCollectionFile::load(QString, bool) calls.
|
||||||
|
5d69072 csoler Sat, 14 May 2016 18:53:57 -0400 Merge pull request #383 from PhenomRetroShare/Fix_FreeTcpPacketIfPeersUnknown
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sat, 28 May 2016 10:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160514.4dc62d0e~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
5bb570e csoler Sat, 14 May 2016 10:57:52 -0400 Merge pull request #384 from PhenomRetroShare/Fix_RsAccountsDetailPrivateInit
|
||||||
|
7fd84f2 Phenom Sat, 14 May 2016 16:50:17 +0200 Fix Initialisation of Private in RsAccountDetails
|
||||||
|
52f488c csoler Fri, 13 May 2016 11:13:07 -0400 Merge pull request #382 from PhenomRetroShare/Fix_CorrectPR378
|
||||||
|
d7efeb9 Phenom Fri, 13 May 2016 17:06:00 +0200 Move nDir->Files into condition nDir exists.
|
||||||
|
4b8a1d2 csoler Thu, 12 May 2016 14:42:31 -0400 Merge pull request #380 from PhenomRetroShare/Fix_ContentValue
|
||||||
|
1c5bcb8 csoler Thu, 12 May 2016 14:41:10 -0400 Merge pull request #379 from PhenomRetroShare/Fix_UninitializedVar
|
||||||
|
2487f3e csoler Thu, 12 May 2016 14:40:37 -0400 Merge pull request #378 from PhenomRetroShare/Fix_CasenDirResetedBefore
|
||||||
|
61e5a62 Phenom Thu, 12 May 2016 20:29:12 +0200 Fix ContentValue::ContentValue if GetAsxxx return false.
|
||||||
|
ed56707 Phenom Thu, 12 May 2016 20:14:59 +0200 Fix in case nDir was reset before
|
||||||
|
a1ece16 Phenom Thu, 12 May 2016 20:00:44 +0200 Fix uninitialized variables netsize, rsnetsize in p3netmgr.cc
|
||||||
|
1d476de csoler Thu, 12 May 2016 10:26:38 -0400 fixed initialisation of semaphores in created thread object
|
||||||
|
96012ef csoler Wed, 11 May 2016 22:18:02 -0400 new attempt to fix thread issues
|
||||||
|
383e403 csoler Wed, 11 May 2016 12:42:59 -0400 tried to improve the RsSemaphore class to avoid and display more info about the
|
||||||
|
e891e2b csoler Wed, 11 May 2016 10:00:20 -0400 added missing check for ssl_connection that would cause crash when the ssl conne
|
||||||
|
8fdf8f8 csoler Tue, 10 May 2016 09:46:33 -0400 fixed possible crash in rsnet.cc
|
||||||
|
74bb3b6 csoler Mon, 9 May 2016 20:54:58 -0400 replaced deprecated gethostbyname by getaddrinfo. Only linux was using the re-entrant
|
||||||
|
f8e6937 csoler Sun, 8 May 2016 18:36:41 -0400 Merge pull request #373 from PhenomRetroShare/Fix_LibResAPI_MacOS
|
||||||
|
4b81fb0 csoler Sun, 8 May 2016 10:42:20 -0400 Merge pull request #374 from PhenomRetroShare/Fix_MacOSVersion
|
||||||
|
ceb092c Phenom Fri, 6 May 2016 22:51:25 +0200 Fix preprocessor for MacOS version.
|
||||||
|
61d2ab5 Phenom Fri, 6 May 2016 22:12:40 +0200 Fix compilation of LibResAPI for MacOS
|
||||||
|
6a7bd90 csoler Fri, 6 May 2016 08:59:59 -0400 Merge pull request #372 from zeners/master
|
||||||
|
ae631a1 zeners Fri, 6 May 2016 10:34:13 +0200 Merge remote branch 'origin/master'
|
||||||
|
08be19f zeners Fri, 6 May 2016 10:29:03 +0200 webui: rebuild files on qmake
|
||||||
|
13dec7a zeners Fri, 6 May 2016 10:06:03 +0200 webui: reset file-date on touch to force build
|
||||||
|
48bc31e csoler Thu, 5 May 2016 23:55:16 -0400 Merge pull request #371 from csoler/v0.6-Threads
|
||||||
|
67e9760 csoler Thu, 5 May 2016 22:03:46 -0400 removed debug output from threads
|
||||||
|
b5ace40 csoler Thu, 5 May 2016 21:21:45 -0400 attempt to fix socket problem on 32bits/64bits windows, by using the proper SOCKET typ
|
||||||
|
9847a7a csoler Thu, 5 May 2016 20:52:10 -0400 implemented a new semaphore class that should be cross plateform
|
||||||
|
092345c csoler Thu, 5 May 2016 09:49:56 -0400 Merge pull request #363 from Nyfor/travis
|
||||||
|
ad2df86 csoler Thu, 5 May 2016 09:45:22 -0400 Merge pull request #370 from Nyfor/fix-segfault-on-close
|
||||||
|
dbd0418 Nyfor Wed, 4 May 2016 18:48:13 +0200 Fix segfault on shutdown.
|
||||||
|
0817aad csoler Wed, 4 May 2016 22:51:33 -0400 improved debugging output of rsthreads.cc (part 3)
|
||||||
|
bb00e39 csoler Wed, 4 May 2016 22:34:03 -0400 improved debugging output of rsthreads.cc (part 2)
|
||||||
|
2e02a89 csoler Wed, 4 May 2016 22:23:36 -0400 improved debugging output of rsthreads.cc
|
||||||
|
e50e686 csoler Wed, 4 May 2016 18:01:18 -0400 updated the debug message for incoming data with no registered tunnel
|
||||||
|
40f8313 csoler Wed, 4 May 2016 15:32:17 -0400 Merge pull request #307 from hunbernd/fix/sqlcipher-version
|
||||||
|
ca003c5 csoler Tue, 3 May 2016 20:55:36 -0400 added missing initialisation of deleted memory before calling realloc
|
||||||
|
0ff2941 csoler Tue, 3 May 2016 13:11:41 -0400 Merge pull request #365 from zeners/master
|
||||||
|
f4a4765 zeners Tue, 3 May 2016 19:04:42 +0200 Merge remote branch 'origin/master'
|
||||||
|
962dd91 zeners Tue, 3 May 2016 19:02:07 +0200 webui: include files on first clean build
|
||||||
|
aec8b4d csoler Mon, 2 May 2016 18:10:39 -0400 fixed bug in counting of incoming data size for sliced packets
|
||||||
|
f3bc978 Nyfor Wed, 27 Apr 2016 18:32:59 +0200 Updated Travis file.
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sat, 14 May 2016 16:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160424.0d84a558~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
7914aeb csoler Sat, 30 Apr 2016 17:33:47 -0400 use RsTemporaryMemory in signature verification
|
||||||
|
be7e87c csoler Sat, 30 Apr 2016 17:25:24 -0400 use RsTemporaryMemory in signature verification
|
||||||
|
01605e5 csoler Sat, 30 Apr 2016 11:19:21 -0400 updated description f packet slicing in comments section of pqistreamer
|
||||||
|
1f7a94d csoler Sat, 30 Apr 2016 11:13:51 -0400 fixed bug causing crash in pqistreamer
|
||||||
|
0bd6670 csoler Sat, 30 Apr 2016 09:47:21 -0400 Merge pull request #362 from zeners/master
|
||||||
|
0a6ae55 zeners Sat, 30 Apr 2016 14:21:09 +0200 webui: redefined building webui
|
||||||
|
baf9404 csoler Fri, 29 Apr 2016 20:09:48 -0400 Merge pull request #360 from csoler/v0.6-RTT3
|
||||||
|
4bdd464 csoler Fri, 29 Apr 2016 18:53:25 -0400 removed a few debug output and timer measurement
|
||||||
|
6d2bfcf csoler Fri, 29 Apr 2016 18:52:58 -0400 restored average kicking rate to a more reasonnable value. To be tested (for to
|
||||||
|
3bc3989 csoler Fri, 29 Apr 2016 18:41:10 -0400 removed debug info for pqistreamer
|
||||||
|
5ab9aed csoler Fri, 29 Apr 2016 18:40:28 -0400 added placeholder service ID for packet slicing probe
|
||||||
|
654e0fc csoler Fri, 29 Apr 2016 17:53:21 -0400 added missing call to SSL_pending, which caused decrypted data to wait in the S
|
||||||
|
a443064 csoler Tue, 26 Apr 2016 23:42:44 -0400 various changes to measure RTTs more accurately
|
||||||
|
87764ab csoler Tue, 26 Apr 2016 21:23:19 -0400 removed debug info in pqistreamer
|
||||||
|
153db5c csoler Tue, 26 Apr 2016 09:22:24 -0400 added on/off mechanism for packet slicing to ensure packward compatibility
|
||||||
|
3b68585 csoler Mon, 25 Apr 2016 23:37:02 -0400 improved/simplified slicing protocol
|
||||||
|
dd81ce3 csoler Mon, 25 Apr 2016 22:50:41 -0400 using BinToHex to display mem blocks in pqistreamer debug
|
||||||
|
18e9e1c csoler Sun, 24 Apr 2016 21:29:55 -0400 moerged with upstream/master
|
||||||
|
f629575 csoler Sun, 24 Apr 2016 21:18:44 -0400 fixed a few bugs in packet slicing in pqiQoS
|
||||||
|
a2c11f9 csoler Sun, 24 Apr 2016 13:43:34 -0400 added packet reconstruction and deserialising
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sat, 30 Apr 2016 18:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160424.0d84a558~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
0dc43c3 csoler Sat, 23 Apr 2016 08:29:53 -0400 Merge pull request #338 from Nyfor/master
|
||||||
|
5e94c77 Nyfor Mon, 4 Apr 2016 12:07:09 +0200 Fixed compilation for Clang.
|
||||||
|
d696f72 csoler Fri, 22 Apr 2016 20:38:07 -0400 fixed compilation
|
||||||
|
acd059b csoler Fri, 22 Apr 2016 18:49:42 -0400 removed potential memory leak in TransfersDialog
|
||||||
|
52cf66a csoler Fri, 22 Apr 2016 17:55:15 -0400 fixed memory leak in SubscribeToolButton menu
|
||||||
|
55e8087 csoler Fri, 22 Apr 2016 17:30:55 -0400 added missing free for public keys used in envelop encryption
|
||||||
|
10230df csoler Fri, 22 Apr 2016 16:50:43 -0400 added missing SSL shutdown when replacing existing connection
|
||||||
|
5261c3c csoler Thu, 21 Apr 2016 22:23:07 -0400 prevented turtle to not deleting a config item when it is not cast
|
||||||
|
e9fa9eb csoler Thu, 21 Apr 2016 22:07:50 -0400 removed tricky memory leak in chat lobbies due to handling of partial messages
|
||||||
|
7aea6e5 csoler Thu, 21 Apr 2016 22:07:10 -0400 removed some debug info
|
||||||
|
eca83fd csoler Thu, 21 Apr 2016 19:54:50 -0400 removed some debug info
|
||||||
|
fba3d37 csoler Thu, 21 Apr 2016 19:47:34 -0400 fixed memory leak after receiving RsNxsItem deserialised from decrypted memory
|
||||||
|
0d3ff0e csoler Thu, 21 Apr 2016 19:46:47 -0400 fixed possible uninitialised memory read in memory decryption return
|
||||||
|
0c711a4 csoler Thu, 21 Apr 2016 19:41:21 -0400 added missing calls to EVP_CIPHER_CTX_cleanup() to release memory after decryption, causing memory
|
||||||
|
3fae108 csoler Thu, 21 Apr 2016 12:58:48 -0400 removed div by zero in transfers dialog
|
||||||
|
0572492 csoler Wed, 20 Apr 2016 21:20:47 -0400 severely reduced packet grouping, which limited the effectiveness of QoS
|
||||||
|
d6ae71e csoler Wed, 20 Apr 2016 20:21:29 -0400 removed pointer to QStringList in QHash, causing memory loss
|
||||||
|
aba3d2f csoler Wed, 20 Apr 2016 18:24:02 -0400 removed memory leak due to zeroing (on purpose!) a data chunk in GRouter before deleting it
|
||||||
|
d017771 csoler Wed, 20 Apr 2016 18:08:26 -0400 fixed missing sendTime in distant chat, causing inconsistent display in GUI
|
||||||
|
80a9fec csoler Tue, 19 Apr 2016 22:18:25 -0400 Merge pull request #353 from crhode/master
|
||||||
|
39553a6 csoler Tue, 19 Apr 2016 21:58:30 -0400 removed debug info
|
||||||
|
5645e44 Manuel Davis Tue, 19 Apr 2016 11:32:56 -0500 Change regular expression(s) for identifying hotlinks in feral text.
|
||||||
|
8be53dd Manuel Davis Tue, 19 Apr 2016 11:11:58 -0500 Improve inserting placemark in ChatLobby.
|
||||||
|
26af7c9 csoler Sun, 17 Apr 2016 22:58:48 -0400 changed heart beat limit to a larger value. Apparently too tight a value causes disconnections due
|
||||||
|
c14c240 csoler Sun, 17 Apr 2016 00:51:45 -0400 fixed update of circles GUI using a timer. This is not optimal, and should be replaced by a proper
|
||||||
|
3000f94 csoler Sat, 16 Apr 2016 22:44:06 -0400 separated subscribe status from wether we are part of a circle or not. Still needs update of GUI
|
||||||
|
b861aa9 csoler Sat, 16 Apr 2016 17:10:36 -0400 Merge pull request #352 from AsamK/trailing_semicolon
|
||||||
|
e7ec204 AsamK Sat, 16 Apr 2016 20:40:24 +0200 Add trailing semi-colon to MimeType in .desktop files
|
||||||
|
fa8a585 csoler Fri, 15 Apr 2016 18:25:53 -0400 removed some debug info
|
||||||
|
d642934 csoler Fri, 15 Apr 2016 18:25:41 -0400 increased frequency of update for banned PGP nodes
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sun, 24 Apr 2016 12:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160415.26574fd9~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
2552b55 defnax Fri, 15 Apr 2016 20:32:00 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
|
||||||
|
85942f4 defnax Fri, 15 Apr 2016 20:30:32 +0200 improving the create circle layout
|
||||||
|
cb6c2c9 csoler Thu, 14 Apr 2016 23:49:55 -0400 Merge pull request #350 from csoler/v0.6-Circles
|
||||||
|
048192e csoler Thu, 14 Apr 2016 23:47:42 -0400 added mOriginator to CircleCache entry and auto-ask for unknown GXS ids to the friend who suppl
|
||||||
|
ba1a1b2 csoler Thu, 14 Apr 2016 23:09:59 -0400 fixed auto-subscribed of circles when some IDs are unknown
|
||||||
|
47dd442 csoler Thu, 14 Apr 2016 18:26:47 -0400 merge upstream/master
|
||||||
|
971f8e0 csoler Wed, 13 Apr 2016 18:41:49 -0400 fixed potential crash due to not updating mPendingDataIterator after deleting map entry
|
||||||
|
92eb9c5 csoler Wed, 13 Apr 2016 18:15:56 -0400 Merge pull request #346 from PhenomRetroShare/Move_ChatNotifyButtonToToolBar
|
||||||
|
aad295d defnax Wed, 13 Apr 2016 21:00:07 +0200 Fixed layout margin
|
||||||
|
45f77de Phenom Wed, 13 Apr 2016 20:42:12 +0200 Change Lobby Send button tooltip.
|
||||||
|
718d6f9 Phenom Wed, 13 Apr 2016 20:26:36 +0200 Resize Chat Tool Bar Button for Hight DPI screen.
|
||||||
|
42a2b37 Phenom Wed, 13 Apr 2016 19:21:18 +0200 Move SearchBar to Tool Bar and remove Show/Hide action.
|
||||||
|
c5873f3 Phenom Sun, 10 Apr 2016 16:42:15 +0200 Move Chat notify button from search bar to tool bar.
|
||||||
|
d512c4a csoler Tue, 12 Apr 2016 22:59:12 -0400 enabled new link type for posted (patch from Fanch)
|
||||||
|
cf746f1 csoler Tue, 12 Apr 2016 10:06:01 -0400 fixed possible crash in GxsIdDetails
|
||||||
|
d5ed84e csoler Mon, 11 Apr 2016 23:43:18 -0400 allow one to change the contact author of a circle
|
||||||
|
8f9028d csoler Mon, 11 Apr 2016 23:30:42 -0400 fixed bug in GxsIdLabel due to not removign existing jobs for a given widget before setting it
|
||||||
|
6b2de05 csoler Mon, 11 Apr 2016 22:42:02 -0400 added channel admin and distribution method in channel summary page
|
||||||
|
a52bd98 csoler Mon, 11 Apr 2016 10:10:10 -0400 fixed potential div by 0 in speed estimations. To be tested.
|
||||||
|
b148239 csoler Sun, 10 Apr 2016 21:09:47 -0400 always pass data accept test in distant chat when we are on the client side of the tunnel
|
||||||
|
c97f197 csoler Sun, 10 Apr 2016 20:39:08 -0400 removed depth obfucation of search results and replaced by 0 always, effectively removing any i
|
||||||
|
123041a csoler Sun, 10 Apr 2016 18:55:05 -0400 skip circle vetting when sending message posts with no author
|
||||||
|
0d5b9ae csoler Sun, 10 Apr 2016 18:55:05 -0400 fixed last commit
|
||||||
|
b8075d6 csoler Sun, 10 Apr 2016 18:53:49 -0400 skip circle vetting when sending message posts with no author
|
||||||
|
4fe66d6 csoler Sun, 10 Apr 2016 10:53:21 -0400 removed Edit/New circles buttons, put them in context menu. Added header frame (needs a proper
|
||||||
|
c9c15e5 csoler Sun, 10 Apr 2016 09:49:31 -0400 Merge pull request #345 from PhenomRetroShare/Update_CircleGraphical
|
||||||
|
d727311 Phenom Sun, 10 Apr 2016 12:00:23 +0200 Fix Graphic Circles update.
|
||||||
|
3eb9a5e electron128 Sun, 10 Apr 2016 11:14:32 +0200 Merge pull request #344 from Phenom: Fix Escaped charaters in WebUI
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sat, 09 Apr 2016 23:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160409.33d32589~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
3b45fd8 csoler Sat, 9 Apr 2016 17:50:46 -0400 create new item "My own identities" to store own ids in IdDialog
|
||||||
|
a5044bd csoler Sat, 9 Apr 2016 14:48:05 -0400 improved calculation of speed in pqistreamer (was called before only when sending bytes), and prevented situation wher
|
||||||
|
993d7d4 csoler Sat, 9 Apr 2016 14:46:12 -0400 removed debug info in rsgxsnetservice
|
||||||
|
0853773 csoler Sat, 9 Apr 2016 12:51:15 -0400 merged and removed debug output in rsgxsnetservice.cc
|
||||||
|
10a32d3 csoler Sat, 9 Apr 2016 11:38:07 -0400 Merge pull request #343 from csoler/v0.6-Circles
|
||||||
|
ca0f769 csoler Fri, 8 Apr 2016 21:08:22 -0400 removed warning that would show up too often when a GxsTunnel is down and message cannot be sent
|
||||||
|
85c8274 csoler Fri, 8 Apr 2016 20:41:12 -0400 Merge pull request #342 from PhenomRetroShare/Fix_AllowOnlyOneInst
|
||||||
|
08e5679 Phenom Fri, 8 Apr 2016 02:14:27 +0200 Fix Allow Only One Instance
|
||||||
|
554251d csoler Thu, 7 Apr 2016 19:50:02 -0400 Merge pull request #341 from PhenomRetroShare/Add_WebUIClearButton
|
||||||
|
24b3f0d Phenom Fri, 8 Apr 2016 01:31:36 +0200 Add a Clear button on WebUI
|
||||||
|
b90808d csoler Thu, 7 Apr 2016 18:26:18 -0400 changed update of server update TS in subscribeStatusChange from 0 to time(NULL)
|
||||||
|
c8cae4c csoler Thu, 7 Apr 2016 00:09:00 -0400 Merge pull request #297 from PhenomRetroShare/Add_AllowOnlyOneIntanceAndPassArg
|
||||||
|
4ad3b11 csoler Wed, 6 Apr 2016 22:27:02 -0400 fixed compiler warning
|
||||||
|
4bf9262 csoler Wed, 6 Apr 2016 22:26:34 -0400 merged with upstream/master
|
||||||
|
60ffcd2 csoler Wed, 6 Apr 2016 22:23:10 -0400 fixed double item deletion in RsGxsNetService::handleRecvItem()
|
||||||
|
c79c9ba csoler Wed, 6 Apr 2016 21:12:54 -0400 added encryption of message sync requests for external circles-restricted groups, and verification that properly encry
|
||||||
|
10bb542 Phenom Tue, 1 Mar 2016 13:08:33 +0100 Allow only one instance for useLocalServer option activated. If exists, pass to it arguments.
|
||||||
|
f26348b csoler Tue, 5 Apr 2016 18:09:02 -0400 fixed bug in grouter which caused sending of messages to some offline peers, hence wasting some routes, and causing "
|
||||||
|
7817a54 csoler Tue, 5 Apr 2016 17:55:03 -0400 merged with trunk
|
||||||
|
9871b37 csoler Mon, 4 Apr 2016 23:02:09 -0400 Merge pull request #305 from realityfabric/openssl_crypto_infinite_loop
|
||||||
|
9217ec3 csoler Mon, 4 Apr 2016 21:36:37 -0400 added circle distribution info in forum summary page
|
||||||
|
ff4c360 csoler Mon, 4 Apr 2016 21:15:49 -0400 fixed display bug in bw statistics graph
|
||||||
|
b206317 csoler Mon, 4 Apr 2016 12:17:34 -0400 Merge pull request #339 from PhenomRetroShare/Fix_UnitTests_Compilation
|
||||||
|
f2b9957 Phenom Mon, 4 Apr 2016 17:18:42 +0200 Fix UnitTests Compilation
|
||||||
|
d34b2e8 csoler Sun, 3 Apr 2016 17:11:13 -0400 allow to change the author ID of a group during update. Set proper value in group author widget
|
||||||
|
18dd7ee csoler Sun, 3 Apr 2016 11:42:45 -0400 moved "too many routing clues" message to debug output, since it can be caused by normal lobby operation
|
||||||
|
3554e48 csoler Sun, 3 Apr 2016 11:38:53 -0400 output packet error with some details (inspired by Phenom-PR289)
|
||||||
|
a3890ad csoler Sun, 3 Apr 2016 11:00:03 -0400 added gathering of routing clues from lobbies
|
||||||
|
9ced517 csoler Sat, 2 Apr 2016 16:54:30 -0400 improved tooltips in people list
|
||||||
|
53dbc52 csoler Sat, 2 Apr 2016 16:50:22 -0400 removed mention of null PGP ids in People
|
||||||
|
f8639e5 csoler Sat, 2 Apr 2016 16:44:41 -0400 fixed bug considering null PGP ids in ban list
|
||||||
|
5bbaa1e csoler Sat, 2 Apr 2016 16:14:08 -0400 added people settings page, removed debug output
|
||||||
|
9d9b790 csoler Sat, 2 Apr 2016 14:04:08 -0400 exposed un-verified PGP signatures on GXS ids in GUI. Added auto-ban of GXS ids signed by a PGP ids that has already s
|
||||||
|
9a6bcf8 csoler Sat, 2 Apr 2016 14:02:04 -0400 removed blue color for admin flag in forums, since admin flag is already indicated by position in "My Forums" list, an
|
||||||
|
7c4d85d csoler Sat, 2 Apr 2016 14:00:04 -0400 fixed compilation for ubuntu xenial
|
||||||
|
0350c1d csoler Fri, 1 Apr 2016 17:47:03 -0400 Merge pull request #335 from PhenomRetroShare/Add_ClearWebAPIWhenClearChatHistory2
|
||||||
|
c6f1cc4 Phenom Thu, 31 Mar 2016 22:52:53 +0200 Clear WebAPI when clear chat history in GUI.
|
||||||
|
ab78825 thunder2 Thu, 31 Mar 2016 10:23:23 +0200 Enabled webui build script for Windows compile
|
||||||
|
21421ab csoler Wed, 30 Mar 2016 14:03:50 -0400 Merge pull request #334 from zeners/master
|
||||||
|
8def617 zeners Wed, 30 Mar 2016 19:50:11 +0200 webui: windows build-script
|
||||||
|
741db13 csoler Wed, 30 Mar 2016 12:34:32 -0400 Merge pull request #333 from zeners/webui
|
||||||
|
f570477 zeners Wed, 30 Mar 2016 18:20:59 +0200 webui: patch init.sh like build.sh
|
||||||
|
cee3477 defnax Wed, 30 Mar 2016 17:06:34 +0200 Fixed the default splitter expanding of People Dialog
|
||||||
|
351af47 csoler Tue, 29 Mar 2016 15:42:23 -0400 Merge pull request #332 from zeners/master
|
||||||
|
aca8830 zeners Tue, 29 Mar 2016 21:22:14 +0200 compatible to g++11 / QT5
|
||||||
|
5783c59 electron128 Tue, 29 Mar 2016 20:16:44 +0200 Merge pull request #318 from realityfabric/remove_empty_file
|
||||||
|
475cb40 electron128 Tue, 29 Mar 2016 20:13:24 +0200 Merge pull request #328 from PhenomRetroShare/Fix_WebUI_MakeSrcBuild
|
||||||
|
5b5504c electron128 Tue, 29 Mar 2016 19:42:07 +0200 Merge pull request #330 from zeners/webui
|
||||||
|
be328e2 zeners Tue, 29 Mar 2016 18:57:18 +0200 webui: include files in install
|
||||||
|
f5f27ed zeners Tue, 29 Mar 2016 18:56:00 +0200 Merge branch 'master'
|
||||||
|
a53fbad thunder2 Tue, 29 Mar 2016 08:13:28 +0200 Fixed Windows compile.
|
||||||
|
7c288fc csoler Mon, 28 Mar 2016 23:24:50 -0400 added xenial as build target
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Sat, 09 Apr 2016 23:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160330.21421ab8~trusty) trusty; urgency=low
|
||||||
|
|
||||||
|
3701366 electron128 Mon, 28 Mar 2016 14:07:19 +0200 Merge pull request #327 from zeners/webui
|
||||||
|
dfa2cba zeners Mon, 28 Mar 2016 13:03:49 +0200 webui: menu in gui mode fixed
|
||||||
|
a11cd25 zeners Mon, 28 Mar 2016 11:35:44 +0200 Merge branch 'master'
|
||||||
|
bf374b3 zeners Mon, 28 Mar 2016 11:34:33 +0200 webui 4 windows build prepare
|
||||||
|
68b4cd8 electron128 Mon, 28 Mar 2016 10:19:10 +0200 Merge pull request #323 from zeners/webui
|
||||||
|
0482655 zeners Sun, 27 Mar 2016 20:29:48 +0200 webui: removed searchresult debug output
|
||||||
|
bbdb04f zeners Sun, 27 Mar 2016 20:13:47 +0200 webui: searchresult cross-checking with downloads
|
||||||
|
3bbd370 zeners Sun, 27 Mar 2016 18:28:32 +0200 webui: windows creating batch-files
|
||||||
|
d96a8ef zeners Sat, 26 Mar 2016 23:38:18 +0100 Merge branch 'master'
|
||||||
|
0c138d7 csoler Sat, 26 Mar 2016 18:36:52 -0400 moved discarding of banned identities from lobbies before signature checking, so as to avoid to time stamp their GXSI
|
||||||
|
215402b zeners Sat, 26 Mar 2016 23:36:02 +0100 webui: add downloads: focus fixed
|
||||||
|
922644f zeners Sat, 26 Mar 2016 23:24:29 +0100 Merge branch 'master'
|
||||||
|
502b137 csoler Sat, 26 Mar 2016 17:51:51 -0400 Merge pull request #325 from csoler/v0.6-Circles
|
||||||
|
ebf54d1 csoler Sat, 26 Mar 2016 17:25:15 -0400 fixed unit tests
|
||||||
|
a67c1d7 zeners Sat, 26 Mar 2016 18:19:33 +0100 webui: paste RS-links for download
|
||||||
|
1b8b9d4 csoler Fri, 25 Mar 2016 21:10:01 -0400 turned PeopleDialog to unix ff
|
||||||
|
6c8737c csoler Fri, 25 Mar 2016 21:09:37 -0400 merged with upstream/master
|
||||||
|
4831465 csoler Fri, 25 Mar 2016 21:03:09 -0400 fixed tiny bits in circles/people GUI
|
||||||
|
9efc29f csoler Fri, 25 Mar 2016 20:58:10 -0400 improved display of circle creator ID
|
||||||
|
d1b09b9 csoler Fri, 25 Mar 2016 18:54:13 -0400 removed some debug info
|
||||||
|
083dc62 csoler Fri, 25 Mar 2016 18:27:20 -0400 small code cleaning bits
|
||||||
|
3d45947 csoler Fri, 25 Mar 2016 18:21:37 -0400 fixed small bug in debug output; cleanup debug output
|
||||||
|
44cadc2 csoler Thu, 24 Mar 2016 19:46:08 -0400 cleaned debug info and disabled local circles before merge
|
||||||
|
7d8001b csoler Thu, 24 Mar 2016 19:23:34 -0400 fixed display of warning in posting into forums without proper credentials
|
||||||
|
9dc7328 csoler Thu, 24 Mar 2016 18:41:15 -0400 fixed async-ed circle loading in IdDialog
|
||||||
|
30193fe zeners Thu, 24 Mar 2016 18:07:21 +0100 webui: switch from react to mithril
|
||||||
|
d33a1e8 csoler Thu, 24 Mar 2016 00:05:54 -0400 added disabling of combo elements in GxsIdChooser for creating forums posts with unautorised GXS ids. Still needs a b
|
||||||
|
40d2350 csoler Wed, 23 Mar 2016 21:50:41 -0400 removed deadlock
|
||||||
|
981f81d csoler Wed, 23 Mar 2016 20:54:45 -0400 added anon ids to offline vetting
|
||||||
|
cef07ff zeners Thu, 24 Mar 2016 00:33:22 +0100 webui: integrate new webui in unix build process
|
||||||
|
57f4463 csoler Wed, 23 Mar 2016 18:23:10 -0400 fixed potential crash due to using deleted data (found by dimqua)
|
||||||
|
a19a068 zeners Wed, 23 Mar 2016 13:11:14 +0100 webui: options>settings, playing with colors
|
||||||
|
585c43b zeners Tue, 22 Mar 2016 23:19:36 +0100 webui: RS-reboot / RS-reboot-detection improved
|
||||||
|
60e9f0f zeners Tue, 22 Mar 2016 21:09:33 +0100 undo gitignore
|
||||||
|
a069db5 zeners Tue, 22 Mar 2016 16:37:48 +0100 webui: chat: display peer location
|
||||||
|
4733523 zeners Tue, 22 Mar 2016 16:33:05 +0100 webui: view / change rights per user
|
||||||
|
|
||||||
|
83ff00e zeners Tue, 22 Mar 2016 12:08:23 +0100 webui: updated mithril to v0.2.3
|
||||||
|
1fb1f3e csoler Mon, 21 Mar 2016 23:21:26 -0400 update of groups up to the latest attached circle server update TS. Should re-send groups that depend on a circle whe
|
||||||
|
51e0d83 zeners Mon, 21 Mar 2016 17:04:21 +0100 webui: options / rights (only defaults)
|
||||||
|
1c94ff7 zeners Mon, 21 Mar 2016 16:41:21 +0100 Merge branch 'master'
|
||||||
|
b153c2e csoler Sun, 20 Mar 2016 22:23:32 -0400 updated TODO
|
||||||
|
c304a3a csoler Sun, 20 Mar 2016 22:21:09 -0400 fixed display of properties in restricted groups
|
||||||
|
90347bd csoler Sun, 20 Mar 2016 12:51:30 -0400 Merge pull request #315 from dartraiden/master
|
||||||
|
c627e1b dartraiden Sun, 20 Mar 2016 19:27:28 +0300 Fix typo
|
||||||
|
c123761 csoler Sun, 20 Mar 2016 09:11:55 -0400 Merge pull request #314 from PhenomRetroShare/Fix_CppCheckerError
|
||||||
|
b13292b Phenom Sun, 20 Mar 2016 12:10:56 +0100 Fix error reported by CppChecker:
|
||||||
|
2e9d22c csoler Sat, 19 Mar 2016 18:47:46 -0400 used RsTemporaryMemory to avoid memory leak in case of error in GxsTunnels
|
||||||
|
d1bb939 csoler Sat, 19 Mar 2016 17:14:00 -0400 Merge pull request #312 from PhenomRetroShare/AddPluginsPathForApple
|
||||||
|
5061046 Phenom Sat, 19 Mar 2016 18:58:00 +0100 Add Plugins Path for Apple
|
||||||
|
12c0efb zeners Sat, 19 Mar 2016 17:39:46 +0100 webui: pgp-linked identity disabled
|
||||||
|
ecf8e7f zeners Sat, 19 Mar 2016 17:39:34 +0100 Merge remote branch 'origin/master'
|
||||||
|
24ba909 csoler Sat, 19 Mar 2016 11:39:53 -0400 fixed mixup between in/out bandwidth traffic info
|
||||||
|
526a83a csoler Fri, 18 Mar 2016 22:11:07 -0400 fixed update of circle name in the GUI
|
||||||
|
4e0ee29 csoler Thu, 17 Mar 2016 20:18:54 -0400 fixed creation/distribution of self-restricted circles
|
||||||
|
b6388d7 csoler Thu, 17 Mar 2016 18:17:58 -0400 fixed update of GUI when circles change
|
||||||
|
36edde6 csoler Wed, 16 Mar 2016 23:30:23 -0400 fixed bug causing GUI to not auto-unsubscribe in circles
|
||||||
|
a2a9079 csoler Wed, 16 Mar 2016 23:03:46 -0400 fixed qt4 compilation
|
||||||
|
31356ba csoler Wed, 16 Mar 2016 21:27:08 -0400 added reload of grp meta on update
|
||||||
|
b219295 csoler Wed, 16 Mar 2016 20:59:52 -0400 added update of GUI, instead of re-creating everything when a circle change
|
||||||
|
5b00c03 csoler Wed, 16 Mar 2016 14:17:16 -0400 Merge pull request #4 from PhenomRetroShare/Fix_PictureFlowDeletion
|
||||||
|
76fddb29 Phenom Wed, 16 Mar 2016 19:05:22 +0100 Fix delete in PictureFlow
|
||||||
|
b6e51b2 csoler Wed, 16 Mar 2016 09:56:36 -0400 Merge pull request #308 from dartraiden/master
|
||||||
|
5ba4f42 dartraiden Wed, 16 Mar 2016 16:24:06 +0300 correct path to Hidden Service configuration panel
|
||||||
|
384131a csoler Tue, 15 Mar 2016 22:41:59 -0400 added force reload of cache for circles that are modified
|
||||||
|
6466209 csoler Tue, 15 Mar 2016 22:11:36 -0400 added test to only subscribe/unsubscribe circles when needed, hence avoiding an unnecessary TS update
|
||||||
|
80aaf30 csoler Tue, 15 Mar 2016 00:00:39 -0400 fixed potential crash due to bad usage of updates
|
||||||
|
bdb326a csoler Mon, 14 Mar 2016 23:19:37 -0400 attempt at fixing circle cache loop. Renamed a few variables and fixed logic. Not yet fully working
|
||||||
|
83e39d8 csoler Sun, 13 Mar 2016 17:29:38 -0400 fixed effect of selecting known/signed IDs in circle creation dialog
|
||||||
|
4cf57d6 csoler Sun, 13 Mar 2016 17:19:14 -0400 set default value for circle distribution type
|
||||||
|
9c649aa csoler Sun, 13 Mar 2016 12:08:03 -0400 improved debugDump(), showing the subscription status of each grp
|
||||||
|
5fe390d csoler Sun, 13 Mar 2016 11:41:33 -0400 changed titles of tree root nodes in circles
|
||||||
|
0518062 csoler Sun, 13 Mar 2016 11:29:21 -0400 fixed circle auto-subscribe
|
||||||
|
|
||||||
|
1b72d2c zeners Sat, 12 Mar 2016 23:38:39 +0100 webui: unsubscribe chat-lobby
|
||||||
|
41a8e53 zeners Sat, 12 Mar 2016 23:28:27 +0100 webui: chat-layout fixed
|
||||||
|
0afa2e3 zeners Sat, 12 Mar 2016 20:20:56 +0100 webui: unread chat message counter in menu
|
||||||
|
e9af179 zeners Sat, 12 Mar 2016 19:17:37 +0100 webui: need for master
|
||||||
|
b1286f0 zeners Sat, 12 Mar 2016 17:44:43 +0100 webui: route peer location to chat-lobby
|
||||||
|
a065dba csoler Sat, 12 Mar 2016 11:05:03 -0500 cleaned code a little bit
|
||||||
|
61c7da7 csoler Sat, 12 Mar 2016 11:02:32 -0500 unselect all IDs when no circle is selected
|
||||||
|
b1da4ed zeners Sat, 12 Mar 2016 16:46:33 +0100 Merge branch 'master'
|
||||||
|
456a882 csoler Sat, 12 Mar 2016 10:41:35 -0500 added highlighting of currently selected circle members
|
||||||
|
5d2833f csoler Sat, 12 Mar 2016 09:25:28 -0500 improved one line of debug output in turtle
|
||||||
|
670fb3d csoler Sat, 12 Mar 2016 09:25:00 -0500 merged
|
||||||
|
4e2fd4e csoler Sat, 12 Mar 2016 09:22:28 -0500 Merge pull request #303 from PhenomRetroShare/Fix_CorrectColoredNameContrast
|
||||||
|
16c59af Phenom Sat, 12 Mar 2016 13:25:10 +0100 Correct Colored Name Contrast in chat, same way than text.
|
||||||
|
9e8a4cd csoler Fri, 11 Mar 2016 22:36:47 -0500 fixed auto-subscribe of circles when unsigned identities are locally owned
|
||||||
|
b97c5df csoler Fri, 11 Mar 2016 17:47:12 -0500 fixed culumn name in GR stats
|
||||||
|
692b549 csoler Fri, 11 Mar 2016 17:27:40 -0500 fixing compilation problem
|
||||||
|
232dba2 csoler Fri, 11 Mar 2016 17:21:27 -0500 allow non signature checking for GR message recepts at intermediate peers when key is missing. Should fix return rece
|
||||||
|
ecebace csoler Fri, 11 Mar 2016 14:26:27 -0500 Merge pull request #301 from PhenomRetroShare/Add_NewColumnInRsCollForPath
|
||||||
|
c0cf05c csoler Fri, 11 Mar 2016 14:25:18 -0500 Merge pull request #302 from PhenomRetroShare/Fix_RsLinkCopyForExtraFile
|
||||||
|
d62a205 Phenom Fri, 11 Mar 2016 20:08:28 +0100 Fix Paste RetroShare Link action when copy File link.
|
||||||
|
7e76e28 Phenom Fri, 11 Mar 2016 17:26:18 +0100 Add a new column in RsColl Editor to get only name in first one.
|
||||||
|
4136d09 csoler Thu, 10 Mar 2016 23:55:20 -0500 updated Circles TODO
|
||||||
|
4e4980b csoler Thu, 10 Mar 2016 22:57:04 -0500 fixed display of info for non admin circles, and added readonly system to not allow editing them
|
||||||
|
5361c85 csoler Thu, 10 Mar 2016 22:02:21 -0500 updated circles TODO
|
||||||
|
0282c2a csoler Wed, 9 Mar 2016 21:49:24 -0500 added ban menu entry to chat lobby participant list
|
||||||
|
3fc6f6b csoler Wed, 9 Mar 2016 20:53:49 -0500 updated TODO(circles), removed useless context menu, added tooltips for circle distribution options
|
||||||
|
4eebe24 csoler Wed, 9 Mar 2016 20:23:33 -0500 disabled auto-sync for messages in GXS circles, while keeping Grp auto-sync
|
||||||
|
76e7893 csoler Wed, 9 Mar 2016 20:18:19 -0500 updated circles TODO
|
||||||
|
2017f92 csoler Tue, 8 Mar 2016 23:12:27 -0500 updated circles todo
|
||||||
|
cf75983 csoler Tue, 8 Mar 2016 23:01:43 -0500 added TODO file specific to circles
|
||||||
|
7e31bda csoler Tue, 8 Mar 2016 23:00:24 -0500 fixed removal of peers from circles
|
||||||
|
cba4795 csoler Tue, 8 Mar 2016 00:02:16 -0500 improved circles GUI logic
|
||||||
|
9b92f66 csoler Mon, 7 Mar 2016 22:51:23 -0500 added edit of existing circles
|
||||||
|
49605a3 csoler Mon, 7 Mar 2016 22:10:18 -0500 fixed variable scope problem in introserver.cc
|
||||||
|
|
||||||
|
-- Cyril Soler <csoler@users.sourceforge.net> Mon, 28 Mar 2016 20:00:00 -0500
|
||||||
|
|
||||||
|
retroshare06 (0.6.0-1.20160306.ecf4a991~precise) precise; urgency=low
|
||||||
|
|
||||||
bb26069 csoler Wed, 2 Mar 2016 19:00:51 -0500 attempt at fixing negative bw rates in GUI that may pop up when an erro
|
bb26069 csoler Wed, 2 Mar 2016 19:00:51 -0500 attempt at fixing negative bw rates in GUI that may pop up when an erro
|
||||||
20fcf63 electron128 Fri, 26 Feb 2016 18:13:20 +0100 Merge pull request #285 from PhenomRetroShare/Fix_SSGxsChannelGro
|
20fcf63 electron128 Fri, 26 Feb 2016 18:13:20 +0100 Merge pull request #285 from PhenomRetroShare/Fix_SSGxsChannelGro
|
||||||
1a110e4 Phenom Mon, 22 Feb 2016 19:07:49 +0100 Define empty service string as a valid case.
|
1a110e4 Phenom Mon, 22 Feb 2016 19:07:49 +0100 Define empty service string as a valid case.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
configure: configure-stamp
|
configure: configure-stamp
|
||||||
configure-stamp:
|
configure-stamp:
|
||||||
dh_testdir
|
dh_testdir
|
||||||
cd src && qmake-qt4 "CONFIG-=debug" "CONFIG+=release" PREFIX=/usr LIB_DIR=/usr/lib RetroShare.pro
|
cd src && qmake "CONFIG-=debug" "CONFIG+=release" PREFIX=/usr LIB_DIR=/usr/lib RetroShare.pro
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ while [ ${#} -gt 0 ]; do
|
||||||
done
|
done
|
||||||
|
|
||||||
if test "${dist}" = "" ; then
|
if test "${dist}" = "" ; then
|
||||||
dist="precise trusty vivid wily"
|
dist="precise trusty vivid wily xenial"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo Attempting to get revision number...
|
echo Attempting to get revision number...
|
||||||
|
@ -133,6 +133,8 @@ for i in ${dist}; do
|
||||||
cp ../control.squeeze_bubba3 debian/control
|
cp ../control.squeeze_bubba3 debian/control
|
||||||
elif test "${i}" = "precise" ; then
|
elif test "${i}" = "precise" ; then
|
||||||
cp ../control.precise debian/control
|
cp ../control.precise debian/control
|
||||||
|
elif test "${i}" = "xenial" ; then
|
||||||
|
cp ../control.xenial debian/control
|
||||||
elif test "${i}" = "stretch" ; then
|
elif test "${i}" = "stretch" ; then
|
||||||
cp ../control.${i} debian/control
|
cp ../control.${i} debian/control
|
||||||
cp ../rules.${i} debian/rules
|
cp ../rules.${i} debian/rules
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
Version=1.0
|
Version=1.0
|
||||||
Name=RetroShare06
|
Name=RetroShare06
|
||||||
Comment=Securely share files with your friends
|
Comment=Securely share files with your friends
|
||||||
Exec=/usr/bin/RetroShare06
|
Exec=/usr/bin/RetroShare06 %U
|
||||||
Icon=/usr/share/pixmaps/retroshare06.xpm
|
Icon=/usr/share/pixmaps/retroshare06.xpm
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Network;P2P;
|
Categories=Network;P2P;
|
||||||
|
MimeType=x-scheme-handler/retroshare;
|
||||||
|
|
|
@ -7,8 +7,8 @@ Group: Productivity/Networking/Other
|
||||||
URL: http://retroshare.sourceforge.net/
|
URL: http://retroshare.sourceforge.net/
|
||||||
Source0: %{name}-%{version}.tar.gz
|
Source0: %{name}-%{version}.tar.gz
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
Requires: qt-x11
|
Requires: qt5-qtbase-gui qt5-qtmultimedia qt5-qtx11extras qt5-qtbase
|
||||||
BuildRequires: gcc-c++ qt-devel desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel
|
BuildRequires: gcc-c++ desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel qt5-qtx11extras-devel qt5-qttools-devel qt5-qtmultimedia-devel qt5-qttools-static
|
||||||
# This is because of sqlcipher:
|
# This is because of sqlcipher:
|
||||||
BuildRequires: tcl
|
BuildRequires: tcl
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ cd lib/sqlcipher
|
||||||
make
|
make
|
||||||
cd -
|
cd -
|
||||||
cd src
|
cd src
|
||||||
qmake-qt4 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro
|
qmake-qt5 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro
|
||||||
make
|
make
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ Section $(Section_Main) Section_Main
|
||||||
|
|
||||||
; WebUI
|
; WebUI
|
||||||
SetOutPath "$INSTDIR\webui"
|
SetOutPath "$INSTDIR\webui"
|
||||||
File /r "${SOURCEDIR}\libresapi\src\webfiles\*.*"
|
File /r "${SOURCEDIR}\libresapi\src\webui\*.*"
|
||||||
|
|
||||||
; License
|
; License
|
||||||
SetOutPath "$INSTDIR\license"
|
SetOutPath "$INSTDIR\license"
|
||||||
|
|
|
@ -241,7 +241,7 @@ Section $(Section_Main) Section_Main
|
||||||
|
|
||||||
; WebUI
|
; WebUI
|
||||||
SetOutPath "$INSTDIR\webui"
|
SetOutPath "$INSTDIR\webui"
|
||||||
File /r "${SOURCEDIR}\libresapi\src\webfiles\*.*"
|
File /r "${SOURCEDIR}\libresapi\src\webui\*.*"
|
||||||
|
|
||||||
; License
|
; License
|
||||||
SetOutPath "$INSTDIR\license"
|
SetOutPath "$INSTDIR\license"
|
||||||
|
|
|
@ -3,9 +3,9 @@ Encoding=UTF-8
|
||||||
Version=1.0
|
Version=1.0
|
||||||
Name=RetroShare06
|
Name=RetroShare06
|
||||||
Comment=Securely share files with your friends
|
Comment=Securely share files with your friends
|
||||||
Exec=/usr/bin/RetroShare06
|
Exec=/usr/bin/RetroShare06 %U
|
||||||
Icon=/usr/share/pixmaps/retroshare06.xpm
|
Icon=/usr/share/pixmaps/retroshare06.xpm
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Application;Network;
|
Categories=Application;Network;
|
||||||
|
MimeType=x-scheme-handler/retroshare;
|
||||||
|
|
|
@ -46,8 +46,6 @@ bdFilter::bdFilter(const std::string &fname, const bdNodeId *ownid, uint32_t fi
|
||||||
mFns = fns;
|
mFns = fns;
|
||||||
mFilename = fname ;
|
mFilename = fname ;
|
||||||
|
|
||||||
time_t now = time(NULL) ;
|
|
||||||
|
|
||||||
loadBannedIpFile() ;
|
loadBannedIpFile() ;
|
||||||
|
|
||||||
mFilterFlags = filterFlags;
|
mFilterFlags = filterFlags;
|
||||||
|
@ -92,8 +90,6 @@ void bdFilter::loadBannedIpFile()
|
||||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||||
addr.sin_family = PF_INET;
|
addr.sin_family = PF_INET;
|
||||||
|
|
||||||
unsigned short port;
|
|
||||||
|
|
||||||
FILE *fd = fopen(mFilename.c_str(),"r") ;
|
FILE *fd = fopen(mFilename.c_str(),"r") ;
|
||||||
|
|
||||||
if(fd == NULL)
|
if(fd == NULL)
|
||||||
|
|
|
@ -496,10 +496,12 @@ void bdNode::checkPotentialPeer(bdId *id, bdId *src)
|
||||||
/* first check the filters */
|
/* first check the filters */
|
||||||
if (!mFilterPeers.addrOkay(&(id->addr)))
|
if (!mFilterPeers.addrOkay(&(id->addr)))
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_NODE_MSGS
|
||||||
std::cerr << "bdNode::checkPotentialPeer(";
|
std::cerr << "bdNode::checkPotentialPeer(";
|
||||||
mFns->bdPrintId(std::cerr, id);
|
mFns->bdPrintId(std::cerr, id);
|
||||||
std::cerr << ") BAD ADDRESS!!!! SHOULD DISCARD POTENTIAL PEER";
|
std::cerr << ") BAD ADDRESS!!!! SHOULD DISCARD POTENTIAL PEER";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,8 @@ int bdSpace::find_node(const bdNodeId *id, int number, std::list<bdId> &matchIds
|
||||||
std::cerr << " Number: " << number;
|
std::cerr << " Number: " << number;
|
||||||
std::cerr << " Bucket #: " << buckno;
|
std::cerr << " Bucket #: " << buckno;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#else
|
||||||
|
(void)number;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bdBucket &buck = buckets[buckno];
|
bdBucket &buck = buckets[buckno];
|
||||||
|
|
|
@ -29,7 +29,7 @@ debug {
|
||||||
|
|
||||||
################################# Linux ##########################################
|
################################# Linux ##########################################
|
||||||
linux-* {
|
linux-* {
|
||||||
QMAKE_CC = g++
|
QMAKE_CC = $${QMAKE_CXX}
|
||||||
}
|
}
|
||||||
|
|
||||||
linux-g++ {
|
linux-g++ {
|
||||||
|
@ -64,7 +64,7 @@ win32-x-g++ {
|
||||||
################################# Windows ##########################################
|
################################# Windows ##########################################
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
QMAKE_CC = g++
|
QMAKE_CC = $${QMAKE_CXX}
|
||||||
OBJECTS_DIR = temp/obj
|
OBJECTS_DIR = temp/obj
|
||||||
MOC_DIR = temp/moc
|
MOC_DIR = temp/moc
|
||||||
DEFINES *= STATICLIB WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
|
DEFINES *= STATICLIB WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
|
||||||
|
@ -89,7 +89,7 @@ win32 {
|
||||||
################################# MacOSX ##########################################
|
################################# MacOSX ##########################################
|
||||||
|
|
||||||
mac {
|
mac {
|
||||||
QMAKE_CC = g++
|
QMAKE_CC = $${QMAKE_CXX}
|
||||||
OBJECTS_DIR = temp/obj
|
OBJECTS_DIR = temp/obj
|
||||||
MOC_DIR = temp/moc
|
MOC_DIR = temp/moc
|
||||||
}
|
}
|
||||||
|
|
1
libresapi/src/.gitignore
vendored
Normal file
1
libresapi/src/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
webui/*
|
|
@ -2,13 +2,13 @@ libresapi: resource_api and new webinterface
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
* ./api contains a C++ backend to control retroshare from webinterfaces or scripting
|
* ./api contains a C++ backend to control retroshare from webinterfaces or scripting
|
||||||
* ./webfiles contains compiled files for the webinterface
|
* ./webui contains compiled files for the webinterface (after build)
|
||||||
* ./webui contains HTML/CSS/JavaScript source files for the webinterface
|
* ./webui-src contains HTML/CSS/JavaScript source files for the webinterface (NEW, webinterface made with mithril.js)
|
||||||
|
|
||||||
Quickinfo for builders and packagers
|
Quickinfo for builders and packagers
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
* copy the files in ./webfiles to
|
* copy the files in ./webui to
|
||||||
* ./webui (Windows)
|
* ./webui (Windows)
|
||||||
* /usr/share/RetroShare06/webui (Linux)
|
* /usr/share/RetroShare06/webui (Linux)
|
||||||
* other OS: see RsAccountsDetail::PathDataDirectory()
|
* other OS: see RsAccountsDetail::PathDataDirectory()
|
|
@ -14,6 +14,7 @@
|
||||||
#include "StateTokenServer.h" // for the state token serialisers
|
#include "StateTokenServer.h" // for the state token serialisers
|
||||||
|
|
||||||
#include "ApiPluginHandler.h"
|
#include "ApiPluginHandler.h"
|
||||||
|
#include "ChannelsHandler.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
data types in json http://json.org/
|
data types in json http://json.org/
|
||||||
|
@ -226,13 +227,14 @@ class ApiServerMainModules
|
||||||
public:
|
public:
|
||||||
ApiServerMainModules(ResourceRouter& router, StateTokenServer* sts, const RsPlugInInterfaces &ifaces):
|
ApiServerMainModules(ResourceRouter& router, StateTokenServer* sts, const RsPlugInInterfaces &ifaces):
|
||||||
mPeersHandler(sts, ifaces.mNotify, ifaces.mPeers, ifaces.mMsgs),
|
mPeersHandler(sts, ifaces.mNotify, ifaces.mPeers, ifaces.mMsgs),
|
||||||
mIdentityHandler(ifaces.mIdentity),
|
mIdentityHandler(sts, ifaces.mNotify, ifaces.mIdentity),
|
||||||
mForumHandler(ifaces.mGxsForums),
|
mForumHandler(ifaces.mGxsForums),
|
||||||
mServiceControlHandler(ifaces.mServiceControl),
|
mServiceControlHandler(ifaces.mServiceControl),
|
||||||
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
|
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
|
||||||
mTransfersHandler(sts, ifaces.mFiles),
|
mTransfersHandler(sts, ifaces.mFiles),
|
||||||
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
||||||
mApiPluginHandler(sts, ifaces)
|
mApiPluginHandler(sts, ifaces),
|
||||||
|
mChannelsHandler(ifaces.mGxsChannels)
|
||||||
{
|
{
|
||||||
// the dynamic cast is to not confuse the addResourceHandler template like this:
|
// the dynamic cast is to not confuse the addResourceHandler template like this:
|
||||||
// addResourceHandler(derived class, parent class)
|
// addResourceHandler(derived class, parent class)
|
||||||
|
@ -254,6 +256,8 @@ public:
|
||||||
&ChatHandler::handleRequest);
|
&ChatHandler::handleRequest);
|
||||||
router.addResourceHandler("apiplugin", dynamic_cast<ResourceRouter*>(&mApiPluginHandler),
|
router.addResourceHandler("apiplugin", dynamic_cast<ResourceRouter*>(&mApiPluginHandler),
|
||||||
&ChatHandler::handleRequest);
|
&ChatHandler::handleRequest);
|
||||||
|
router.addResourceHandler("channels", dynamic_cast<ResourceRouter*>(&mChannelsHandler),
|
||||||
|
&ChannelsHandler::handleRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeersHandler mPeersHandler;
|
PeersHandler mPeersHandler;
|
||||||
|
@ -264,6 +268,7 @@ public:
|
||||||
TransfersHandler mTransfersHandler;
|
TransfersHandler mTransfersHandler;
|
||||||
ChatHandler mChatHandler;
|
ChatHandler mChatHandler;
|
||||||
ApiPluginHandler mApiPluginHandler;
|
ApiPluginHandler mApiPluginHandler;
|
||||||
|
ChannelsHandler mChannelsHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
ApiServer::ApiServer():
|
ApiServer::ApiServer():
|
||||||
|
@ -311,7 +316,7 @@ std::string ApiServer::handleRequest(Request &request)
|
||||||
task = mRouter.handleRequest(request, resp);
|
task = mRouter.handleRequest(request, resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t start = time(NULL);
|
//time_t start = time(NULL);
|
||||||
bool morework = true;
|
bool morework = true;
|
||||||
while(task && morework)
|
while(task && morework)
|
||||||
{
|
{
|
||||||
|
|
|
@ -305,7 +305,7 @@ public:
|
||||||
|
|
||||||
// get content-type from extension
|
// get content-type from extension
|
||||||
std::string ext = "";
|
std::string ext = "";
|
||||||
unsigned int i = info.fname.rfind('.');
|
std::string::size_type i = info.fname.rfind('.');
|
||||||
if(i != std::string::npos)
|
if(i != std::string::npos)
|
||||||
ext = info.fname.substr(i+1);
|
ext = info.fname.substr(i+1);
|
||||||
MHD_add_response_header(resp, "Content-Type", ContentTypes::cTypeFromExt(ext).c_str());
|
MHD_add_response_header(resp, "Content-Type", ContentTypes::cTypeFromExt(ext).c_str());
|
||||||
|
@ -424,7 +424,7 @@ static void sendMessage(MHD_Connection *connection, unsigned int status, std::st
|
||||||
static std::string escape_html(std::string in)
|
static std::string escape_html(std::string in)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
for(int i = 0; i < in.size(); i++)
|
for(uint32_t i = 0; i < in.size(); i++)
|
||||||
{
|
{
|
||||||
char a = (in[i]&0xF0)>>4;
|
char a = (in[i]&0xF0)>>4;
|
||||||
a = a < 10? a+'0': a-10+'A';
|
a = a < 10? a+'0': a-10+'A';
|
||||||
|
|
112
libresapi/src/api/ChannelsHandler.cpp
Normal file
112
libresapi/src/api/ChannelsHandler.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#include "ChannelsHandler.h"
|
||||||
|
|
||||||
|
#include <retroshare/rsgxschannels.h>
|
||||||
|
#include <util/radix64.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Operators.h"
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
StreamBase& operator << (StreamBase& left, RsGxsFile& file)
|
||||||
|
{
|
||||||
|
left << makeKeyValueReference("name", file.mName)
|
||||||
|
<< makeKeyValueReference("hash", file.mHash);
|
||||||
|
if(left.serialise())
|
||||||
|
{
|
||||||
|
double size = file.mSize;
|
||||||
|
left << makeKeyValueReference("size", size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double size = 0;
|
||||||
|
left << makeKeyValueReference("size", size);
|
||||||
|
file.mSize = size;
|
||||||
|
}
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelsHandler::ChannelsHandler(RsGxsChannels *channels):
|
||||||
|
mChannels(channels)
|
||||||
|
{
|
||||||
|
addResourceHandler("create_post", this, &ChannelsHandler::handleCreatePost);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseTask* ChannelsHandler::handleCreatePost(Request &req, Response &resp)
|
||||||
|
{
|
||||||
|
RsGxsChannelPost post;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("group_id", post.mMeta.mGroupId);
|
||||||
|
req.mStream << makeKeyValueReference("subject", post.mMeta.mMsgName);
|
||||||
|
req.mStream << makeKeyValueReference("message", post.mMsg);
|
||||||
|
|
||||||
|
StreamBase& file_array = req.mStream.getStreamToMember("files");
|
||||||
|
while(file_array.hasMore())
|
||||||
|
{
|
||||||
|
RsGxsFile file;
|
||||||
|
file_array.getStreamToMember() << file;
|
||||||
|
post.mFiles.push_back(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string thumbnail_base64;
|
||||||
|
req.mStream << makeKeyValueReference("thumbnail_base64_png", thumbnail_base64);
|
||||||
|
|
||||||
|
if(post.mMeta.mGroupId.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("groupd_id is null");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(post.mMeta.mMsgName.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("subject is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(post.mMsg.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("msg text is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// empty file list is ok, but files have to be valid
|
||||||
|
for(std::list<RsGxsFile>::iterator lit = post.mFiles.begin(); lit != post.mFiles.end(); ++lit)
|
||||||
|
{
|
||||||
|
if(lit->mHash.isNull())
|
||||||
|
{
|
||||||
|
resp.setFail("at least one file hash is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(lit->mName.empty())
|
||||||
|
{
|
||||||
|
resp.setFail("at leats one file name is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(lit->mSize == 0)
|
||||||
|
{
|
||||||
|
resp.setFail("at least one file size is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> png_data = Radix64::decode(thumbnail_base64);
|
||||||
|
if(!png_data.empty())
|
||||||
|
{
|
||||||
|
if(png_data.size() < 8)
|
||||||
|
{
|
||||||
|
resp.setFail("Decoded thumbnail_base64_png is smaller than 8 byte. This can't be a valid png file!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t png_magic_number[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
||||||
|
if(!std::equal(&png_magic_number[0],&png_magic_number[8],png_data.begin()))
|
||||||
|
{
|
||||||
|
resp.setFail("Decoded thumbnail_base64_png does not seem to be a png file. (Header is missing magic number)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
post.mThumbnail.copy(png_data.data(), png_data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
mChannels->createPost(token, post);
|
||||||
|
// TODO: grp creation acknowledge
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace resource_api
|
21
libresapi/src/api/ChannelsHandler.h
Normal file
21
libresapi/src/api/ChannelsHandler.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ResourceRouter.h"
|
||||||
|
|
||||||
|
class RsGxsChannels;
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
class ChannelsHandler : public ResourceRouter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChannelsHandler(RsGxsChannels* channels);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResponseTask* handleCreatePost(Request& req, Response& resp);
|
||||||
|
|
||||||
|
RsGxsChannels* mChannels;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace resource_api
|
|
@ -6,8 +6,10 @@
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
|
@ -97,6 +99,39 @@ StreamBase& operator << (StreamBase& left, ChatHandler::ChatInfo& info)
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SendLobbyParticipantsTask: public GxsResponseTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SendLobbyParticipantsTask(RsIdentity* idservice, ChatHandler::LobbyParticipantsInfo pi):
|
||||||
|
GxsResponseTask(idservice, 0), mParticipantsInfo(pi)
|
||||||
|
{
|
||||||
|
const std::map<RsGxsId, time_t>& map = mParticipantsInfo.participants;
|
||||||
|
for(std::map<RsGxsId, time_t>::const_iterator mit = map.begin(); mit != map.end(); ++mit)
|
||||||
|
{
|
||||||
|
requestGxsId(mit->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ChatHandler::LobbyParticipantsInfo mParticipantsInfo;
|
||||||
|
protected:
|
||||||
|
virtual void gxsDoWork(Request &/*req*/, Response &resp)
|
||||||
|
{
|
||||||
|
resp.mDataStream.getStreamToMember();
|
||||||
|
const std::map<RsGxsId, time_t>& map = mParticipantsInfo.participants;
|
||||||
|
for(std::map<RsGxsId, time_t>::const_iterator mit = map.begin(); mit != map.end(); ++mit)
|
||||||
|
{
|
||||||
|
StreamBase& stream = resp.mDataStream.getStreamToMember();
|
||||||
|
double last_active = mit->second;
|
||||||
|
stream << makeKeyValueReference("last_active", last_active);
|
||||||
|
streamGxsId(mit->first, stream.getStreamToMember("identity"));
|
||||||
|
}
|
||||||
|
resp.mStateToken = mParticipantsInfo.state_token;
|
||||||
|
resp.setOk();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, RsPeers* peers, RsIdentity* identity, UnreadMsgNotify* unread):
|
ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, RsPeers* peers, RsIdentity* identity, UnreadMsgNotify* unread):
|
||||||
mStateTokenServer(sts), mNotify(notify), mRsMsgs(msgs), mRsPeers(peers), mRsIdentity(identity), mUnreadMsgNotify(unread), mMtx("ChatHandler::mMtx")
|
mStateTokenServer(sts), mNotify(notify), mRsMsgs(msgs), mRsPeers(peers), mRsIdentity(identity), mUnreadMsgNotify(unread), mMtx("ChatHandler::mMtx")
|
||||||
{
|
{
|
||||||
|
@ -111,11 +146,13 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs,
|
||||||
addResourceHandler("lobbies", this, &ChatHandler::handleLobbies);
|
addResourceHandler("lobbies", this, &ChatHandler::handleLobbies);
|
||||||
addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby);
|
addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby);
|
||||||
addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby);
|
addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby);
|
||||||
|
addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby);
|
||||||
|
addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants);
|
||||||
addResourceHandler("messages", this, &ChatHandler::handleMessages);
|
addResourceHandler("messages", this, &ChatHandler::handleMessages);
|
||||||
addResourceHandler("send_message", this, &ChatHandler::handleSendMessage);
|
addResourceHandler("send_message", this, &ChatHandler::handleSendMessage);
|
||||||
addResourceHandler("mark_chat_as_read", this, &ChatHandler::handleMarkChatAsRead);
|
addResourceHandler("mark_chat_as_read", this, &ChatHandler::handleMarkChatAsRead);
|
||||||
addResourceHandler("info", this, &ChatHandler::handleInfo);
|
addResourceHandler("info", this, &ChatHandler::handleInfo);
|
||||||
addResourceHandler("typing_label", this, &ChatHandler::handleTypingLabel);
|
addResourceHandler("receive_status", this, &ChatHandler::handleReceiveStatus);
|
||||||
addResourceHandler("send_status", this, &ChatHandler::handleSendStatus);
|
addResourceHandler("send_status", this, &ChatHandler::handleSendStatus);
|
||||||
addResourceHandler("unread_msgs", this, &ChatHandler::handleUnreadMsgs);
|
addResourceHandler("unread_msgs", this, &ChatHandler::handleUnreadMsgs);
|
||||||
}
|
}
|
||||||
|
@ -132,20 +169,40 @@ void ChatHandler::notifyChatMessage(const ChatMessage &msg)
|
||||||
mRawMsgs.push_back(msg);
|
mRawMsgs.push_back(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be removed
|
void ChatHandler::notifyChatCleared(const ChatId &chat_id)
|
||||||
/*
|
|
||||||
ChatHandler::Lobby ChatHandler::getLobbyInfo(ChatLobbyId id)
|
|
||||||
{
|
{
|
||||||
tick();
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
//Remove processed messages
|
||||||
RS_STACK_MUTEX(mMtx); // ********* LOCKED **********
|
std::list<Msg>& msgs = mMsgs[chat_id];
|
||||||
for(std::vector<Lobby>::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit)
|
msgs.clear();
|
||||||
if(vit->id == id)
|
//Remove unprocessed messages
|
||||||
return *vit;
|
for(std::list<ChatMessage>::iterator lit = mRawMsgs.begin(); lit != mRawMsgs.end();)
|
||||||
std::cerr << "ChatHandler::getLobbyInfo Error: Lobby not found" << std::endl;
|
{
|
||||||
return Lobby();
|
ChatMessage& msg = *lit;
|
||||||
|
if (msg.chat_id == chat_id)
|
||||||
|
{
|
||||||
|
lit = mRawMsgs.erase(lit);
|
||||||
|
} else {
|
||||||
|
++lit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHandler::notifyChatStatus(const ChatId &chat_id, const std::string &status)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
locked_storeTypingInfo(chat_id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHandler::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,
|
||||||
|
const RsGxsId &nickname, const std::string& any_string)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
if(event_type == RS_CHAT_LOBBY_EVENT_PEER_STATUS)
|
||||||
|
{
|
||||||
|
locked_storeTypingInfo(ChatId(lobby_id), any_string, nickname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void ChatHandler::tick()
|
void ChatHandler::tick()
|
||||||
{
|
{
|
||||||
|
@ -170,7 +227,44 @@ void ChatHandler::tick()
|
||||||
l.is_broadcast = false;
|
l.is_broadcast = false;
|
||||||
l.gxs_id = info.gxs_id;
|
l.gxs_id = info.gxs_id;
|
||||||
lobbies.push_back(l);
|
lobbies.push_back(l);
|
||||||
|
|
||||||
|
// update the lobby participants list
|
||||||
|
// maybe it causes to much traffic to do this in every tick,
|
||||||
|
// because the client would get the whole list every time a message was received
|
||||||
|
// we could reduce the checking frequency
|
||||||
|
std::map<ChatLobbyId, LobbyParticipantsInfo>::iterator mit = mLobbyParticipantsInfos.find(*lit);
|
||||||
|
if(mit == mLobbyParticipantsInfos.end())
|
||||||
|
{
|
||||||
|
mLobbyParticipantsInfos[*lit].participants = info.gxs_ids;
|
||||||
|
mLobbyParticipantsInfos[*lit].state_token = mStateTokenServer->getNewToken();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LobbyParticipantsInfo& pi = mit->second;
|
||||||
|
if(!std::equal(pi.participants.begin(), pi.participants.end(), info.gxs_ids.begin()))
|
||||||
|
{
|
||||||
|
pi.participants = info.gxs_ids;
|
||||||
|
mStateTokenServer->replaceToken(pi.state_token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove participants info of old lobbies
|
||||||
|
std::vector<ChatLobbyId> participants_info_to_delete;
|
||||||
|
for(std::map<ChatLobbyId, LobbyParticipantsInfo>::iterator mit = mLobbyParticipantsInfos.begin();
|
||||||
|
mit != mLobbyParticipantsInfos.end(); ++mit)
|
||||||
|
{
|
||||||
|
if(std::find(subscribed_ids.begin(), subscribed_ids.end(), mit->first) == subscribed_ids.end())
|
||||||
|
{
|
||||||
|
participants_info_to_delete.push_back(mit->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(std::vector<ChatLobbyId>::iterator vit = participants_info_to_delete.begin(); vit != participants_info_to_delete.end(); ++vit)
|
||||||
|
{
|
||||||
|
LobbyParticipantsInfo& pi = mLobbyParticipantsInfos[*vit];
|
||||||
|
mStateTokenServer->discardToken(pi.state_token);
|
||||||
|
mLobbyParticipantsInfos.erase(*vit);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -369,6 +463,46 @@ void ChatHandler::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void writeUTF8 ( std::ostream & Out, unsigned int Ch )
|
||||||
|
/* writes Ch in UTF-8 encoding to Out. Note this version only deals
|
||||||
|
with characters up to 16 bits.
|
||||||
|
From: http://www.codecodex.com/wiki/Unescape_HTML_special_characters_from_a_String*/
|
||||||
|
{
|
||||||
|
if (Ch >= 0x800)
|
||||||
|
{
|
||||||
|
Out.put(0xE0 | ((Ch >> 12) & 0x0F));
|
||||||
|
Out.put(0x80 | ((Ch >> 6) & 0x3F));
|
||||||
|
Out.put(0x80 | ((Ch ) & 0x3F));
|
||||||
|
}
|
||||||
|
else if (Ch >= 0x80)
|
||||||
|
{
|
||||||
|
Out.put(0xC0 | ((Ch >> 6) & 0x1F));
|
||||||
|
Out.put(0x80 | ((Ch ) & 0x3F));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Out.put(Ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int stringToDecUInt ( std::string str)
|
||||||
|
{
|
||||||
|
unsigned int out = 0;
|
||||||
|
unsigned int max = std::numeric_limits<int>::max() / 10;
|
||||||
|
int lenght = str.length();
|
||||||
|
for (int curs = 0; curs < lenght; ++curs) {
|
||||||
|
char c = str[curs];
|
||||||
|
if ( (c >= '0')
|
||||||
|
&& (c <= '9')
|
||||||
|
&& (out < max)
|
||||||
|
) {
|
||||||
|
out *= 10;
|
||||||
|
out += (int)( c - '0');
|
||||||
|
} else return 0;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links)
|
void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links)
|
||||||
{
|
{
|
||||||
if (in.size() == 0)
|
if (in.size() == 0)
|
||||||
|
@ -386,6 +520,9 @@ void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vec
|
||||||
std::string last_six_chars;
|
std::string last_six_chars;
|
||||||
unsigned int tag_start_index = 0;
|
unsigned int tag_start_index = 0;
|
||||||
Triple current_link;
|
Triple current_link;
|
||||||
|
bool onEscapeChar = false;
|
||||||
|
unsigned int escapeCharIndexStart = -1;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < in.size(); ++i)
|
for(unsigned int i = 0; i < in.size(); ++i)
|
||||||
{
|
{
|
||||||
if(keep_link && in[i] == '"')
|
if(keep_link && in[i] == '"')
|
||||||
|
@ -408,10 +545,12 @@ void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vec
|
||||||
if(!ignore || keep_link)
|
if(!ignore || keep_link)
|
||||||
out += in[i];
|
out += in[i];
|
||||||
// "falling edge" resets mode to keep
|
// "falling edge" resets mode to keep
|
||||||
if(in[i] == '>') {
|
if(in[i] == '>' && ignore) {
|
||||||
// leave ignore mode on, if it's a style tag
|
// leave ignore mode on, if it's a style tag
|
||||||
if (tag_start_index == 0 || tag_start_index + 6 > i || in.substr(tag_start_index, 6) != "<style")
|
if (tag_start_index == 0 || tag_start_index + 6 > i || in.substr(tag_start_index, 6) != "<style") {
|
||||||
ignore = false;
|
ignore = false;
|
||||||
|
tag_start_index = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_six_chars += in[i];
|
last_six_chars += in[i];
|
||||||
|
@ -436,7 +575,248 @@ void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vec
|
||||||
}
|
}
|
||||||
current_link = Triple();
|
current_link = Triple();
|
||||||
}
|
}
|
||||||
|
std::string br = "<br/>";
|
||||||
|
if(last_six_chars.size() >= br.size()
|
||||||
|
&& last_six_chars.substr(last_six_chars.size()-br.size()) == br)
|
||||||
|
{
|
||||||
|
out += "\n";
|
||||||
}
|
}
|
||||||
|
if (in[i] == '&') {
|
||||||
|
onEscapeChar = true;
|
||||||
|
escapeCharIndexStart = out.length();
|
||||||
|
}
|
||||||
|
if (ignore || keep_link) {
|
||||||
|
onEscapeChar = false;
|
||||||
|
escapeCharIndexStart = -1;
|
||||||
|
}
|
||||||
|
if ((in[i] == ';') && onEscapeChar) {
|
||||||
|
onEscapeChar = false;
|
||||||
|
bool escapeFound = true;
|
||||||
|
std::string escapeReplace = "";
|
||||||
|
//Keep only escape value to replace it
|
||||||
|
std::string escapeCharValue = out.substr(escapeCharIndexStart,
|
||||||
|
out.length() - escapeCharIndexStart - 1);
|
||||||
|
if (escapeCharValue[0] == '#') {
|
||||||
|
int escapedCharUTF8 = stringToDecUInt(escapeCharValue.substr(1));
|
||||||
|
std::ostringstream escapedSStream;
|
||||||
|
writeUTF8( escapedSStream, escapedCharUTF8);
|
||||||
|
escapeReplace = escapedSStream.str();
|
||||||
|
} else if (escapeCharValue == "euro") {
|
||||||
|
escapeReplace = "€";
|
||||||
|
} else if (escapeCharValue == "nbsp") {
|
||||||
|
escapeReplace = " ";
|
||||||
|
} else if (escapeCharValue == "quot") {
|
||||||
|
escapeReplace = "\"";
|
||||||
|
} else if (escapeCharValue == "amp") {
|
||||||
|
escapeReplace = "&";
|
||||||
|
} else if (escapeCharValue == "lt") {
|
||||||
|
escapeReplace = "<";
|
||||||
|
} else if (escapeCharValue == "gt") {
|
||||||
|
escapeReplace = ">";
|
||||||
|
} else if (escapeCharValue == "iexcl") {
|
||||||
|
escapeReplace = "¡";
|
||||||
|
} else if (escapeCharValue == "cent") {
|
||||||
|
escapeReplace = "¢";
|
||||||
|
} else if (escapeCharValue == "pound") {
|
||||||
|
escapeReplace = "£";
|
||||||
|
} else if (escapeCharValue == "curren") {
|
||||||
|
escapeReplace = "¤";
|
||||||
|
} else if (escapeCharValue == "yen") {
|
||||||
|
escapeReplace = "¥";
|
||||||
|
} else if (escapeCharValue == "brvbar") {
|
||||||
|
escapeReplace = "¦";
|
||||||
|
} else if (escapeCharValue == "sect") {
|
||||||
|
escapeReplace = "§";
|
||||||
|
} else if (escapeCharValue == "uml") {
|
||||||
|
escapeReplace = "¨";
|
||||||
|
} else if (escapeCharValue == "copy") {
|
||||||
|
escapeReplace = "©";
|
||||||
|
} else if (escapeCharValue == "ordf") {
|
||||||
|
escapeReplace = "ª";
|
||||||
|
} else if (escapeCharValue == "not") {
|
||||||
|
escapeReplace = "¬";
|
||||||
|
} else if (escapeCharValue == "shy") {
|
||||||
|
escapeReplace = " ";//?
|
||||||
|
} else if (escapeCharValue == "reg") {
|
||||||
|
escapeReplace = "®";
|
||||||
|
} else if (escapeCharValue == "macr") {
|
||||||
|
escapeReplace = "¯";
|
||||||
|
} else if (escapeCharValue == "deg") {
|
||||||
|
escapeReplace = "°";
|
||||||
|
} else if (escapeCharValue == "plusmn") {
|
||||||
|
escapeReplace = "±";
|
||||||
|
} else if (escapeCharValue == "sup2") {
|
||||||
|
escapeReplace = "²";
|
||||||
|
} else if (escapeCharValue == "sup3") {
|
||||||
|
escapeReplace = "³";
|
||||||
|
} else if (escapeCharValue == "acute") {
|
||||||
|
escapeReplace = "´";
|
||||||
|
} else if (escapeCharValue == "micro") {
|
||||||
|
escapeReplace = "µ";
|
||||||
|
} else if (escapeCharValue == "para") {
|
||||||
|
escapeReplace = "¶";
|
||||||
|
} else if (escapeCharValue == "middot") {
|
||||||
|
escapeReplace = "·";
|
||||||
|
} else if (escapeCharValue == "cedil") {
|
||||||
|
escapeReplace = "¸";
|
||||||
|
} else if (escapeCharValue == "sup1") {
|
||||||
|
escapeReplace = "¹";
|
||||||
|
} else if (escapeCharValue == "ordm") {
|
||||||
|
escapeReplace = "º";
|
||||||
|
} else if (escapeCharValue == "raquo") {
|
||||||
|
escapeReplace = "»";
|
||||||
|
} else if (escapeCharValue == "frac14") {
|
||||||
|
escapeReplace = "¼";
|
||||||
|
} else if (escapeCharValue == "frac12") {
|
||||||
|
escapeReplace = "½";
|
||||||
|
} else if (escapeCharValue == "frac34") {
|
||||||
|
escapeReplace = "¾";
|
||||||
|
} else if (escapeCharValue == "iquest") {
|
||||||
|
escapeReplace = "¿";
|
||||||
|
} else if (escapeCharValue == "Agrave") {
|
||||||
|
escapeReplace = "À";
|
||||||
|
} else if (escapeCharValue == "Aacute") {
|
||||||
|
escapeReplace = "Á";
|
||||||
|
} else if (escapeCharValue == "Acirc") {
|
||||||
|
escapeReplace = "Â";
|
||||||
|
} else if (escapeCharValue == "Atilde") {
|
||||||
|
escapeReplace = "Ã";
|
||||||
|
} else if (escapeCharValue == "Auml") {
|
||||||
|
escapeReplace = "Ä";
|
||||||
|
} else if (escapeCharValue == "Aring") {
|
||||||
|
escapeReplace = "Å";
|
||||||
|
} else if (escapeCharValue == "AElig") {
|
||||||
|
escapeReplace = "Æ";
|
||||||
|
} else if (escapeCharValue == "Ccedil") {
|
||||||
|
escapeReplace = "Ç";
|
||||||
|
} else if (escapeCharValue == "Egrave") {
|
||||||
|
escapeReplace = "È";
|
||||||
|
} else if (escapeCharValue == "Eacute") {
|
||||||
|
escapeReplace = "É";
|
||||||
|
} else if (escapeCharValue == "Ecirc") {
|
||||||
|
escapeReplace = "Ê";
|
||||||
|
} else if (escapeCharValue == "Euml") {
|
||||||
|
escapeReplace = "Ë";
|
||||||
|
} else if (escapeCharValue == "Igrave") {
|
||||||
|
escapeReplace = "Ì";
|
||||||
|
} else if (escapeCharValue == "Iacute") {
|
||||||
|
escapeReplace = "Í";
|
||||||
|
} else if (escapeCharValue == "Icirc") {
|
||||||
|
escapeReplace = "Î";
|
||||||
|
} else if (escapeCharValue == "Iuml") {
|
||||||
|
escapeReplace = "Ï";
|
||||||
|
} else if (escapeCharValue == "ETH") {
|
||||||
|
escapeReplace = "Ð";
|
||||||
|
} else if (escapeCharValue == "Ntilde") {
|
||||||
|
escapeReplace = "Ñ";
|
||||||
|
} else if (escapeCharValue == "Ograve") {
|
||||||
|
escapeReplace = "Ò";
|
||||||
|
} else if (escapeCharValue == "Oacute") {
|
||||||
|
escapeReplace = "Ó";
|
||||||
|
} else if (escapeCharValue == "Ocirc") {
|
||||||
|
escapeReplace = "Ô";
|
||||||
|
} else if (escapeCharValue == "Otilde") {
|
||||||
|
escapeReplace = "Õ";
|
||||||
|
} else if (escapeCharValue == "Ouml") {
|
||||||
|
escapeReplace = "Ö";
|
||||||
|
} else if (escapeCharValue == "times") {
|
||||||
|
escapeReplace = "×";
|
||||||
|
} else if (escapeCharValue == "Oslash") {
|
||||||
|
escapeReplace = "Ø";
|
||||||
|
} else if (escapeCharValue == "Ugrave") {
|
||||||
|
escapeReplace = "Ù";
|
||||||
|
} else if (escapeCharValue == "Uacute") {
|
||||||
|
escapeReplace = "Ú";
|
||||||
|
} else if (escapeCharValue == "Ucirc") {
|
||||||
|
escapeReplace = "Û";
|
||||||
|
} else if (escapeCharValue == "Uuml") {
|
||||||
|
escapeReplace = "Ü";
|
||||||
|
} else if (escapeCharValue == "Yacute") {
|
||||||
|
escapeReplace = "Ý";
|
||||||
|
} else if (escapeCharValue == "THORN") {
|
||||||
|
escapeReplace = "Þ";
|
||||||
|
} else if (escapeCharValue == "szlig") {
|
||||||
|
escapeReplace = "ß";
|
||||||
|
} else if (escapeCharValue == "agrave") {
|
||||||
|
escapeReplace = "à";
|
||||||
|
} else if (escapeCharValue == "aacute") {
|
||||||
|
escapeReplace = "á";
|
||||||
|
} else if (escapeCharValue == "acirc") {
|
||||||
|
escapeReplace = "â";
|
||||||
|
} else if (escapeCharValue == "atilde") {
|
||||||
|
escapeReplace = "ã";
|
||||||
|
} else if (escapeCharValue == "auml") {
|
||||||
|
escapeReplace = "ä";
|
||||||
|
} else if (escapeCharValue == "aring") {
|
||||||
|
escapeReplace = "å";
|
||||||
|
} else if (escapeCharValue == "aelig") {
|
||||||
|
escapeReplace = "æ";
|
||||||
|
} else if (escapeCharValue == "ccedil") {
|
||||||
|
escapeReplace = "ç";
|
||||||
|
} else if (escapeCharValue == "egrave") {
|
||||||
|
escapeReplace = "è";
|
||||||
|
} else if (escapeCharValue == "eacute") {
|
||||||
|
escapeReplace = "é";
|
||||||
|
} else if (escapeCharValue == "ecirc") {
|
||||||
|
escapeReplace = "ê";
|
||||||
|
} else if (escapeCharValue == "euml") {
|
||||||
|
escapeReplace = "ë";
|
||||||
|
} else if (escapeCharValue == "igrave") {
|
||||||
|
escapeReplace = "ì";
|
||||||
|
} else if (escapeCharValue == "iacute") {
|
||||||
|
escapeReplace = "í";
|
||||||
|
} else if (escapeCharValue == "icirc") {
|
||||||
|
escapeReplace = "î";
|
||||||
|
} else if (escapeCharValue == "iuml") {
|
||||||
|
escapeReplace = "ï";
|
||||||
|
} else if (escapeCharValue == "eth") {
|
||||||
|
escapeReplace = "ð";
|
||||||
|
} else if (escapeCharValue == "ntilde") {
|
||||||
|
escapeReplace = "ñ";
|
||||||
|
} else if (escapeCharValue == "ograve") {
|
||||||
|
escapeReplace = "ò";
|
||||||
|
} else if (escapeCharValue == "oacute") {
|
||||||
|
escapeReplace = "ó";
|
||||||
|
} else if (escapeCharValue == "ocirc") {
|
||||||
|
escapeReplace = "ô";
|
||||||
|
} else if (escapeCharValue == "otilde") {
|
||||||
|
escapeReplace = "õ";
|
||||||
|
} else if (escapeCharValue == "ouml") {
|
||||||
|
escapeReplace = "ö";
|
||||||
|
} else if (escapeCharValue == "divide") {
|
||||||
|
escapeReplace = "÷";
|
||||||
|
} else if (escapeCharValue == "oslash") {
|
||||||
|
escapeReplace = "ø";
|
||||||
|
} else if (escapeCharValue == "ugrave") {
|
||||||
|
escapeReplace = "ù";
|
||||||
|
} else if (escapeCharValue == "uacute") {
|
||||||
|
escapeReplace = "ú";
|
||||||
|
} else if (escapeCharValue == "ucirc") {
|
||||||
|
escapeReplace = "û";
|
||||||
|
} else if (escapeCharValue == "uuml") {
|
||||||
|
escapeReplace = "ü";
|
||||||
|
} else if (escapeCharValue == "yacute") {
|
||||||
|
escapeReplace = "ý";
|
||||||
|
} else if (escapeCharValue == "thorn") {
|
||||||
|
escapeReplace = "þ";
|
||||||
|
} else {
|
||||||
|
escapeFound = false;
|
||||||
|
}
|
||||||
|
if (escapeFound) {
|
||||||
|
out = out.substr(0, escapeCharIndexStart-1);
|
||||||
|
out += escapeReplace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHandler::locked_storeTypingInfo(const ChatId &chat_id, std::string status, RsGxsId lobby_gxs_id)
|
||||||
|
{
|
||||||
|
TypingLabelInfo& info = mTypingLabelInfo[chat_id];
|
||||||
|
info.timestamp = time(0);
|
||||||
|
info.status = status;
|
||||||
|
mStateTokenServer->replaceToken(info.state_token);
|
||||||
|
info.author_id = lobby_gxs_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleWildcard(Request &/*req*/, Response &resp)
|
void ChatHandler::handleWildcard(Request &/*req*/, Response &resp)
|
||||||
|
@ -496,11 +876,44 @@ void ChatHandler::handleSubscribeLobby(Request &req, Response &resp)
|
||||||
resp.setFail("lobby join failed. (See console for more info)");
|
resp.setFail("lobby join failed. (See console for more info)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleUnsubscribeLobby(Request &req, Response &/*resp*/)
|
void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
ChatLobbyId id = 0;
|
ChatLobbyId id = 0;
|
||||||
req.mStream << makeKeyValueReference("id", id);
|
req.mStream << makeKeyValueReference("id", id);
|
||||||
mRsMsgs->unsubscribeChatLobby(id);
|
mRsMsgs->unsubscribeChatLobby(id);
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHandler::handleClearLobby(Request &req, Response &resp)
|
||||||
|
{
|
||||||
|
ChatLobbyId id = 0;
|
||||||
|
req.mStream << makeKeyValueReference("id", id);
|
||||||
|
if (id !=0) {
|
||||||
|
notifyChatCleared(ChatId(id));
|
||||||
|
} else {
|
||||||
|
//Is BroadCast
|
||||||
|
notifyChatCleared(ChatId("B"));
|
||||||
|
}
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseTask* ChatHandler::handleLobbyParticipants(Request &req, Response &resp)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
|
||||||
|
ChatId id(req.mPath.top());
|
||||||
|
if(!id.isLobbyId())
|
||||||
|
{
|
||||||
|
resp.setFail("Path element \""+req.mPath.top()+"\" is not a ChatLobbyId.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::map<ChatLobbyId, LobbyParticipantsInfo>::const_iterator mit = mLobbyParticipantsInfos.find(id.toLobbyId());
|
||||||
|
if(mit == mLobbyParticipantsInfos.end())
|
||||||
|
{
|
||||||
|
resp.setFail("lobby not found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return new SendLobbyParticipantsTask(mRsIdentity, mit->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleMessages(Request &req, Response &resp)
|
void ChatHandler::handleMessages(Request &req, Response &resp)
|
||||||
|
@ -573,89 +986,6 @@ void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp)
|
||||||
mStateTokenServer->replaceToken(mUnreadMsgsStateToken);
|
mStateTokenServer->replaceToken(mUnreadMsgsStateToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be removed
|
|
||||||
// we do now cache chat info, to be able to include it in new message notify easily
|
|
||||||
/*
|
|
||||||
class InfoResponseTask: public GxsResponseTask
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InfoResponseTask(ChatHandler* ch, RsPeers* peers, RsIdentity* identity): GxsResponseTask(identity, 0), mChatHandler(ch), mRsPeers(peers), mState(BEGIN){}
|
|
||||||
|
|
||||||
enum State {BEGIN, WAITING};
|
|
||||||
ChatHandler* mChatHandler;
|
|
||||||
RsPeers* mRsPeers;
|
|
||||||
State mState;
|
|
||||||
bool is_broadcast;
|
|
||||||
bool is_gxs_id;
|
|
||||||
bool is_lobby;
|
|
||||||
bool is_peer;
|
|
||||||
std::string remote_author_id;
|
|
||||||
std::string remote_author_name;
|
|
||||||
virtual void gxsDoWork(Request& req, Response& resp)
|
|
||||||
{
|
|
||||||
ChatId id(req.mPath.top());
|
|
||||||
if(id.isNotSet())
|
|
||||||
{
|
|
||||||
resp.setFail("not a valid chat id");
|
|
||||||
done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(mState == BEGIN)
|
|
||||||
{
|
|
||||||
is_broadcast = false;
|
|
||||||
is_gxs_id = false;
|
|
||||||
is_lobby = false;
|
|
||||||
is_peer = false;
|
|
||||||
if(id.isBroadcast())
|
|
||||||
{
|
|
||||||
is_broadcast = true;
|
|
||||||
}
|
|
||||||
else if(id.isGxsId())
|
|
||||||
{
|
|
||||||
is_gxs_id = true;
|
|
||||||
remote_author_id = id.toGxsId().toStdString();
|
|
||||||
requestGxsId(id.toGxsId());
|
|
||||||
}
|
|
||||||
else if(id.isLobbyId())
|
|
||||||
{
|
|
||||||
is_lobby = true;
|
|
||||||
remote_author_id = "";
|
|
||||||
remote_author_name = mChatHandler->getLobbyInfo(id.toLobbyId()).name;
|
|
||||||
}
|
|
||||||
else if(id.isPeerId())
|
|
||||||
{
|
|
||||||
is_peer = true;
|
|
||||||
remote_author_id = id.toPeerId().toStdString();
|
|
||||||
remote_author_name = mRsPeers->getPeerName(id.toPeerId());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error in InfoResponseTask::gxsDoWork(): unhandled chat_id=" << id.toStdString() << std::endl;
|
|
||||||
}
|
|
||||||
mState = WAITING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(is_gxs_id)
|
|
||||||
remote_author_name = getName(id.toGxsId());
|
|
||||||
resp.mDataStream << makeKeyValueReference("remote_author_id", remote_author_id)
|
|
||||||
<< makeKeyValueReference("remote_author_name", remote_author_name)
|
|
||||||
<< makeKeyValueReference("is_broadcast", is_broadcast)
|
|
||||||
<< makeKeyValueReference("is_gxs_id", is_gxs_id)
|
|
||||||
<< makeKeyValueReference("is_lobby", is_lobby)
|
|
||||||
<< makeKeyValueReference("is_peer", is_peer);
|
|
||||||
resp.setOk();
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ResponseTask *ChatHandler::handleInfo(Request &req, Response &resp)
|
|
||||||
{
|
|
||||||
return new InfoResponseTask(this, mRsPeers, mRsIdentity);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ChatHandler::handleInfo(Request &req, Response &resp)
|
void ChatHandler::handleInfo(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
@ -675,14 +1005,99 @@ void ChatHandler::handleInfo(Request &req, Response &resp)
|
||||||
resp.setOk();
|
resp.setOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleTypingLabel(Request &/*req*/, Response &/*resp*/)
|
class SendTypingLabelInfo: public GxsResponseTask
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
SendTypingLabelInfo(RsIdentity* identity, RsPeers* peers, ChatId id, const ChatHandler::TypingLabelInfo& info):
|
||||||
|
GxsResponseTask(identity), mState(BEGIN), mPeers(peers),mId(id), mInfo(info) {}
|
||||||
|
private:
|
||||||
|
enum State {BEGIN, WAITING_ID};
|
||||||
|
State mState;
|
||||||
|
RsPeers* mPeers;
|
||||||
|
ChatId mId;
|
||||||
|
ChatHandler::TypingLabelInfo mInfo;
|
||||||
|
protected:
|
||||||
|
void gxsDoWork(Request& /*req*/, Response& resp)
|
||||||
|
{
|
||||||
|
if(mState == BEGIN)
|
||||||
|
{
|
||||||
|
// lobby and distant require to fetch a gxs_id
|
||||||
|
if(mId.isLobbyId())
|
||||||
|
{
|
||||||
|
requestGxsId(mInfo.author_id);
|
||||||
|
}
|
||||||
|
else if(mId.isDistantChatId())
|
||||||
|
{
|
||||||
|
DistantChatPeerInfo dcpinfo ;
|
||||||
|
rsMsgs->getDistantChatStatus(mId.toDistantChatId(), dcpinfo);
|
||||||
|
requestGxsId(dcpinfo.to_id);
|
||||||
|
}
|
||||||
|
mState = WAITING_ID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string name = "BUG: case not handled in SendTypingLabelInfo";
|
||||||
|
if(mId.isPeerId())
|
||||||
|
{
|
||||||
|
name = mPeers->getPeerName(mId.toPeerId());
|
||||||
|
}
|
||||||
|
else if(mId.isDistantChatId())
|
||||||
|
{
|
||||||
|
DistantChatPeerInfo dcpinfo ;
|
||||||
|
rsMsgs->getDistantChatStatus(mId.toDistantChatId(), dcpinfo);
|
||||||
|
name = getName(dcpinfo.to_id);
|
||||||
|
}
|
||||||
|
else if(mId.isLobbyId())
|
||||||
|
{
|
||||||
|
name = getName(mInfo.author_id);
|
||||||
|
}
|
||||||
|
else if(mId.isBroadcast())
|
||||||
|
{
|
||||||
|
name = mPeers->getPeerName(mId.broadcast_status_peer_id);
|
||||||
|
}
|
||||||
|
uint32_t ts = mInfo.timestamp;
|
||||||
|
resp.mDataStream << makeKeyValueReference("author_name", name)
|
||||||
|
<< makeKeyValueReference("timestamp", ts)
|
||||||
|
<< makeKeyValueReference("status_string", mInfo.status);
|
||||||
|
resp.mStateToken = mInfo.state_token;
|
||||||
|
resp.setOk();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ResponseTask* ChatHandler::handleReceiveStatus(Request &req, Response &resp)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||||
|
ChatId id(req.mPath.top());
|
||||||
|
if(id.isNotSet())
|
||||||
|
{
|
||||||
|
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::map<ChatId, TypingLabelInfo>::iterator mit = mTypingLabelInfo.find(id);
|
||||||
|
if(mit == mTypingLabelInfo.end())
|
||||||
|
{
|
||||||
|
locked_storeTypingInfo(id, "");
|
||||||
|
mit = mTypingLabelInfo.find(id);
|
||||||
|
}
|
||||||
|
return new SendTypingLabelInfo(mRsIdentity, mRsPeers, id, mit->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleSendStatus(Request &/*req*/, Response &/*resp*/)
|
void ChatHandler::handleSendStatus(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
|
std::string chat_id;
|
||||||
|
std::string status;
|
||||||
|
req.mStream << makeKeyValueReference("chat_id", chat_id)
|
||||||
|
<< makeKeyValueReference("status", status);
|
||||||
|
ChatId id(chat_id);
|
||||||
|
if(id.isNotSet())
|
||||||
|
{
|
||||||
|
resp.setFail("chat_id is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRsMsgs->sendStatusString(id, status);
|
||||||
|
resp.setOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatHandler::handleUnreadMsgs(Request &/*req*/, Response &resp)
|
void ChatHandler::handleUnreadMsgs(Request &/*req*/, Response &resp)
|
||||||
|
|
|
@ -25,6 +25,14 @@ public:
|
||||||
// from NotifyClient
|
// from NotifyClient
|
||||||
// note: this may get called from the own and from foreign threads
|
// note: this may get called from the own and from foreign threads
|
||||||
virtual void notifyChatMessage(const ChatMessage& msg);
|
virtual void notifyChatMessage(const ChatMessage& msg);
|
||||||
|
virtual void notifyChatCleared(const ChatId& chat_id);
|
||||||
|
|
||||||
|
// typing label for peer, broadcast and distant chat
|
||||||
|
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */);
|
||||||
|
|
||||||
|
//typing label for lobby chat, peer join and leave messages
|
||||||
|
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,
|
||||||
|
const RsGxsId& /* nickname */,const std::string& /* any string */);
|
||||||
|
|
||||||
// from tickable
|
// from tickable
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
@ -81,6 +89,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LobbyParticipantsInfo{
|
||||||
|
public:
|
||||||
|
StateToken state_token;
|
||||||
|
std::map<RsGxsId, time_t> participants;
|
||||||
|
};
|
||||||
|
|
||||||
class ChatInfo{
|
class ChatInfo{
|
||||||
public:
|
public:
|
||||||
bool is_broadcast;
|
bool is_broadcast;
|
||||||
|
@ -91,20 +105,33 @@ public:
|
||||||
std::string remote_author_name;
|
std::string remote_author_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TypingLabelInfo{
|
||||||
|
public:
|
||||||
|
time_t timestamp;
|
||||||
|
std::string status;
|
||||||
|
StateToken state_token;
|
||||||
|
// only for lobbies
|
||||||
|
RsGxsId author_id;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleWildcard(Request& req, Response& resp);
|
void handleWildcard(Request& req, Response& resp);
|
||||||
void handleLobbies(Request& req, Response& resp);
|
void handleLobbies(Request& req, Response& resp);
|
||||||
void handleSubscribeLobby(Request& req, Response& resp);
|
void handleSubscribeLobby(Request& req, Response& resp);
|
||||||
void handleUnsubscribeLobby(Request& req, Response& resp);
|
void handleUnsubscribeLobby(Request& req, Response& resp);
|
||||||
|
void handleClearLobby(Request& req, Response& resp);
|
||||||
|
ResponseTask* handleLobbyParticipants(Request& req, Response& resp);
|
||||||
void handleMessages(Request& req, Response& resp);
|
void handleMessages(Request& req, Response& resp);
|
||||||
void handleSendMessage(Request& req, Response& resp);
|
void handleSendMessage(Request& req, Response& resp);
|
||||||
void handleMarkChatAsRead(Request& req, Response& resp);
|
void handleMarkChatAsRead(Request& req, Response& resp);
|
||||||
void handleInfo(Request& req, Response& resp);
|
void handleInfo(Request& req, Response& resp);
|
||||||
void handleTypingLabel(Request& req, Response& resp);
|
ResponseTask *handleReceiveStatus(Request& req, Response& resp);
|
||||||
void handleSendStatus(Request& req, Response& resp);
|
void handleSendStatus(Request& req, Response& resp);
|
||||||
void handleUnreadMsgs(Request& req, Response& resp);
|
void handleUnreadMsgs(Request& req, Response& resp);
|
||||||
|
|
||||||
void getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links);
|
void getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links);
|
||||||
|
// last parameter is only used for lobbies!
|
||||||
|
void locked_storeTypingInfo(const ChatId& chat_id, std::string status, RsGxsId lobby_gxs_id = RsGxsId());
|
||||||
|
|
||||||
StateTokenServer* mStateTokenServer;
|
StateTokenServer* mStateTokenServer;
|
||||||
RsNotify* mNotify;
|
RsNotify* mNotify;
|
||||||
|
@ -121,9 +148,13 @@ private:
|
||||||
|
|
||||||
std::map<ChatId, ChatInfo> mChatInfo;
|
std::map<ChatId, ChatInfo> mChatInfo;
|
||||||
|
|
||||||
|
std::map<ChatId, TypingLabelInfo> mTypingLabelInfo;
|
||||||
|
|
||||||
StateToken mLobbiesStateToken;
|
StateToken mLobbiesStateToken;
|
||||||
std::vector<Lobby> mLobbies;
|
std::vector<Lobby> mLobbies;
|
||||||
|
|
||||||
|
std::map<ChatLobbyId, LobbyParticipantsInfo> mLobbyParticipantsInfos;
|
||||||
|
|
||||||
StateToken mUnreadMsgsStateToken;
|
StateToken mUnreadMsgsStateToken;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@ class RsPlugInInterfaces;
|
||||||
|
|
||||||
namespace resource_api{
|
namespace resource_api{
|
||||||
|
|
||||||
|
// populates the given RsPlugInInterfaces object with pointers from gloabl variables like rsPeers, rsMsgs, rsFiles...
|
||||||
bool getPluginInterfaces(RsPlugInInterfaces& interfaces);
|
bool getPluginInterfaces(RsPlugInInterfaces& interfaces);
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
|
|
@ -62,6 +62,7 @@ bool GxsResponseTask::doWork(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
more = false; // pause when an id failed, to give the service time tim fetch the data
|
more = false; // pause when an id failed, to give the service time tim fetch the data
|
||||||
ready = false;
|
ready = false;
|
||||||
|
// TODO: remove identities which failed many times from list, to avoid blocking when ids fail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!ready)
|
if(!ready)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class GxsResponseTask: public ResponseTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// token service is allowed to be null if no token functions are wanted
|
// token service is allowed to be null if no token functions are wanted
|
||||||
GxsResponseTask(RsIdentity* id_service, RsTokenService* token_service);
|
GxsResponseTask(RsIdentity* id_service, RsTokenService* token_service = 0);
|
||||||
virtual bool doWork(Request &req, Response& resp);
|
virtual bool doWork(Request &req, Response& resp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -16,17 +16,18 @@ namespace resource_api
|
||||||
class SendIdentitiesListTask: public GxsResponseTask
|
class SendIdentitiesListTask: public GxsResponseTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SendIdentitiesListTask(RsIdentity* idservice, std::list<RsGxsId> ids):
|
SendIdentitiesListTask(RsIdentity* idservice, std::list<RsGxsId> ids, StateToken state):
|
||||||
GxsResponseTask(idservice, 0)
|
GxsResponseTask(idservice, 0), mStateToken(state)
|
||||||
{
|
{
|
||||||
for(std::list<RsGxsId>::iterator vit = ids.begin(); vit != ids.end(); ++vit)
|
for(std::list<RsGxsId>::iterator vit = ids.begin(); vit != ids.end(); ++vit)
|
||||||
{
|
{
|
||||||
requestGxsId(*vit);
|
requestGxsId(*vit);
|
||||||
mIds.push_back(*vit);// convert fro list to vector
|
mIds.push_back(*vit);// convert from list to vector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::vector<RsGxsId> mIds;
|
std::vector<RsGxsId> mIds;
|
||||||
|
StateToken mStateToken;
|
||||||
protected:
|
protected:
|
||||||
virtual void gxsDoWork(Request &req, Response &resp)
|
virtual void gxsDoWork(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
|
@ -35,17 +36,89 @@ protected:
|
||||||
{
|
{
|
||||||
streamGxsId(*vit, resp.mDataStream.getStreamToMember());
|
streamGxsId(*vit, resp.mDataStream.getStreamToMember());
|
||||||
}
|
}
|
||||||
|
resp.mStateToken = mStateToken;
|
||||||
resp.setOk();
|
resp.setOk();
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IdentityHandler::IdentityHandler(RsIdentity *identity):
|
class CreateIdentityTask: public GxsResponseTask
|
||||||
mRsIdentity(identity)
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
CreateIdentityTask(RsIdentity* idservice):
|
||||||
|
GxsResponseTask(idservice, idservice->getTokenService()), mState(BEGIN), mToken(0), mRsIdentity(idservice){}
|
||||||
|
private:
|
||||||
|
enum State {BEGIN, WAIT_ACKN, WAIT_ID};
|
||||||
|
State mState;
|
||||||
|
uint32_t mToken;
|
||||||
|
RsIdentity* mRsIdentity;
|
||||||
|
RsGxsId mId;
|
||||||
|
protected:
|
||||||
|
virtual void gxsDoWork(Request &req, Response &resp)
|
||||||
|
{
|
||||||
|
switch(mState)
|
||||||
|
{
|
||||||
|
case BEGIN:{
|
||||||
|
RsIdentityParameters params;
|
||||||
|
req.mStream << makeKeyValueReference("name", params.nickname) << makeKeyValueReference("pgp_linked", params.isPgpLinked);
|
||||||
|
|
||||||
|
if(params.nickname == "")
|
||||||
|
{
|
||||||
|
resp.setFail("name can't be empty");
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRsIdentity->createIdentity(mToken, params);
|
||||||
|
addWaitingToken(mToken);
|
||||||
|
mState = WAIT_ACKN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WAIT_ACKN:{
|
||||||
|
RsGxsGroupId grpId;
|
||||||
|
if(!mRsIdentity->acknowledgeGrp(mToken, grpId))
|
||||||
|
{
|
||||||
|
resp.setFail("acknowledge of group id failed");
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mId = RsGxsId(grpId);
|
||||||
|
requestGxsId(mId);
|
||||||
|
mState = WAIT_ID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WAIT_ID:
|
||||||
|
streamGxsId(mId, resp.mDataStream);
|
||||||
|
resp.setOk();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIdentity *identity):
|
||||||
|
mStateTokenServer(sts), mNotify(notify), mRsIdentity(identity),
|
||||||
|
mMtx("IdentityHandler Mtx"), mStateToken(sts->getNewToken())
|
||||||
|
{
|
||||||
|
mNotify->registerNotifyClient(this);
|
||||||
|
|
||||||
addResourceHandler("*", this, &IdentityHandler::handleWildcard);
|
addResourceHandler("*", this, &IdentityHandler::handleWildcard);
|
||||||
addResourceHandler("own", this, &IdentityHandler::handleOwn);
|
addResourceHandler("own", this, &IdentityHandler::handleOwn);
|
||||||
|
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentityHandler::~IdentityHandler()
|
||||||
|
{
|
||||||
|
mNotify->unregisterNotifyClient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdentityHandler::notifyGxsChange(const RsGxsChanges &changes)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
||||||
|
// if changes come from identity service, invalidate own state token
|
||||||
|
if(changes.mService == mRsIdentity->getTokenService())
|
||||||
|
{
|
||||||
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||||
|
@ -54,6 +127,7 @@ void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||||
|
|
||||||
if(req.isPut())
|
if(req.isPut())
|
||||||
{
|
{
|
||||||
|
#ifdef REMOVE
|
||||||
RsIdentityParameters params;
|
RsIdentityParameters params;
|
||||||
req.mStream << makeKeyValueReference("name", params.nickname);
|
req.mStream << makeKeyValueReference("name", params.nickname);
|
||||||
if(req.mStream.isOK())
|
if(req.mStream.isOK())
|
||||||
|
@ -67,9 +141,14 @@ void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
||||||
|
resp.mStateToken = mStateToken;
|
||||||
|
}
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
|
@ -124,14 +203,24 @@ void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseTask* IdentityHandler::handleOwn(Request &req, Response &resp)
|
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
|
||||||
{
|
{
|
||||||
|
StateToken state;
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
||||||
|
state = mStateToken;
|
||||||
|
}
|
||||||
std::list<RsGxsId> ids;
|
std::list<RsGxsId> ids;
|
||||||
if(mRsIdentity->getOwnIds(ids))
|
if(mRsIdentity->getOwnIds(ids))
|
||||||
return new SendIdentitiesListTask(mRsIdentity, ids);
|
return new SendIdentitiesListTask(mRsIdentity, ids, state);
|
||||||
resp.mDataStream.getStreamToMember();
|
resp.mDataStream.getStreamToMember();
|
||||||
resp.setWarning("identities not loaded yet");
|
resp.setWarning("identities not loaded yet");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResponseTask* IdentityHandler::handleCreateIdentity(Request & /* req */, Response & /* resp */)
|
||||||
|
{
|
||||||
|
return new CreateIdentityTask(mRsIdentity);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
|
|
@ -1,19 +1,36 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <retroshare/rsnotify.h>
|
||||||
|
#include <util/rsthreads.h>
|
||||||
|
|
||||||
#include "ResourceRouter.h"
|
#include "ResourceRouter.h"
|
||||||
|
#include "StateTokenServer.h"
|
||||||
|
|
||||||
class RsIdentity;
|
class RsIdentity;
|
||||||
|
|
||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
|
|
||||||
class IdentityHandler: public ResourceRouter
|
class IdentityHandler: public ResourceRouter, NotifyClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IdentityHandler(RsIdentity* identity);
|
IdentityHandler(StateTokenServer* sts, RsNotify* notify, RsIdentity* identity);
|
||||||
|
virtual ~IdentityHandler();
|
||||||
|
|
||||||
|
// from NotifyClient
|
||||||
|
// note: this may get called from foreign threads
|
||||||
|
virtual void notifyGxsChange(const RsGxsChanges &changes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsIdentity* mRsIdentity;
|
|
||||||
void handleWildcard(Request& req, Response& resp);
|
void handleWildcard(Request& req, Response& resp);
|
||||||
ResponseTask *handleOwn(Request& req, Response& resp);
|
ResponseTask *handleOwn(Request& req, Response& resp);
|
||||||
|
ResponseTask *handleCreateIdentity(Request& req, Response& resp);
|
||||||
|
|
||||||
|
StateTokenServer* mStateTokenServer;
|
||||||
|
RsNotify* mNotify;
|
||||||
|
RsIdentity* mRsIdentity;
|
||||||
|
|
||||||
|
RsMutex mMtx;
|
||||||
|
StateToken mStateToken; // mutex protected
|
||||||
};
|
};
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
|
|
@ -24,6 +24,7 @@ void handlePaginationRequest(Request& req, Response& resp, C& data)
|
||||||
// set result type to list
|
// set result type to list
|
||||||
resp.mDataStream.getStreamToMember();
|
resp.mDataStream.getStreamToMember();
|
||||||
resp.mDebug << "note: list is empty" << std::endl;
|
resp.mDebug << "note: list is empty" << std::endl;
|
||||||
|
resp.setOk();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ PeersHandler::~PeersHandler()
|
||||||
mStateTokenServer->unregisterTickClient(this);
|
mStateTokenServer->unregisterTickClient(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeersHandler::notifyListChange(int list, int type)
|
void PeersHandler::notifyListChange(int list, int /* type */)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||||
if(list == NOTIFY_LIST_FRIENDS)
|
if(list == NOTIFY_LIST_FRIENDS)
|
||||||
|
@ -193,6 +193,8 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
|
||||||
ok &= mRsPeers->getPeerDetails(*lit, details);
|
ok &= mRsPeers->getPeerDetails(*lit, details);
|
||||||
detailsVec.push_back(details);
|
detailsVec.push_back(details);
|
||||||
}
|
}
|
||||||
|
// mark response as list, in case it is empty
|
||||||
|
resp.mDataStream.getStreamToMember();
|
||||||
for(std::list<RsPgpId>::iterator lit = identities.begin(); lit != identities.end(); ++lit)
|
for(std::list<RsPgpId>::iterator lit = identities.begin(); lit != identities.end(); ++lit)
|
||||||
{
|
{
|
||||||
// if no own ssl id is known, then hide the own id from the friendslist
|
// if no own ssl id is known, then hide the own id from the friendslist
|
||||||
|
|
|
@ -12,7 +12,7 @@ public:
|
||||||
{
|
{
|
||||||
addResourceHandler("eins", this, &TestResource::eins);
|
addResourceHandler("eins", this, &TestResource::eins);
|
||||||
}
|
}
|
||||||
ResponseTask* eins(Request& req, Response& resp)
|
ResponseTask* eins(Request& /* req */, Response& /* resp */)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, A
|
||||||
this->argv = argv;
|
this->argv = argv;
|
||||||
// start worker thread
|
// start worker thread
|
||||||
if(full_control)
|
if(full_control)
|
||||||
start();
|
start("resapi ctrl mod");
|
||||||
else
|
else
|
||||||
mRunState = RUNNING_OK_NO_FULL_CONTROL;
|
mRunState = RUNNING_OK_NO_FULL_CONTROL;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ bool RsControlModule::processShouldExit()
|
||||||
return mProcessShouldExit;
|
return mProcessShouldExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsControlModule::askForPassword(const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled)
|
bool RsControlModule::askForPassword(const std::string &key_details, bool /* prev_is_bad */, std::string &password, bool& cancelled)
|
||||||
{
|
{
|
||||||
cancelled = false ;
|
cancelled = false ;
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "Operators.h"
|
#include "Operators.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
// maybe move to another place later
|
// maybe move to another place later
|
||||||
|
@ -44,6 +46,7 @@ ServiceControlHandler::ServiceControlHandler(RsServiceControl* control):
|
||||||
mRsServiceControl(control)
|
mRsServiceControl(control)
|
||||||
{
|
{
|
||||||
addResourceHandler("*", this, &ServiceControlHandler::handleWildcard);
|
addResourceHandler("*", this, &ServiceControlHandler::handleWildcard);
|
||||||
|
addResourceHandler("user", this, &ServiceControlHandler::handleUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceControlHandler::handleWildcard(Request &req, Response &resp)
|
void ServiceControlHandler::handleWildcard(Request &req, Response &resp)
|
||||||
|
@ -73,7 +76,42 @@ void ServiceControlHandler::handleWildcard(Request &req, Response &resp)
|
||||||
}
|
}
|
||||||
else if(req.isPut())
|
else if(req.isPut())
|
||||||
{
|
{
|
||||||
|
// change service default
|
||||||
|
|
||||||
|
std::string serviceidtext;
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("service_id", serviceidtext)
|
||||||
|
<< makeKeyValueReference("default_allowed", enabled);
|
||||||
|
|
||||||
|
RsServicePermissions serv_perms ;
|
||||||
|
//uint32_t serviceid = fromString<uint32_t>(serviceidtext);
|
||||||
|
uint32_t serviceid = atoi(serviceidtext.c_str());
|
||||||
|
if (serviceid == 0) {
|
||||||
|
resp.setFail("service_id missed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rsServiceControl->getServicePermissions(serviceid, serv_perms)){
|
||||||
|
resp.setFail("service_id " + serviceidtext + " is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serv_perms.mDefaultAllowed = enabled;
|
||||||
|
if(serv_perms.mDefaultAllowed)
|
||||||
|
{
|
||||||
|
serv_perms.mPeersDenied.clear() ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serv_perms.mPeersAllowed.clear() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = rsServiceControl->updateServicePermissions(serviceid,serv_perms);
|
||||||
|
if (!ok) {
|
||||||
|
resp.setFail("updateServicePermissions failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ok)
|
if(ok)
|
||||||
|
@ -86,4 +124,62 @@ void ServiceControlHandler::handleWildcard(Request &req, Response &resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServiceControlHandler::handleUser(Request& req, Response& resp){
|
||||||
|
// no get, only put (post) to allow user or delete to remove user
|
||||||
|
|
||||||
|
std::string serviceidtext;
|
||||||
|
std::string peeridtext;
|
||||||
|
bool enabled;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("service_id", serviceidtext)
|
||||||
|
<< makeKeyValueReference("peer_id", peeridtext)
|
||||||
|
<< makeKeyValueReference("enabled", enabled);
|
||||||
|
|
||||||
|
RsPeerId peer_id(peeridtext);
|
||||||
|
|
||||||
|
if (peer_id.isNull()) {
|
||||||
|
resp.setFail("peer_id missing or not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsServicePermissions serv_perms ;
|
||||||
|
uint32_t serviceid = atoi(serviceidtext.c_str());
|
||||||
|
if (serviceid == 0) {
|
||||||
|
resp.setFail("service_id missed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rsServiceControl->getServicePermissions(serviceid, serv_perms)){
|
||||||
|
resp.setFail("service_id " + serviceidtext + " is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(req.isPut())
|
||||||
|
{
|
||||||
|
if (enabled && !serv_perms.peerHasPermission(peer_id))
|
||||||
|
{
|
||||||
|
serv_perms.setPermission(peer_id);
|
||||||
|
} else if (!enabled && serv_perms.peerHasPermission(peer_id)){
|
||||||
|
serv_perms.resetPermission(peer_id);
|
||||||
|
} else {
|
||||||
|
//nothing todo
|
||||||
|
resp.setOk();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
resp.setFail("only POST supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok = rsServiceControl->updateServicePermissions(serviceid,serv_perms);
|
||||||
|
if (!ok) {
|
||||||
|
resp.setFail("updateServicePermissions failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
|
|
@ -16,5 +16,6 @@ public:
|
||||||
private:
|
private:
|
||||||
RsServiceControl* mRsServiceControl;
|
RsServiceControl* mRsServiceControl;
|
||||||
void handleWildcard(Request& req, Response& resp);
|
void handleWildcard(Request& req, Response& resp);
|
||||||
|
void handleUser(Request& req, Response& resp);
|
||||||
};
|
};
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
|
|
@ -114,6 +114,7 @@ void StateTokenServer::handleWildcard(Request &req, Response &resp)
|
||||||
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
|
||||||
// want to lookpup many tokens at once, return a list of invalid tokens
|
// want to lookpup many tokens at once, return a list of invalid tokens
|
||||||
// TODO: make generic list serialiser/deserialiser
|
// TODO: make generic list serialiser/deserialiser
|
||||||
|
resp.mDataStream.getStreamToMember();
|
||||||
while(req.mStream.hasMore())
|
while(req.mStream.hasMore())
|
||||||
{
|
{
|
||||||
StateToken token;
|
StateToken token;
|
||||||
|
|
|
@ -42,7 +42,7 @@ void TransfersHandler::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersHandler::handleWildcard(Request &req, Response &resp)
|
void TransfersHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ void TransfersHandler::handleControlDownload(Request &req, Response &resp)
|
||||||
resp.setFail("error: action not handled");
|
resp.setFail("error: action not handled");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersHandler::handleDownloads(Request &req, Response &resp)
|
void TransfersHandler::handleDownloads(Request & /* req */, Response &resp)
|
||||||
{
|
{
|
||||||
tick();
|
tick();
|
||||||
resp.mStateToken = mStateToken;
|
resp.mStateToken = mStateToken;
|
||||||
|
|
|
@ -525,7 +525,7 @@ std::string SerializeValue(const Value& v)
|
||||||
// json expets decimal points, so replace all commas with decimal points
|
// json expets decimal points, so replace all commas with decimal points
|
||||||
if(v.GetType() == FloatVal || v.GetType() == DoubleVal)
|
if(v.GetType() == FloatVal || v.GetType() == DoubleVal)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < str.size(); i++)
|
for(unsigned int i = 0; i < str.size(); i++)
|
||||||
if(str[i] == ',')
|
if(str[i] == ',')
|
||||||
str[i] = '.';
|
str[i] = '.';
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,97 @@ CONFIG += libmicrohttpd
|
||||||
INCLUDEPATH += ../../libretroshare/src
|
INCLUDEPATH += ../../libretroshare/src
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
|
|
||||||
webui_files.path = "$${DATA_DIR}/webui"
|
webui_files.path = "$${DATA_DIR}/webui"
|
||||||
webui_files.files = webfiles/*
|
webui_files.files = webui/app.js webui/app.css webui/index.html
|
||||||
INSTALLS += webui_files
|
INSTALLS += webui_files
|
||||||
|
|
||||||
webui_img_files.path = "$${DATA_DIR}/webui/img"
|
webui_img_files.path = "$${DATA_DIR}/webui/img"
|
||||||
webui_img_files.files = ../../retroshare-gui/src/gui/images/logo/logo_splash.png
|
webui_img_files.files = ../../retroshare-gui/src/gui/images/logo/logo_splash.png
|
||||||
INSTALLS += webui_img_files
|
INSTALLS += webui_img_files
|
||||||
|
|
||||||
|
# create dummy files, we need it to include files on first try
|
||||||
|
system(webui-src/make-src/build.sh .)
|
||||||
|
|
||||||
|
WEBUI_SRC_SCRIPT = webui-src/make-src/build.sh
|
||||||
|
|
||||||
|
WEBUI_SRC_HTML = $$WEBUI_SRC_SCRIPT
|
||||||
|
WEBUI_SRC_HTML += webui-src/app/assets/index.html
|
||||||
|
|
||||||
|
WEBUI_SRC_JS = $$WEBUI_SRC_SCRIPT
|
||||||
|
WEBUI_SRC_JS += webui-src/app/accountselect.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/adddownloads.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/addidentity.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/addpeer.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/chat.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/createlogin.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/downloads.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/forums.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/home.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/identities.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/main.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/menudef.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/menu.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/mithril.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/mithril.min.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/peers.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/retroshare.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/search.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/searchresult.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/servicecontrol.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/settings.js
|
||||||
|
WEBUI_SRC_JS += webui-src/app/waiting.js
|
||||||
|
|
||||||
|
WEBUI_SRC_CSS = $$WEBUI_SRC_SCRIPT
|
||||||
|
WEBUI_SRC_CSS += webui-src/app/green-black.scss
|
||||||
|
WEBUI_SRC_CSS += webui-src/app/_reset.scss
|
||||||
|
WEBUI_SRC_CSS += webui-src/app/_chat.sass
|
||||||
|
WEBUI_SRC_CSS += webui-src/app/main.sass
|
||||||
|
|
||||||
|
|
||||||
|
create_webfiles_html.output = webui/index.html
|
||||||
|
create_webfiles_html.input = WEBUI_SRC_HTML
|
||||||
|
create_webfiles_html.commands = sh $$_PRO_FILE_PWD_/webui-src/make-src/build.sh $$_PRO_FILE_PWD_ index.html .
|
||||||
|
create_webfiles_html.variable_out = JUNK
|
||||||
|
create_webfiles_html.CONFIG = combine no_link
|
||||||
|
|
||||||
|
create_webfiles_js.output = webui/app.js
|
||||||
|
create_webfiles_js.input = WEBUI_SRC_JS
|
||||||
|
create_webfiles_js.commands = sh $$_PRO_FILE_PWD_/webui-src/make-src/build.sh $$_PRO_FILE_PWD_ app.js .
|
||||||
|
create_webfiles_js.variable_out = JUNK
|
||||||
|
create_webfiles_js.CONFIG = combine no_link
|
||||||
|
|
||||||
|
create_webfiles_css.output = webui/app.css
|
||||||
|
create_webfiles_css.input = WEBUI_SRC_CSS
|
||||||
|
create_webfiles_css.commands = sh $$_PRO_FILE_PWD_/webui-src/make-src/build.sh $$_PRO_FILE_PWD_ app.css .
|
||||||
|
create_webfiles_css.variable_out = JUNK
|
||||||
|
create_webfiles_css.CONFIG = combine no_link
|
||||||
|
|
||||||
|
|
||||||
|
QMAKE_EXTRA_COMPILERS += create_webfiles_html create_webfiles_js create_webfiles_css
|
||||||
}
|
}
|
||||||
|
|
||||||
win32{
|
win32{
|
||||||
DEFINES *= WINDOWS_SYS
|
DEFINES *= WINDOWS_SYS
|
||||||
INCLUDEPATH += . $$INC_DIR
|
INCLUDEPATH += . $$INC_DIR
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
|
# Qt 5
|
||||||
|
PRO_PATH=$$shell_path($$_PRO_FILE_PWD_)
|
||||||
|
MAKE_SRC=$$shell_path($$PRO_PATH/webui-src/make-src)
|
||||||
|
} else {
|
||||||
|
# Qt 4
|
||||||
|
PRO_PATH=$$replace(_PRO_FILE_PWD_, /, \\)
|
||||||
|
MAKE_SRC=$$PRO_PATH\\webui-src\\make-src
|
||||||
|
}
|
||||||
|
|
||||||
|
#create_webfiles.commands = $$MAKE_SRC\\build.bat $$PRO_PATH
|
||||||
|
#QMAKE_EXTRA_TARGETS += create_webfiles
|
||||||
|
#PRE_TARGETDEPS += create_webfiles
|
||||||
|
QMAKE_POST_LINK=$$MAKE_SRC\\build.bat $$PRO_PATH
|
||||||
|
|
||||||
|
# create dummy files
|
||||||
|
system($$MAKE_SRC\\init.bat .)
|
||||||
}
|
}
|
||||||
|
|
||||||
libmicrohttpd{
|
libmicrohttpd{
|
||||||
|
@ -66,7 +145,8 @@ SOURCES += \
|
||||||
api/LivereloadHandler.cpp \
|
api/LivereloadHandler.cpp \
|
||||||
api/TmpBlobStore.cpp \
|
api/TmpBlobStore.cpp \
|
||||||
util/ContentTypes.cpp \
|
util/ContentTypes.cpp \
|
||||||
api/ApiPluginHandler.cpp
|
api/ApiPluginHandler.cpp \
|
||||||
|
api/ChannelsHandler.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
api/ApiServer.h \
|
api/ApiServer.h \
|
||||||
|
@ -91,4 +171,5 @@ HEADERS += \
|
||||||
api/LivereloadHandler.h \
|
api/LivereloadHandler.h \
|
||||||
api/TmpBlobStore.h \
|
api/TmpBlobStore.h \
|
||||||
util/ContentTypes.h \
|
util/ContentTypes.h \
|
||||||
api/ApiPluginHandler.h
|
api/ApiPluginHandler.h \
|
||||||
|
api/ChannelsHandler.h
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,109 +0,0 @@
|
||||||
/**
|
|
||||||
* JS Api for Retroshare
|
|
||||||
* @constructor
|
|
||||||
* @param {object} connection - an object which implements a request() function.
|
|
||||||
* The request function should take two parameters: an object to be send as request and a callback.
|
|
||||||
* The callback should get called with an response object on success.
|
|
||||||
*/
|
|
||||||
function RsApi(connection)
|
|
||||||
{
|
|
||||||
var runnign = true;
|
|
||||||
/**
|
|
||||||
* Send a request to the server
|
|
||||||
* @param req - the request so send
|
|
||||||
* @param {Function} cb - callback function which takes the response as parameter
|
|
||||||
*/
|
|
||||||
this.request = function(req, cb)
|
|
||||||
{
|
|
||||||
connection.request(req, cb);
|
|
||||||
};
|
|
||||||
var tokenlisteners = [];
|
|
||||||
/**
|
|
||||||
* Register a callback to be called when the state token expired.
|
|
||||||
* @param {Function} listener - the callback function, which does not take arguments
|
|
||||||
* @param token - the state token to listen for
|
|
||||||
*/
|
|
||||||
this.register_token_listener = function(listener, token)
|
|
||||||
{
|
|
||||||
tokenlisteners.push({listener:listener, token:token});
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Unregister a previously registered callback.
|
|
||||||
*/
|
|
||||||
this.unregister_token_listener = function(listener) // no token as parameter, assuming unregister from all listening tokens
|
|
||||||
{
|
|
||||||
var to_delete = [];
|
|
||||||
for(var i=0; i<tokenlisteners.length; i++){
|
|
||||||
if(tokenlisteners[i].listener === listener){
|
|
||||||
to_delete.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(var i=0; i<to_delete.length; i++){
|
|
||||||
// copy the last element to the current index
|
|
||||||
var index = to_delete[i];
|
|
||||||
tokenlisteners[index] = tokenlisteners[tokenlisteners.length-1];
|
|
||||||
// remove last element
|
|
||||||
tokenlisteners.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* start polling for state changes
|
|
||||||
*/
|
|
||||||
this.start = function(){
|
|
||||||
running = true;
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* stop polling for state changes
|
|
||||||
*/
|
|
||||||
this.stop = function(){
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************** interal stuff **************
|
|
||||||
var TICK_INTERVAL = 3000;
|
|
||||||
function received_tokenstates(resp)
|
|
||||||
{
|
|
||||||
if(resp.data){
|
|
||||||
for(var i=0; i<resp.data.length; i++){
|
|
||||||
var token = resp.data[i];
|
|
||||||
// search the listener for this token
|
|
||||||
for(var j=0; j<tokenlisteners.length; j++){
|
|
||||||
if(tokenlisteners[j].token === token){
|
|
||||||
// call the listener
|
|
||||||
tokenlisteners[j].listener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// schedule new update
|
|
||||||
if(running)
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
};
|
|
||||||
function received_error()
|
|
||||||
{
|
|
||||||
// try again, maybe want a better logic later
|
|
||||||
if(running)
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
};
|
|
||||||
function tick()
|
|
||||||
{
|
|
||||||
var data = [];
|
|
||||||
// maybe cache the token list?
|
|
||||||
// profiler will tell us if we should
|
|
||||||
for(var i=0; i<tokenlisteners.length; i++){
|
|
||||||
data.push(tokenlisteners[i].token);
|
|
||||||
}
|
|
||||||
connection.request({
|
|
||||||
path: "statetokenservice",
|
|
||||||
data: data,
|
|
||||||
}, received_tokenstates, received_error);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// with this trick, we should be able to run in browser or nodejs
|
|
||||||
if(typeof window === 'undefined')
|
|
||||||
{
|
|
||||||
// we are running in nodejs, so have to add to export
|
|
||||||
module.exports = RsApi;
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
/**
|
|
||||||
* Connection to the RS backend using XHR
|
|
||||||
* (could add other connections later, for example WebSockets)
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function RsXHRConnection(server_hostname, server_port)
|
|
||||||
{
|
|
||||||
var debug;
|
|
||||||
//debug = function(str){console.log(str);};
|
|
||||||
debug = function(str){};
|
|
||||||
|
|
||||||
//server_hostname = "localhost";
|
|
||||||
//server_port = "9090";
|
|
||||||
var api_root_path = "/api/v2/";
|
|
||||||
|
|
||||||
var status_listeners = [];
|
|
||||||
|
|
||||||
function notify_status(status)
|
|
||||||
{
|
|
||||||
for(var i = 0; i < status_listeners.length; i++)
|
|
||||||
{
|
|
||||||
status_listeners[i](status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a callback to be called when the state of the connection changes.
|
|
||||||
* @param {function} cb - callback which receives a single argument. The arguments value is "connected" or "not_connected".
|
|
||||||
*/
|
|
||||||
this.register_status_listener = function(cb)
|
|
||||||
{
|
|
||||||
status_listeners.push(cb);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister a status callback function.
|
|
||||||
* @param {function} cb - a privously registered callback function
|
|
||||||
*/
|
|
||||||
this.unregister_status_listener = function(cb)
|
|
||||||
{
|
|
||||||
var to_delete = [];
|
|
||||||
for(var i = 0; i < status_listeners.length; i++)
|
|
||||||
{
|
|
||||||
if(status_listeners[i] === cb){
|
|
||||||
to_delete.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(var i = 0; i < to_delete.length; i++)
|
|
||||||
{
|
|
||||||
// copy the last element to the current index
|
|
||||||
var index = to_delete[i];
|
|
||||||
status_listeners[i] = status_listeners[status_listeners.length-1];
|
|
||||||
// remove the last element
|
|
||||||
status_listeners.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a request to the backend
|
|
||||||
* automatically encodes the request as JSON before sending it to the server
|
|
||||||
* @param {object} req - the request to send to the server
|
|
||||||
* @param {function} cb - callback function to be called to handle the response. The callback takes one object as parameter. Can be left undefined.
|
|
||||||
* @param {function} err_cb - callback function to signal a failed request. Can be undefined.
|
|
||||||
*/
|
|
||||||
this.request = function(req, cb, err_cb)
|
|
||||||
{
|
|
||||||
//var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
|
|
||||||
// TODO: window is not available in QML
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.onreadystatechange = function(){
|
|
||||||
//console.log("onreadystatechanged state"+xhr.readyState);
|
|
||||||
// TODO: figure out how to catch errors like connection refused
|
|
||||||
// maybe want to have to set a state variable like ok=false
|
|
||||||
// the gui could then display: "no connection to server"
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if(xhr.status !== 200)
|
|
||||||
{
|
|
||||||
console.log("RsXHRConnection: request failed with status: "+xhr.status);
|
|
||||||
console.log("request was:");
|
|
||||||
console.log(req);
|
|
||||||
notify_status("not_connected");
|
|
||||||
if(err_cb !== undefined)
|
|
||||||
err_cb();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// received response
|
|
||||||
notify_status("connected");
|
|
||||||
debug("RsXHRConnection received response:");
|
|
||||||
debug(xhr.responseText);
|
|
||||||
if(false)//if(xhr.responseText === "")
|
|
||||||
{
|
|
||||||
debug("Warning: response is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var respObj = JSON.parse(xhr.responseText);
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
debug("Exception during response handling: "+e);
|
|
||||||
}
|
|
||||||
if(cb === undefined)
|
|
||||||
debug("No callback function specified");
|
|
||||||
else
|
|
||||||
cb(respObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// post is required for sending data
|
|
||||||
var method;
|
|
||||||
if(req.data){
|
|
||||||
method = "POST";
|
|
||||||
} else {
|
|
||||||
method = "GET";
|
|
||||||
}
|
|
||||||
xhr.open(method, "http://"+server_hostname+":"+server_port+api_root_path+req.path);
|
|
||||||
var data = JSON.stringify(req.data);
|
|
||||||
debug("RsXHRConnection sending data:");
|
|
||||||
debug(data);
|
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
||||||
xhr.send(data);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,134 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: black;
|
|
||||||
color: lime;
|
|
||||||
font-family: monospace;
|
|
||||||
margin: 0em;
|
|
||||||
/*padding: 1.5em;*/
|
|
||||||
padding: 2mm;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#overlay{
|
|
||||||
z-index: 10;
|
|
||||||
position: fixed;
|
|
||||||
top:0;
|
|
||||||
left:0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.paddingbox{
|
|
||||||
padding:2mm;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav{
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0em;
|
|
||||||
margin: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav li{
|
|
||||||
display: inline;
|
|
||||||
padding: 0.1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
border-width: 0.1em;
|
|
||||||
border-color: blue;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
td{
|
|
||||||
padding: 0.3em;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0.1em;
|
|
||||||
border-color: lime;
|
|
||||||
}
|
|
||||||
.btn{
|
|
||||||
border-style: solid;
|
|
||||||
border-color: lime;
|
|
||||||
border-width: 0.1em;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn2, .box{
|
|
||||||
border-style: solid;
|
|
||||||
/*border-color: lime;*/
|
|
||||||
border-color: limeGreen;
|
|
||||||
/*border-width: 1px;*/
|
|
||||||
border-radius: 3mm;
|
|
||||||
padding: 2mm;
|
|
||||||
font-size: 10mm;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-bottom: 2mm;
|
|
||||||
}
|
|
||||||
.btn2:hover{
|
|
||||||
background-color: midnightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filelink{
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
input, textarea{
|
|
||||||
color: lime;
|
|
||||||
font-family: monospace;
|
|
||||||
background-color: black;
|
|
||||||
border-color: lime;
|
|
||||||
font-size: 10mm;
|
|
||||||
border-radius: 3mm;
|
|
||||||
border-width: 1mm;
|
|
||||||
padding: 2mm;
|
|
||||||
margin-bottom: 2mm;
|
|
||||||
margin-right: 2mm;
|
|
||||||
|
|
||||||
/* make the button the whole screen width */
|
|
||||||
width: 100%;
|
|
||||||
/* make the text input fit small screens*/
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
input:hover{
|
|
||||||
background-color: midnightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flexbox{
|
|
||||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
|
||||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
|
||||||
display: -webkit-flex; /* NEW - Chrome */
|
|
||||||
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
.flexwidemember{
|
|
||||||
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
|
||||||
width: 20%; /* For old syntax, otherwise collapses. */
|
|
||||||
-webkit-flex: 1; /* Chrome */
|
|
||||||
-ms-flex: 1; /* IE 10 */
|
|
||||||
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo_splash{
|
|
||||||
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
-webkit-animation-name: logo_splash; /* Chrome, Safari, Opera */
|
|
||||||
-webkit-animation-duration: 3s; /* Chrome, Safari, Opera */
|
|
||||||
animation-name: logo_splash;
|
|
||||||
animation-duration: 3s;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
/* Chrome, Safari, Opera */
|
|
||||||
@-webkit-keyframes logo_splash {
|
|
||||||
from {opacity: 0;}
|
|
||||||
to {opacity: 1;}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Standard syntax */
|
|
||||||
@keyframes logo_splash {
|
|
||||||
from {opacity: 0;}
|
|
||||||
to {opacity: 1;}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,29 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>New webinterface for Retroshare</title>
|
|
||||||
|
|
||||||
<script src="RsXHRConnection.js"></script>
|
|
||||||
<script src="RsApi.js"></script>
|
|
||||||
|
|
||||||
<!-- it seems to work more reliable, if the jsx file is loaded before react -->
|
|
||||||
<script type="text/jsx" src="gui.jsx"></script>
|
|
||||||
|
|
||||||
<script src="react.js"></script>
|
|
||||||
<script src="JSXTransformer.js"></script>
|
|
||||||
|
|
||||||
<link href="green-black.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="initial-scale=1">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script>
|
|
||||||
document.write("<p>loading lots of stuff...</p>");
|
|
||||||
</script>
|
|
||||||
<p><noscript>The Retroshare web interface requires JavaScript. Please enable JavaScript in your browser.</noscript></p>
|
|
||||||
<!--<div id="logo_splash">
|
|
||||||
<img src="img/logo_splash.png"></img>
|
|
||||||
</div>-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
19541
libresapi/src/webfiles/react.js
vendored
19541
libresapi/src/webfiles/react.js
vendored
File diff suppressed because it is too large
Load diff
2
libresapi/src/webui-src/.gitignore
vendored
Normal file
2
libresapi/src/webui-src/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules/*
|
||||||
|
public/*
|
78
libresapi/src/webui-src/README.md
Normal file
78
libresapi/src/webui-src/README.md
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
A new approach to build a webinterface for RS
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
1. get JSON encoded data from the backend, data contains a state token
|
||||||
|
2. render data with mithril.js
|
||||||
|
3. ask the backend if the state token from step 1 expired. If yes, then start again with step 1.
|
||||||
|
|
||||||
|
Steps 1. and 3. are common for most things, only Step 2. differs. This allows to re-use code for steps 1. and 3.
|
||||||
|
|
||||||
|
BUILD / DEVELOPMENT
|
||||||
|
------------
|
||||||
|
|
||||||
|
- install tools
|
||||||
|
sudo apt-get install TODO (insert package names for nodejs, ruby, sass here)
|
||||||
|
- run this once in webui-src directory, to install more tools
|
||||||
|
npm install
|
||||||
|
- start build
|
||||||
|
npm run watch
|
||||||
|
- the build process watches files for changes, and rebuilds and reloads the page. Build output is in ./public
|
||||||
|
- use the --webinterface 9090 command line parameter to enable webui in retroshare-nogui
|
||||||
|
- set the --docroot parameter of retroshare-nogui to point to the "libresapi/src/webui-src/public" directory
|
||||||
|
(or symlink from /usr/share/RetroShare06/webui on Linux, ./webui on Windows)
|
||||||
|
- retroshare-gui does not have a --docroot parameter. Use symlinks then.
|
||||||
|
|
||||||
|
CONTRIBUTE
|
||||||
|
----------
|
||||||
|
|
||||||
|
- if you are a web developer or want to become one
|
||||||
|
get in contact!
|
||||||
|
- lots of work to do, i need you!
|
||||||
|
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
[ ] make stylesheets or find reusable sass/css components
|
||||||
|
google material design has nice rules for color, spacing and everything: https://www.google.de/design/spec/material-design/introduction.html
|
||||||
|
[ ] find icons, maybe use google material design iconfont
|
||||||
|
[X] use urls/mithril routing for the menu. urls could replace state stored in rs.content
|
||||||
|
[X] drag and drop private key upload and import
|
||||||
|
[X] link from peer location to chat (use urls and mithril routing)
|
||||||
|
[X] add/remove friend, own cert
|
||||||
|
[X] downloads, search
|
||||||
|
[ ] make reusable infinite list controller, the js part to load data from Pagination.h (tweak Pagination.h to make everything work)
|
||||||
|
should provide forward, backward and follow-list-end
|
||||||
|
[ ] backend: view/create identities
|
||||||
|
[ ] backend: chat lobby participants list
|
||||||
|
[X] chat: send_message
|
||||||
|
[ ] backend: chat typing notifications
|
||||||
|
[ ] make routines to handle retroshare links
|
||||||
|
[ ] backend: edit shared folders
|
||||||
|
[ ] backend: view shared files
|
||||||
|
[ ] redirect if a url is not usable in the current runstate (e.g. redirect from login page to home page, after login)
|
||||||
|
[X] sort friendslist
|
||||||
|
|
||||||
|
need 4 master
|
||||||
|
-------------
|
||||||
|
[X] unsubscribe lobby
|
||||||
|
[X] unread chat message counter in menu
|
||||||
|
[X] list chat-lobby participants
|
||||||
|
[X] creating app.js on build (no need for npm on regulary build)
|
||||||
|
|
||||||
|
url-handling (brainstorming)
|
||||||
|
----------------------------
|
||||||
|
* normal weblinks (bbcode? => only with gui support)
|
||||||
|
* rslinks
|
||||||
|
- files
|
||||||
|
- (chatrooms)
|
||||||
|
- forum retroshare://forum?name=Developers%27%20Discussions&id=8fd22bd8f99754461e7ba1ca8a727995
|
||||||
|
- own cert link (paste)
|
||||||
|
- cert-links
|
||||||
|
- searches
|
||||||
|
- [X] downloads pasten
|
||||||
|
- uploads?
|
||||||
|
* enter / display urls
|
||||||
|
- use urls in href like used for input (so it can be copy-link)
|
||||||
|
- handle RS-urls with javascript, other with target _blank
|
||||||
|
* smilies
|
||||||
|
* Bilder
|
||||||
|
* KEEP IT SIMPLE
|
81
libresapi/src/webui-src/app/_chat.sass
Normal file
81
libresapi/src/webui-src/app/_chat.sass
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
.chat
|
||||||
|
$color: black
|
||||||
|
$header_height: 50px
|
||||||
|
$left_width: 200px
|
||||||
|
$right_width: 200px
|
||||||
|
$input_height: 100px
|
||||||
|
padding: 15px
|
||||||
|
&.container
|
||||||
|
height: 100%
|
||||||
|
padding: 0px
|
||||||
|
position: relative
|
||||||
|
box-sizing: border-box
|
||||||
|
&.header
|
||||||
|
position: absolute
|
||||||
|
top: 0px
|
||||||
|
left: 0px
|
||||||
|
right: 0px
|
||||||
|
height: $header_height
|
||||||
|
background-color: $color
|
||||||
|
border-bottom: solid 1px gray
|
||||||
|
box-sizing: border-box
|
||||||
|
&.left
|
||||||
|
position: absolute
|
||||||
|
top: $header_height
|
||||||
|
bottom: 0px
|
||||||
|
left: 0px
|
||||||
|
width: $left_width
|
||||||
|
//border-right: solid 1px gray
|
||||||
|
box-sizing: border-box
|
||||||
|
background-color: black
|
||||||
|
&.right
|
||||||
|
position: absolute
|
||||||
|
top: $header_height
|
||||||
|
right: 0px
|
||||||
|
bottom: 0px
|
||||||
|
width: $right_width
|
||||||
|
box-sizing: border-box
|
||||||
|
//border-left: solid 1px gray
|
||||||
|
&.middle
|
||||||
|
//background-color: blue
|
||||||
|
position: absolute
|
||||||
|
top: 0px
|
||||||
|
margin-top: $header_height
|
||||||
|
left: $left_width
|
||||||
|
right: $right_width
|
||||||
|
box-sizing: border-box
|
||||||
|
padding: 0px
|
||||||
|
height: 100%
|
||||||
|
overflow-y: scroll
|
||||||
|
&.bottom
|
||||||
|
position: absolute
|
||||||
|
bottom: 0px
|
||||||
|
right: $right_width
|
||||||
|
left: $left_width
|
||||||
|
padding: 5px
|
||||||
|
&.msg
|
||||||
|
padding: 0px
|
||||||
|
$author_width: 100px
|
||||||
|
&.container
|
||||||
|
position: relative
|
||||||
|
border-bottom: solid 1px lightgray
|
||||||
|
padding: 10px
|
||||||
|
height: unset
|
||||||
|
//background-color: lime
|
||||||
|
&.from
|
||||||
|
position: absolute
|
||||||
|
width: $author_width
|
||||||
|
top: 10px
|
||||||
|
left: 0px
|
||||||
|
color: white
|
||||||
|
text-align: right
|
||||||
|
&.when
|
||||||
|
float: right
|
||||||
|
color: lightgray
|
||||||
|
margin-bottom: 10px
|
||||||
|
&.text
|
||||||
|
padding-left: $author_width
|
||||||
|
top: 0px
|
||||||
|
left: $author_width
|
||||||
|
white-space: pre-wrap
|
||||||
|
height: initial
|
48
libresapi/src/webui-src/app/_reset.scss
Normal file
48
libresapi/src/webui-src/app/_reset.scss
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
68
libresapi/src/webui-src/app/accountselect.js
Normal file
68
libresapi/src/webui-src/app/accountselect.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
function cancel(){
|
||||||
|
rs.memory("control/locations").curraccount=null;
|
||||||
|
m.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selAccount(account){
|
||||||
|
rs.memory("control/locations").curraccount=account;
|
||||||
|
m.redraw();
|
||||||
|
rs.request("control/login", {id: account.id}, function(){
|
||||||
|
console.log("login sent");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function curraccount() {
|
||||||
|
var mem;
|
||||||
|
mem = rs.memory("control/locations");
|
||||||
|
if (mem.curraccount === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return mem.curraccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
var accounts = rs("control/locations");
|
||||||
|
if(accounts === undefined || accounts == null){
|
||||||
|
return m("div", "accounts: waiting_server");
|
||||||
|
}
|
||||||
|
if (curraccount() == null) {
|
||||||
|
return m("div", [
|
||||||
|
m("h2","login:"),
|
||||||
|
m("hr"),
|
||||||
|
accounts.map(function(account){
|
||||||
|
return [
|
||||||
|
m("div.btn2", {
|
||||||
|
onclick: function(){
|
||||||
|
selAccount(account)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
account.location + " (" + account.name + ")"),
|
||||||
|
m("br")
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// rs.untoken("control/password");
|
||||||
|
return m("div", [
|
||||||
|
m("div", [
|
||||||
|
"logging in ...",
|
||||||
|
m("br"),
|
||||||
|
"(waiting for password-request)",
|
||||||
|
]),
|
||||||
|
/*
|
||||||
|
m("hr"),
|
||||||
|
m(".btn2", {
|
||||||
|
onclick: function() {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
},"Cancel " + curraccount().name + " login "),
|
||||||
|
*/
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
299
libresapi/src/webui-src/app/adddownloads.js
Normal file
299
libresapi/src/webui-src/app/adddownloads.js
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
var me = {
|
||||||
|
toParse: [], // links to parse ( = pasted content)
|
||||||
|
toConfirm: [], // links to confirm
|
||||||
|
toAdd: [], // links to add
|
||||||
|
toResult: [], // Result to show
|
||||||
|
index: 0,
|
||||||
|
view: function(){
|
||||||
|
return m("div", {
|
||||||
|
style: {
|
||||||
|
height:"100%",
|
||||||
|
boxSizing: "border-box",
|
||||||
|
paddingBottom: "130px",
|
||||||
|
}
|
||||||
|
},[
|
||||||
|
m("h2","add downloads"),
|
||||||
|
m("hr"),
|
||||||
|
this.toParse.length
|
||||||
|
? step2()
|
||||||
|
: this.toConfirm.length
|
||||||
|
? step3()
|
||||||
|
: this.toAdd.length
|
||||||
|
? step4()
|
||||||
|
: this.toResult.length
|
||||||
|
? step5()
|
||||||
|
: step1()
|
||||||
|
,
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
parseOne: function(){
|
||||||
|
if (me.index == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var startindex = me.index;
|
||||||
|
while (me.toParse.length > me.index && me.index - startindex < 10) {
|
||||||
|
var src = me.toParse[me.index].split("?",2);
|
||||||
|
console.log(src);
|
||||||
|
if (src[0] == "retroshare://file" && src.length == 2) {
|
||||||
|
var target = {action: "begin"};
|
||||||
|
var errText = "Error: link missing name and/or hash"
|
||||||
|
src[1].split("&").map(function(parm){
|
||||||
|
var pos = parm.indexOf("=");
|
||||||
|
if (pos >0){
|
||||||
|
if (parm.substr(0,pos) == "name") {
|
||||||
|
var sname=decodeURIComponent(parm.substr(pos+1))
|
||||||
|
if (sname.match("[\\\\/]")) {
|
||||||
|
errText="name contains illegal char "
|
||||||
|
+ sname.match("[\\\\/]");
|
||||||
|
} else {
|
||||||
|
target.name=sname;
|
||||||
|
}
|
||||||
|
} else if (parm.substr(0,pos) == "size") {
|
||||||
|
target.size=parseFloat(parm.substr(pos+1));
|
||||||
|
} else if (parm.substr(0,pos) == "hash") {
|
||||||
|
target.hash=parm.substr(pos+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (target['name'] && target['hash']){
|
||||||
|
me.toConfirm.push({
|
||||||
|
text: target.name,
|
||||||
|
target: target,
|
||||||
|
confirmed: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
me.toConfirm.push({
|
||||||
|
text:errText,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
me.toConfirm.push({ text: "Error: no Retroshare-file link"})
|
||||||
|
}
|
||||||
|
me.index++;
|
||||||
|
}
|
||||||
|
if (me.toParse.length > me.index) {
|
||||||
|
window.setTimeout("require(\"adddownloads\").parseOne()",1);
|
||||||
|
} else {
|
||||||
|
me.toParse = [];
|
||||||
|
console.log(me.toConfirm.length);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
|
addOne: function(){
|
||||||
|
if (me.index == null) {
|
||||||
|
cancel();
|
||||||
|
} else if (me.index >= me.toAdd.length) {
|
||||||
|
me.toResult=me.toAdd;
|
||||||
|
me.toAdd=[];
|
||||||
|
refresh();
|
||||||
|
} else {
|
||||||
|
console.log([
|
||||||
|
me.toAdd[me.index].action,
|
||||||
|
me.toAdd[me.index].name,
|
||||||
|
me.toAdd[me.index].size,
|
||||||
|
me.toAdd[me.index].hash,
|
||||||
|
]);
|
||||||
|
refresh();
|
||||||
|
rs.request("transfers/control_download", me.toAdd[me.index],
|
||||||
|
function(data,statetoken){
|
||||||
|
if (me.index != null) {
|
||||||
|
me.toAdd[me.index].ok=true;
|
||||||
|
me.index++;
|
||||||
|
me.addOne();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
onfail: function(value){
|
||||||
|
me.toAdd[me.index].ok=false;
|
||||||
|
me.toAdd[me.index].debug_msg=value;
|
||||||
|
me.index++;
|
||||||
|
me.addOne();
|
||||||
|
},
|
||||||
|
onmismatch: function(response){
|
||||||
|
me.toAdd[me.index].ok=false;
|
||||||
|
me.toAdd[me.index].debug_msg=response.debug_msg;
|
||||||
|
me.index++;
|
||||||
|
me.addOne();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
me.toAdd=[];
|
||||||
|
me.toConfirm=[];
|
||||||
|
me.toParse=[];
|
||||||
|
me.toResult=[];
|
||||||
|
me.index=null;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDownloads(){
|
||||||
|
me.toParse = document.getElementById("txtInput").value.replace("\r\n","\n").split("\n");
|
||||||
|
var pos;
|
||||||
|
while ((pos=me.toParse.indexOf(""))>=0) {
|
||||||
|
me.toParse.splice(pos,1);
|
||||||
|
}
|
||||||
|
var parser = document.createElement('a');
|
||||||
|
me.toConfirm = [];
|
||||||
|
me.index = 0;
|
||||||
|
if (me.toParse.length > me.index){
|
||||||
|
window.setTimeout("require(\"adddownloads\").parseOne()",1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDownloads(){
|
||||||
|
me.toConfirm.map(function(item){
|
||||||
|
if (item.confirmed) {
|
||||||
|
item.debug_msg="";
|
||||||
|
me.toAdd.push(item.target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
me.toConfirm=[];
|
||||||
|
if (me.toAdd.length > 0){
|
||||||
|
me.index=0;
|
||||||
|
window.setTimeout("require(\"adddownloads\").addOne()",1);
|
||||||
|
} else {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh(){
|
||||||
|
m.startComputation();
|
||||||
|
m.endComputation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelBtn(){
|
||||||
|
return m("div.btn2", {
|
||||||
|
style:{
|
||||||
|
textAlign: "center",
|
||||||
|
color: "red",
|
||||||
|
borderColor: "red",
|
||||||
|
},
|
||||||
|
onclick:cancel,
|
||||||
|
},"cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
// paste links
|
||||||
|
function step1(){
|
||||||
|
m.initControl = "txtInput";
|
||||||
|
return [
|
||||||
|
m("h3","step 1 / 5: paste retroshare-links:"),
|
||||||
|
m("textarea[id=txtInput]", {
|
||||||
|
style: {
|
||||||
|
height:"100%",
|
||||||
|
},
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
parseDownloads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("div.btn2", {
|
||||||
|
style:{
|
||||||
|
textAlign:"center",
|
||||||
|
},
|
||||||
|
onclick:parseDownloads,
|
||||||
|
},"add downloads")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsing links
|
||||||
|
function step2(){
|
||||||
|
return [
|
||||||
|
m("h3","step 2 / 5: parsing input ..."),
|
||||||
|
m("p",
|
||||||
|
"parsing " + (me.index) + " / " + me.toParse.length),
|
||||||
|
cancelBtn(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsing confirm
|
||||||
|
function step3(){
|
||||||
|
return [
|
||||||
|
m("h3","step 3 / 5: confirm-links:"),
|
||||||
|
m("ul",
|
||||||
|
me.toConfirm.map(function(item){
|
||||||
|
return m("li", {
|
||||||
|
style:{
|
||||||
|
color: item.confirmed
|
||||||
|
? "lime"
|
||||||
|
: "red"
|
||||||
|
},
|
||||||
|
}, item.text);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
m("div.btn2", {
|
||||||
|
style:{
|
||||||
|
textAlign:"center",
|
||||||
|
},
|
||||||
|
onclick:addDownloads,
|
||||||
|
},"add green listed downloads"),
|
||||||
|
cancelBtn(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// adding links
|
||||||
|
function step4(){
|
||||||
|
return [
|
||||||
|
m("h3","step 4 / 5: adding downloads:"),
|
||||||
|
m("p",
|
||||||
|
"adding " + (me.index) + " / " + me.toParse.length),
|
||||||
|
m("ul",
|
||||||
|
me.toAdd.map(function(item){
|
||||||
|
return m("li", {
|
||||||
|
style:{
|
||||||
|
color: item.ok === undefined
|
||||||
|
? "white"
|
||||||
|
: item.ok == null
|
||||||
|
? "grey"
|
||||||
|
: item.ok
|
||||||
|
? "lime"
|
||||||
|
: "red"
|
||||||
|
},
|
||||||
|
}, (item.debug_msg ? item.debug_msg + ": " : "") + item.name
|
||||||
|
+ " " + item.size + " " + item.hash);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
cancelBtn(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// show result
|
||||||
|
function step5(){
|
||||||
|
return [
|
||||||
|
m("h3","step 5 / 5: Result:"),
|
||||||
|
m("p",
|
||||||
|
"verarbeitet: " + me.toResult.length),
|
||||||
|
m("ul",
|
||||||
|
me.toResult.map(function(item){
|
||||||
|
return m("li", {
|
||||||
|
style:{
|
||||||
|
color: item.ok === undefined
|
||||||
|
? "white"
|
||||||
|
: item.ok == null
|
||||||
|
? "grey"
|
||||||
|
: item.ok
|
||||||
|
? "lime"
|
||||||
|
: "red"
|
||||||
|
},
|
||||||
|
}, (item.debug_msg ? item.debug_msg + ": " : "") + item.name);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
m("div.btn2", {
|
||||||
|
style:{
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
onclick: cancel,
|
||||||
|
},"ok"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = me;
|
54
libresapi/src/webui-src/app/addidentity.js
Normal file
54
libresapi/src/webui-src/app/addidentity.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
function createidentity(){
|
||||||
|
var data = {
|
||||||
|
name: document.getElementById("txtname").value,
|
||||||
|
pgp_linked: false,
|
||||||
|
//document.getElementById("chklinked").checked,
|
||||||
|
};
|
||||||
|
m.route("/waiting");
|
||||||
|
rs.request("identity/create_identity",data, function(){
|
||||||
|
m.route("/identities");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
m.initControl = "txtname";
|
||||||
|
return m("div",
|
||||||
|
m("h2","create identity"),
|
||||||
|
m("hr"),
|
||||||
|
m("h3","name"),
|
||||||
|
m("input", {
|
||||||
|
type: "text",
|
||||||
|
id: "txtname",
|
||||||
|
/*
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setPasswd(this.value);
|
||||||
|
sendPassword(needpasswd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}),
|
||||||
|
/*
|
||||||
|
m("b","linked with pgp-id: "),
|
||||||
|
m("input", {
|
||||||
|
type: "checkbox",
|
||||||
|
id: "chklinked",
|
||||||
|
style: {
|
||||||
|
fontweight:"bold",
|
||||||
|
width: "0%",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
*/
|
||||||
|
m("p"," "),
|
||||||
|
m("input.btn2", {
|
||||||
|
onclick: createidentity,
|
||||||
|
type: "button",
|
||||||
|
value: "create new identity",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}}
|
151
libresapi/src/webui-src/app/addpeer.js
Normal file
151
libresapi/src/webui-src/app/addpeer.js
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
var newkey = "";
|
||||||
|
var remote = "";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
var key = m.route.param("radix");
|
||||||
|
var pgp = m.route.param("pgp_id");
|
||||||
|
var peer_id =m.route.param("peer_id");
|
||||||
|
|
||||||
|
if (key===undefined && pgp === undefined) {
|
||||||
|
|
||||||
|
var owncert = rs("peers/self/certificate");
|
||||||
|
if (owncert === undefined ) {
|
||||||
|
owncert = {cert_string:"< waiting for server ... >"}
|
||||||
|
}
|
||||||
|
return m("div", [
|
||||||
|
m("h2","add new friend (Step 1/3)"),
|
||||||
|
m("p","Your own key, give it to your friends"),
|
||||||
|
m("pre", owncert.cert_string),
|
||||||
|
m("p","paste your friends key below"),
|
||||||
|
m("textarea", {
|
||||||
|
ref:"cert",
|
||||||
|
cols:"70",
|
||||||
|
rows:"16",
|
||||||
|
onchange: m.withAttr("value", function(value){newkey=value;})
|
||||||
|
}),
|
||||||
|
m("br"),
|
||||||
|
m("input.btn2",{
|
||||||
|
type:"button",
|
||||||
|
value:"read",
|
||||||
|
onclick: function (){
|
||||||
|
m.route("/addpeer",{radix:newkey})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
} else if (pgp === undefined) {
|
||||||
|
rs.request("peers/examine_cert",{cert_string:key},
|
||||||
|
function(data,responsetoken){
|
||||||
|
data.radix=key;
|
||||||
|
m.route("/addpeer", data);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return m("div", [
|
||||||
|
m("h2","add new friend (Step 2/3)"),
|
||||||
|
m("div", "analyse cert, please wait for server ...")
|
||||||
|
// { data: null, debug_msg: "failed to load certificate ", returncode: "fail" }
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
var result = {
|
||||||
|
cert_string:key ,
|
||||||
|
flags:{
|
||||||
|
allow_direct_download:false,
|
||||||
|
allow_push:false,
|
||||||
|
// set to false, until the webinterface supports managment of the blacklist/whitelist
|
||||||
|
require_whitelist: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return m("div",[
|
||||||
|
m("h2","add new friend (Step 3/3)"),
|
||||||
|
m("p","Do you want to add "
|
||||||
|
+ m.route.param("name")
|
||||||
|
+ " (" + m.route.param("location") + ")"
|
||||||
|
+ " to your friendslist?"),
|
||||||
|
m("input.checkbox[type=checkbox]", {
|
||||||
|
onchange: m.withAttr("checked", function(checked){
|
||||||
|
result.flags.allow_direct_download=checked;
|
||||||
|
})
|
||||||
|
}), "Allow direct downloads from this node",
|
||||||
|
m("br"),
|
||||||
|
m("input.checkbox[type=checkbox]", {
|
||||||
|
onchange: m.withAttr("checked", function(checked){
|
||||||
|
result.flags.allow_push=checked;
|
||||||
|
})
|
||||||
|
}), "Auto download recommended files from this node",
|
||||||
|
m("div.btn2",{
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/waiting");
|
||||||
|
rs.request("peers",result,function(data, responsetoken){
|
||||||
|
m.route("/peers");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},"add to friendslist")
|
||||||
|
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
return "peers/self/certificate"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RS.request({path: "peers/examine_cert", data: {cert_string: cert_string}}, this.examine_cert_callback);
|
||||||
|
this.setState({page:"waiting", cert_string: cert_string});
|
||||||
|
|
||||||
|
|
||||||
|
RS.request(
|
||||||
|
{
|
||||||
|
path: "peers",
|
||||||
|
data: {
|
||||||
|
cert_string: this.state.cert_string,
|
||||||
|
flags:{
|
||||||
|
allow_direct_download: this.refs.cb_direct_dl.getDOMNode().checked,
|
||||||
|
allow_push: this.refs.cb_push.getDOMNode().checked,
|
||||||
|
// set to false, until the webinterface supports managment of the blacklist/whitelist
|
||||||
|
require_whitelist: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
render: function(){
|
||||||
|
if(this.state.page === "start")
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<p>Your own key, give it to your friends</p>
|
||||||
|
<OwnCert/>
|
||||||
|
<p>paste your friends key below</p>
|
||||||
|
<textarea ref="cert" cols="70" rows="16"></textarea><br/>
|
||||||
|
<input
|
||||||
|
type="button"
|
||||||
|
value="read key"
|
||||||
|
onClick={this.add_friend_handler}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
if(this.state.page === "waiting")
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
waiting for response from server...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
if(this.state.page === "peer")
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<p>Do you want to add {this.state.data.name} to your friendslist?</p>
|
||||||
|
<input className="checkbox" type="checkbox" ref="cb_direct_dl"/> Allow direct downloads from this node<br/>
|
||||||
|
<input className="checkbox" type="checkbox" ref="cb_push"/> Auto download recommended files from this node<br/>
|
||||||
|
<div onClick={this.final_add_handler} className="btn2">add to friendslist</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
*/
|
23
libresapi/src/webui-src/app/assets/index.html
Normal file
23
libresapi/src/webui-src/app/assets/index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>rswebui6</title>
|
||||||
|
<link rel="stylesheet" href="app.css">
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="load_ui();">
|
||||||
|
<div id="main">if app does not load, enable JavaScript!</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function load_ui(){
|
||||||
|
var m = require("mithril");
|
||||||
|
var ui = require("main");
|
||||||
|
var main = document.getElementById("main");
|
||||||
|
ui.init(main);
|
||||||
|
if (m.initControl != undefined) {
|
||||||
|
m.initControl.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
298
libresapi/src/webui-src/app/chat.js
Normal file
298
libresapi/src/webui-src/app/chat.js
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
var msg = null;
|
||||||
|
var particips = [];
|
||||||
|
|
||||||
|
function dspmsg(from, when, text){
|
||||||
|
return m(".chat.msg.container",[
|
||||||
|
m(".chat.msg.from", from),
|
||||||
|
m(".chat.msg.when", when),
|
||||||
|
m(".chat.msg.text", text),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function lobbies(){
|
||||||
|
return [
|
||||||
|
rs.list("chat/lobbies",function(lobby){
|
||||||
|
return m("div.btn",{
|
||||||
|
title: "topic: " + lobby.topic + "\n"
|
||||||
|
+ "subscribed: " + lobby.subscribed,
|
||||||
|
style: {
|
||||||
|
backgroundColor: lobby.subscribed ? 'blue' : 'darkred',
|
||||||
|
},
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/chat?lobby=" + lobby.chat_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lobby.name + (
|
||||||
|
lobby.unread_msg_count > 0
|
||||||
|
? ("(" + lobby.unread_msg_count + ")")
|
||||||
|
: "")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
rs.sort.bool("is_broadcast",
|
||||||
|
rs.sort.bool("subscribed",
|
||||||
|
rs.sort("name")))
|
||||||
|
),
|
||||||
|
m("br"),
|
||||||
|
m("h3","peers:"),
|
||||||
|
rs.list("peers",function(peer){
|
||||||
|
return peer.locations.map(function(loc){
|
||||||
|
if (loc.location == "") {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
return m("div.btn",{
|
||||||
|
style: {
|
||||||
|
backgroundColor: loc.is_online ? 'blue' : 'darkred',
|
||||||
|
},
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/chat?lobby=" + loc.chat_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
peer.name + " / " + loc.location + (
|
||||||
|
loc.unread_msgs > 0
|
||||||
|
? ("(" + loc.unread_msgs + ")")
|
||||||
|
: "")
|
||||||
|
);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLobbyDetails(lobbyid){
|
||||||
|
var lobs = rs("chat/lobbies");
|
||||||
|
if (lobs === undefined) {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
for(var i = 0, l = lobs.length; i < l; ++i) {
|
||||||
|
if (lobs[i].chat_id == lobbyid) {
|
||||||
|
return lobs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var peers = rs("peers");
|
||||||
|
if (peers === undefined) {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
for(var i = 0, l = peers.length; i < l; ++i) {
|
||||||
|
var peer = peers[i];
|
||||||
|
for(var i1 = 0, l1 = peer.locations.length; i1 < l1; ++i1) {
|
||||||
|
if (peer.locations[i1].chat_id == lobbyid) {
|
||||||
|
return peer.locations[i1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendmsg(msgid){
|
||||||
|
var txtmsg = document.getElementById("txtNewMsg");
|
||||||
|
rs.request("chat/send_message", {
|
||||||
|
chat_id: msgid,
|
||||||
|
msg: txtmsg.value
|
||||||
|
});
|
||||||
|
txtmsg.value="";
|
||||||
|
}
|
||||||
|
|
||||||
|
function lobby(lobbyid){
|
||||||
|
var msgs;
|
||||||
|
var lobdt = getLobbyDetails(lobbyid);
|
||||||
|
var info = rs("chat/info/" + lobbyid);
|
||||||
|
if (lobdt == null || info === undefined) {
|
||||||
|
return m("div","waiting ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
var mem = rs.memory("chat/info/" + lobbyid);
|
||||||
|
if (mem.msg === undefined) {
|
||||||
|
mem.msg = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
var reqData = {};
|
||||||
|
if (mem.lastKnownMsg != undefined) {
|
||||||
|
reqData.begin_after = mem.lastKnownMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.request("chat/messages/" + lobbyid, reqData, function (data) {
|
||||||
|
if (data.length > 0 ) {
|
||||||
|
mem.msg = mem.msg.concat(data);
|
||||||
|
if (mem.msg.length > 0) {
|
||||||
|
mem.lastKnownMsg = mem.msg[mem.msg.length -1].id;
|
||||||
|
}
|
||||||
|
rs.request("chat/mark_chat_as_read/" + lobbyid,{}, null,
|
||||||
|
{allow: "ok|not_set"});
|
||||||
|
} else {
|
||||||
|
mem.msg = [];
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
onmismatch: function (){},
|
||||||
|
log:function(){} //no logging (pulling)
|
||||||
|
});
|
||||||
|
|
||||||
|
var intro = [
|
||||||
|
m("h2",lobdt.name),
|
||||||
|
m("p",lobdt.topic ? lobdt.topic: lobdt.location),
|
||||||
|
m("hr")
|
||||||
|
]
|
||||||
|
if (lobdt.subscribed != undefined && !lobdt.subscribed) {
|
||||||
|
return [
|
||||||
|
intro,
|
||||||
|
m("b","select subscribe identity:"),
|
||||||
|
m("p"),
|
||||||
|
rs.list("identity/own", function(item){
|
||||||
|
return m("div.btn2",{
|
||||||
|
onclick:function(){
|
||||||
|
console.log("subscribe - id:" + lobdt.id +", "
|
||||||
|
+ "gxs_id:" + item.gxs_id)
|
||||||
|
rs.request("chat/subscribe_lobby",{
|
||||||
|
id:lobdt.id,
|
||||||
|
gxs_id:item.gxs_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},"subscribe as " + item.name);
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
msg = m(".chat.bottom",[
|
||||||
|
m("div","enter new message:"),
|
||||||
|
m("input",{
|
||||||
|
id:"txtNewMsg",
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
sendmsg(lobbyid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("div.btn2", {
|
||||||
|
style: {textAlign:"center"},
|
||||||
|
onclick: function(){
|
||||||
|
sendmsg(lobbyid);
|
||||||
|
}
|
||||||
|
},"submit")
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (lobdt.subscribed != undefined
|
||||||
|
&& lobdt.subscribed
|
||||||
|
&& !lobdt.is_broadcast
|
||||||
|
) {
|
||||||
|
//set participants
|
||||||
|
particips = [
|
||||||
|
m("div.btn", {
|
||||||
|
style: {
|
||||||
|
"text-align":"center"
|
||||||
|
},
|
||||||
|
onclick: function (){
|
||||||
|
rs.request("chat/unsubscribe_lobby",{
|
||||||
|
id:lobdt.id,
|
||||||
|
});
|
||||||
|
m.route("/chat");
|
||||||
|
}
|
||||||
|
},"unsubscribe"),
|
||||||
|
m("div.btn", {
|
||||||
|
style: {
|
||||||
|
"text-align":"center"
|
||||||
|
},
|
||||||
|
onclick: function (){
|
||||||
|
rs.request("chat/clear_lobby",{
|
||||||
|
id:lobdt.id,
|
||||||
|
});
|
||||||
|
m.route("/chat?lobby=" + lobbyid);
|
||||||
|
}
|
||||||
|
},"clear"),
|
||||||
|
m("h3","participants:"),
|
||||||
|
rs.list(
|
||||||
|
"chat/lobby_participants/" + lobbyid,
|
||||||
|
function(item) {
|
||||||
|
return m("div",item.identity.name);
|
||||||
|
},
|
||||||
|
function (a,b){
|
||||||
|
return rs.stringSort(a.identity.name,b.identity.name);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
if (lobdt.subscribed != undefined
|
||||||
|
&& lobdt.subscribed
|
||||||
|
&& lobdt.is_broadcast
|
||||||
|
) {
|
||||||
|
//set participants
|
||||||
|
particips = [
|
||||||
|
m("div.btn", {
|
||||||
|
style: {
|
||||||
|
"text-align":"center"
|
||||||
|
},
|
||||||
|
onclick: function (){
|
||||||
|
rs.request("chat/clear_lobby",{
|
||||||
|
lobbyid,
|
||||||
|
});
|
||||||
|
m.route("/chat?lobby=" + lobbyid);
|
||||||
|
}
|
||||||
|
},"clear"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
intro,
|
||||||
|
mem.msg.map(function(item){
|
||||||
|
var d = new Date(new Number(item.send_time)*1000);
|
||||||
|
return dspmsg(
|
||||||
|
item.author_name,
|
||||||
|
d.toLocaleDateString() + " " + d.toLocaleTimeString(),
|
||||||
|
item.msg
|
||||||
|
);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
frame: function(content, right){
|
||||||
|
return m("div", {
|
||||||
|
style: {
|
||||||
|
"height": "100%",
|
||||||
|
"box-sizing": "border-box",
|
||||||
|
"padding-bottom": "170px",
|
||||||
|
}
|
||||||
|
},[
|
||||||
|
m(".chat.container", [
|
||||||
|
m(".chat.header", [
|
||||||
|
m(
|
||||||
|
"h2",
|
||||||
|
{style:{margin:"0px"}},
|
||||||
|
"chat"
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
m(".chat.left", [
|
||||||
|
m("div.chat.header[style=position:relative]","lobbies:"),
|
||||||
|
m("br"),
|
||||||
|
lobbies(),
|
||||||
|
]),
|
||||||
|
m(".chat.right", right),
|
||||||
|
m(".chat.middle", content),
|
||||||
|
m(".chat.clear", ""),
|
||||||
|
]),
|
||||||
|
msg != null
|
||||||
|
? msg
|
||||||
|
: [],
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
view: function(){
|
||||||
|
var lobbyid = m.route.param("lobby");
|
||||||
|
msg = null;
|
||||||
|
if (lobbyid != undefined ) {
|
||||||
|
particips = [];
|
||||||
|
return this.frame(
|
||||||
|
lobby(lobbyid),
|
||||||
|
particips
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return this.frame(
|
||||||
|
m(
|
||||||
|
"div",
|
||||||
|
{style: {margin:"10px"}},
|
||||||
|
"please select lobby"
|
||||||
|
),
|
||||||
|
m("div","")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
254
libresapi/src/webui-src/app/createlogin.js
Normal file
254
libresapi/src/webui-src/app/createlogin.js
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
var locationName = "";
|
||||||
|
var password ="";
|
||||||
|
var ssl_name = "";
|
||||||
|
var newName = "";
|
||||||
|
|
||||||
|
function listprofiles(){
|
||||||
|
var locations = rs("control/locations");
|
||||||
|
var knownProfileIds = [];
|
||||||
|
var result = [];
|
||||||
|
if(locations === undefined || locations == null){
|
||||||
|
return m("div", "profiles: waiting_server");
|
||||||
|
}
|
||||||
|
locations.map(function(location) {
|
||||||
|
if (knownProfileIds.indexOf(location.pgp_id)<0){
|
||||||
|
knownProfileIds.push(location.pgp_id);
|
||||||
|
result.push(m(
|
||||||
|
"div.btn2",{
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/createlogin",{
|
||||||
|
id: location.pgp_id,
|
||||||
|
name: location.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
location.name
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocationName(location) {
|
||||||
|
locationName = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPasswd(passwd) {
|
||||||
|
password = passwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSslName(ssl) {
|
||||||
|
ssl_name = ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNewName(name) {
|
||||||
|
newName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkpasswd(){
|
||||||
|
var status = "";
|
||||||
|
var color = "red";
|
||||||
|
var lbl = document.getElementById("lblpwdinfo");
|
||||||
|
var passwd2 = document.getElementById("txtpasswd2").value;
|
||||||
|
if (passwd2 == password && passwd2 != "") {
|
||||||
|
color = "lime";
|
||||||
|
status = "password ok";
|
||||||
|
} else if (passwd2 == "") {
|
||||||
|
color = "yellow";
|
||||||
|
status = "password required";
|
||||||
|
} else {
|
||||||
|
color = "red";
|
||||||
|
status = "passwords don't match";
|
||||||
|
}
|
||||||
|
lbl.textContent = status;
|
||||||
|
lbl.style.color=color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createLocation() {
|
||||||
|
var profile = m.route.param("id");
|
||||||
|
var profname = m.route.param("name");
|
||||||
|
|
||||||
|
var loc ={
|
||||||
|
ssl_name: document.getElementById("txtlocation").value,
|
||||||
|
pgp_password: password,
|
||||||
|
};
|
||||||
|
if (profile != undefined) {
|
||||||
|
loc.pgp_id= profile;
|
||||||
|
} else {
|
||||||
|
loc.pgp_name = newName;
|
||||||
|
};
|
||||||
|
rs.request("control/create_location",loc,function(data){
|
||||||
|
m.route("/accountselect", {});
|
||||||
|
});
|
||||||
|
m.route("/createlogin",{state:wait});
|
||||||
|
}
|
||||||
|
|
||||||
|
function certDrop(event)
|
||||||
|
{
|
||||||
|
console.log("onDrop()");
|
||||||
|
console.log(event.dataTransfer.files);
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
var reader = new FileReader();
|
||||||
|
|
||||||
|
var widget = this;
|
||||||
|
|
||||||
|
reader.onload = function(evt) {
|
||||||
|
console.log("onDrop(): file loaded");
|
||||||
|
rs.request(
|
||||||
|
"control/import_pgp",{
|
||||||
|
key_string:evt.target.result,
|
||||||
|
}, importCallback);
|
||||||
|
};
|
||||||
|
reader.readAsText(event.dataTransfer.files[0]);
|
||||||
|
m.route("/createlogin",{state:"waiting"});
|
||||||
|
}
|
||||||
|
|
||||||
|
function importCallback(resp)
|
||||||
|
{
|
||||||
|
console.log("importCallback()" + resp);
|
||||||
|
m.route("/createlogin",{
|
||||||
|
id:resp.pgp_id,
|
||||||
|
name:"",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
var profile = m.route.param("id");
|
||||||
|
var state = m.route.param("state");
|
||||||
|
var profname = m.route.param("name");
|
||||||
|
var hidden = m.route.param("hidden");
|
||||||
|
if (state == "wait"){
|
||||||
|
return m("div","waiting ...");
|
||||||
|
} if (state == "newid"){
|
||||||
|
m.initControl = "txtnewname";
|
||||||
|
return m("div",[
|
||||||
|
m("h2","create login - Step 2 / 2: create location"),
|
||||||
|
m("h3","- for new profile "),
|
||||||
|
m("hr"),
|
||||||
|
m("h2","PGP-profile name:"),
|
||||||
|
m("input",{
|
||||||
|
id: "txtnewname",
|
||||||
|
type:"text",
|
||||||
|
onchange:m.withAttr("value", setNewName),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
document.getElementById("txtpasswd").focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
m("h2","enter password:"),
|
||||||
|
m("input", {
|
||||||
|
id: "txtpasswd",
|
||||||
|
type:"password",
|
||||||
|
onchange: m.withAttr("value",setPasswd),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setPasswd(this.value);
|
||||||
|
document.getElementById("txtpasswd2").focus();
|
||||||
|
};
|
||||||
|
checkpasswd;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("h2", "re-enter password:"),
|
||||||
|
m("input", {
|
||||||
|
id: "txtpasswd2",
|
||||||
|
type:"password",
|
||||||
|
onfocus: checkpasswd,
|
||||||
|
onchange: checkpasswd,
|
||||||
|
onkeyup: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
document.getElementById("txtlocation").focus();
|
||||||
|
}
|
||||||
|
checkpasswd();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("h3",{
|
||||||
|
id: "lblpwdinfo",
|
||||||
|
style:"color:yellow",
|
||||||
|
}, "password required"),
|
||||||
|
m("h2","location name:"),
|
||||||
|
m("input",{
|
||||||
|
id: "txtlocation",
|
||||||
|
type:"text",
|
||||||
|
onchange:m.withAttr("value", setLocationName),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setSslName(this.value);
|
||||||
|
createLocation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
m("br"),
|
||||||
|
m("input",{
|
||||||
|
type: "button",
|
||||||
|
onclick: createLocation,
|
||||||
|
value: "create location",
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
} else if (profile != undefined) {
|
||||||
|
m.initControl = "txtpasswd";
|
||||||
|
return m("div",[
|
||||||
|
m("h2","create login - Step 2 / 2: create location"),
|
||||||
|
m("h3","- for " + profname + " (" +profile + ")"),
|
||||||
|
m("hr"),
|
||||||
|
m("h2","enter password:"),
|
||||||
|
m("input", {
|
||||||
|
id: "txtpasswd",
|
||||||
|
type:"password",
|
||||||
|
onchange: m.withAttr("value",setPasswd),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setPasswd(this.value);
|
||||||
|
document.getElementById("txtlocation").focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("h2","location name:"),
|
||||||
|
m("input",{
|
||||||
|
id: "txtlocation",
|
||||||
|
type:"text",
|
||||||
|
onchange:m.withAttr("value", setLocationName),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setSslName(this.value);
|
||||||
|
createLocation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
m("br"),
|
||||||
|
m("input",{
|
||||||
|
type: "button",
|
||||||
|
onclick: createLocation,
|
||||||
|
value: "create location",
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return m("div",[
|
||||||
|
m("h2","create login - Step 1 / 2: select profile(PGP-ID)"),
|
||||||
|
m("hr"),
|
||||||
|
m("div.btn2",{
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/createlogin", {state: "newid"});
|
||||||
|
},
|
||||||
|
} ,"<create new profile>"),
|
||||||
|
m("div.btn2",{
|
||||||
|
ondragover:function(event){
|
||||||
|
/*important: block default event*/
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
ondrop: certDrop,
|
||||||
|
} ,"<import profile (drag and drop a profile here)>"),
|
||||||
|
listprofiles()
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
96
libresapi/src/webui-src/app/downloads.js
Normal file
96
libresapi/src/webui-src/app/downloads.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
function makeFriendlyUnit(bytes)
|
||||||
|
{
|
||||||
|
if(bytes < 1e3)
|
||||||
|
return bytes.toFixed(1) + "B";
|
||||||
|
if(bytes < 1e6)
|
||||||
|
return (bytes/1e3).toFixed(1) + "kB";
|
||||||
|
if(bytes < 1e9)
|
||||||
|
return (bytes/1e6).toFixed(1) + "MB";
|
||||||
|
if(bytes < 1e12)
|
||||||
|
return (bytes/1e9).toFixed(1) + "GB";
|
||||||
|
return (bytes/1e12).toFixed(1) + "TB";
|
||||||
|
}
|
||||||
|
|
||||||
|
function progressBar(file){
|
||||||
|
return m("div[style=border:5px solid lime;"
|
||||||
|
+ 'border-radius:3mm;'
|
||||||
|
+ 'padding:2mm;'
|
||||||
|
+ 'height:5mm'
|
||||||
|
+ "]", [
|
||||||
|
m("div[style="
|
||||||
|
+ 'background-color:lime;'
|
||||||
|
+ 'height:100%;'
|
||||||
|
+ 'width:' + (file.transfered / file.size * 100)+'%'
|
||||||
|
+ ']'
|
||||||
|
,"")
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
function cntrlBtn(file, act) {
|
||||||
|
return(
|
||||||
|
m("div.btn",{
|
||||||
|
onclick: function(){
|
||||||
|
rs.request("transfers/control_download",{action: act, id: file.id});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
act)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
var paths = rs("transfers/downloads");
|
||||||
|
var filestreamer_url = "/fstream/";
|
||||||
|
if (paths === undefined) {
|
||||||
|
return m("div", "Downloads ... please wait ...");
|
||||||
|
}
|
||||||
|
return m("div", [
|
||||||
|
m("h2","Downloads (" + paths.length +")"),
|
||||||
|
m("div.btn2", {
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/downloads/add");
|
||||||
|
}
|
||||||
|
}, "add retrohare downloads"),
|
||||||
|
m("hr"),
|
||||||
|
m('table', [
|
||||||
|
m("tr",[
|
||||||
|
m("th","name"),
|
||||||
|
m("th","size"),
|
||||||
|
m("th","progress"),
|
||||||
|
m("th","transfer rate"),
|
||||||
|
m("th","status"),
|
||||||
|
m("th","progress"),
|
||||||
|
m("th","action")
|
||||||
|
]),
|
||||||
|
paths.map(function (file){
|
||||||
|
var ctrlBtn = m("div","");
|
||||||
|
var progress = file.transfered / file.size * 100;
|
||||||
|
return m("tr",[
|
||||||
|
m("td",[
|
||||||
|
m("a.filelink",
|
||||||
|
{
|
||||||
|
target: "blank",
|
||||||
|
href: filestreamer_url + file.hash + "/" + encodeURIComponent(file.name)
|
||||||
|
},
|
||||||
|
file.name
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
m("td", makeFriendlyUnit(file.size)),
|
||||||
|
m("td", progress.toPrecision(3) + "%"),
|
||||||
|
m("td", makeFriendlyUnit(file.transfer_rate*1e3)+"/s"),
|
||||||
|
m("td", file.download_status),
|
||||||
|
m("td", progressBar(file)),
|
||||||
|
m("td", [
|
||||||
|
cntrlBtn(file, file.download_status==="paused"?"start":"pause"),
|
||||||
|
cntrlBtn(file, "cancel")]
|
||||||
|
)
|
||||||
|
])
|
||||||
|
})
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
65
libresapi/src/webui-src/app/forums.js
Normal file
65
libresapi/src/webui-src/app/forums.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
return m("div",[
|
||||||
|
m("h2","forums"),
|
||||||
|
m("p","(work in progress, currently only listing)"),
|
||||||
|
m("hr"),
|
||||||
|
/*
|
||||||
|
m("div.btn2", {
|
||||||
|
onclick: function (){
|
||||||
|
m.route("/addforum");
|
||||||
|
}
|
||||||
|
},"< create new forum >"),
|
||||||
|
*/
|
||||||
|
m("ul",
|
||||||
|
rs.list("forums",
|
||||||
|
function(item){
|
||||||
|
return m("li",[
|
||||||
|
m("h2",item.name),
|
||||||
|
m("div",{style:{margin:"10px"}},
|
||||||
|
[
|
||||||
|
item.description != ""
|
||||||
|
? [
|
||||||
|
m("span", "Description: "
|
||||||
|
+ item.description),
|
||||||
|
m("br")]
|
||||||
|
: [],
|
||||||
|
m("span","messages visible: "
|
||||||
|
+ item.visible_msg_count),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
/*
|
||||||
|
item.subscribed
|
||||||
|
? [
|
||||||
|
m(
|
||||||
|
"span.btn2",
|
||||||
|
{style:{padding:"0px"}},
|
||||||
|
"unsubscribe"
|
||||||
|
),
|
||||||
|
" ",
|
||||||
|
m(
|
||||||
|
"span.btn2",
|
||||||
|
{style:{padding:"0px", margin:"10px"}},
|
||||||
|
"enter"
|
||||||
|
),
|
||||||
|
m("hr", {style: {color:"silver"}}),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
m(
|
||||||
|
"span.btn2",
|
||||||
|
{style:{padding:"0px", margin:"10px"}},
|
||||||
|
"subscribe"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
rs.sort("name")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}}
|
145
libresapi/src/webui-src/app/green-black.scss
Normal file
145
libresapi/src/webui-src/app/green-black.scss
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: lime;
|
||||||
|
font-family: monospace;
|
||||||
|
margin: 0em;
|
||||||
|
/*padding: 1.5em;*/
|
||||||
|
padding: 2mm;
|
||||||
|
font-size: 1.1em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay{
|
||||||
|
z-index: 10;
|
||||||
|
position: fixed;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingbox{
|
||||||
|
padding:2mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav{
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0em;
|
||||||
|
margin: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav li{
|
||||||
|
display: inline;
|
||||||
|
padding: 0.1em;
|
||||||
|
margin-right: 1em;
|
||||||
|
border-width: 0.1em;
|
||||||
|
border-color: blue;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
td{
|
||||||
|
padding: 0.3em;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0.1em;
|
||||||
|
border-color: lime;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
color: lime;
|
||||||
|
}
|
||||||
|
.menu{
|
||||||
|
border-style: solid;
|
||||||
|
border-color: lime;
|
||||||
|
border-width: 0.1em;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.0em;
|
||||||
|
}
|
||||||
|
.btn{
|
||||||
|
border-style: solid;
|
||||||
|
border-color: lime;
|
||||||
|
border-width: 0.1em;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn2, .box{
|
||||||
|
border-style: solid;
|
||||||
|
/*border-color: lime;*/
|
||||||
|
border-color: limeGreen;
|
||||||
|
/*border-width: 1px;*/
|
||||||
|
border-radius: 3mm;
|
||||||
|
padding: 2mm;
|
||||||
|
font-size: 10mm;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 2mm;
|
||||||
|
}
|
||||||
|
.btn2:hover{
|
||||||
|
background-color: midnightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filelink{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, textarea{
|
||||||
|
color: lime;
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: black;
|
||||||
|
border-color: lime;
|
||||||
|
font-size: 10mm;
|
||||||
|
border-radius: 3mm;
|
||||||
|
border-width: 1mm;
|
||||||
|
padding: 2mm;
|
||||||
|
margin-bottom: 2mm;
|
||||||
|
margin-right: 2mm;
|
||||||
|
|
||||||
|
/* make the button the whole screen width */
|
||||||
|
width: 100%;
|
||||||
|
/* make the text input fit small screens*/
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
input:hover{
|
||||||
|
background-color: midnightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexbox{
|
||||||
|
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||||
|
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
||||||
|
display: -ms-flexbox; /* TWEENER - IE 10 */
|
||||||
|
display: -webkit-flex; /* NEW - Chrome */
|
||||||
|
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexwidemember{
|
||||||
|
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||||
|
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
||||||
|
width: 20%; /* For old syntax, otherwise collapses. */
|
||||||
|
-webkit-flex: 1; /* Chrome */
|
||||||
|
-ms-flex: 1; /* IE 10 */
|
||||||
|
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo_splash{
|
||||||
|
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
-webkit-animation-name: logo_splash; /* Chrome, Safari, Opera */
|
||||||
|
-webkit-animation-duration: 3s; /* Chrome, Safari, Opera */
|
||||||
|
animation-name: logo_splash;
|
||||||
|
animation-duration: 3s;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
/* Chrome, Safari, Opera */
|
||||||
|
@-webkit-keyframes logo_splash {
|
||||||
|
from {opacity: 0;}
|
||||||
|
to {opacity: 1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard syntax */
|
||||||
|
@keyframes logo_splash {
|
||||||
|
from {opacity: 0;}
|
||||||
|
to {opacity: 1;}
|
||||||
|
}
|
6
libresapi/src/webui-src/app/home.js
Normal file
6
libresapi/src/webui-src/app/home.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
return m("div","RetroShare - WebClient - Welcome");
|
||||||
|
}
|
||||||
|
};
|
22
libresapi/src/webui-src/app/identities.js
Normal file
22
libresapi/src/webui-src/app/identities.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
return m("div",[
|
||||||
|
m("h2","identities"),
|
||||||
|
m("hr"),
|
||||||
|
m("div.btn2", {
|
||||||
|
onclick: function (){
|
||||||
|
m.route("/addidentity");
|
||||||
|
}
|
||||||
|
},"< create new identity >"),
|
||||||
|
m("ul",
|
||||||
|
rs.list("identity/own", function(item){
|
||||||
|
return m("li",[m("h2",item.name)]);
|
||||||
|
},
|
||||||
|
rs.sort("name"))
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}}
|
122
libresapi/src/webui-src/app/main.js
Normal file
122
libresapi/src/webui-src/app/main.js
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
var menu =require("menu");
|
||||||
|
var currentpasswd = null;
|
||||||
|
|
||||||
|
|
||||||
|
function setPasswd(password) {
|
||||||
|
currentpasswd = password
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPassword(data) {
|
||||||
|
console.log("sending pwd for " + data.key_name + "...");
|
||||||
|
rs.request("control/password", {password: currentpasswd}, function(){
|
||||||
|
m.redraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function Page(menu){
|
||||||
|
this.menu = menu;
|
||||||
|
this.module = (menu.module != undefined) ? menu.module : menu.name;
|
||||||
|
this.path = menu.path != undefined ? menu.path : ("/" + menu.name);
|
||||||
|
|
||||||
|
var runst = menu.runstate;
|
||||||
|
var content = require(this.module);
|
||||||
|
var mm = require("menu");
|
||||||
|
|
||||||
|
this.view = function(){
|
||||||
|
var runstate = rs("control/runstate");
|
||||||
|
var needpasswd = rs("control/password");
|
||||||
|
//console.log("runstate: " + (runstate === undefined ? runstate : runstate.runstate));
|
||||||
|
if(runstate === undefined){
|
||||||
|
return m("h2", "waiting_server ... ");
|
||||||
|
} else if (runstate.runstate == null){
|
||||||
|
// try clean reboot ...
|
||||||
|
rs.clearCache();
|
||||||
|
rs("control/runstate"); //reboot detector
|
||||||
|
console.log("i'm down");
|
||||||
|
return m("h2", "server down");
|
||||||
|
} else if (needpasswd != undefined && needpasswd.want_password === true){
|
||||||
|
m.initControl = "txtpasswd";
|
||||||
|
return m("div",[
|
||||||
|
m("h2","password required"),
|
||||||
|
m("h3",needpasswd.key_name),
|
||||||
|
m("input",{
|
||||||
|
id: "txtpasswd",
|
||||||
|
type:"password",
|
||||||
|
onchange:m.withAttr("value", setPasswd),
|
||||||
|
onkeydown: function(event){
|
||||||
|
if (event.keyCode == 13){
|
||||||
|
setPasswd(this.value);
|
||||||
|
sendPassword(needpasswd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("br"),
|
||||||
|
m("input[type=button][value=send password]",{
|
||||||
|
onclick: function(){
|
||||||
|
sendPassword(needpasswd);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
if (runstate.runstate.match("waiting_init|waiting_startup")) {
|
||||||
|
return m("h2","server starting ...")
|
||||||
|
} else if(runstate.runstate.match("waiting_account_select|running_ok.*")) {
|
||||||
|
if (runst === undefined || runstate.runstate.match(runst)) {
|
||||||
|
return m("div", {
|
||||||
|
style: {
|
||||||
|
height: "100%",
|
||||||
|
"box-sizing": "border-box",
|
||||||
|
"padding-bottom": "40px"
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
m("div", mm.view()),
|
||||||
|
m("hr"),
|
||||||
|
m("div", {
|
||||||
|
style: {
|
||||||
|
height: "100%",
|
||||||
|
"box-sizing": "border-box",
|
||||||
|
"padding-bottom":"40px"
|
||||||
|
}
|
||||||
|
}, content)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// funktion currently not available
|
||||||
|
m.route("/");
|
||||||
|
return m("div", [
|
||||||
|
m("div", mm.view()),
|
||||||
|
m("hr"),
|
||||||
|
m("div", require("home").view())
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return m("div", "unknown runstate: " + runstate.runstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init:function(main){
|
||||||
|
console.log("start init ...");
|
||||||
|
var menudef = require("menudef");
|
||||||
|
var maps = {};
|
||||||
|
var m = require("mithril");
|
||||||
|
|
||||||
|
menudef.nodes.map(function(menu){
|
||||||
|
if (menu.action === undefined) {
|
||||||
|
var p = new Page(menu)
|
||||||
|
console.log("adding route " + menu.name + " for " + p.path + " with module " + p.module);
|
||||||
|
maps[p.path] = p;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m.route.mode = "hash";
|
||||||
|
m.route(main,"/",maps);
|
||||||
|
console.log("init done.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
12
libresapi/src/webui-src/app/main.sass
Normal file
12
libresapi/src/webui-src/app/main.sass
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*@import "reset" */
|
||||||
|
|
||||||
|
html, body, #main
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
|
||||||
|
/*body */
|
||||||
|
/* font-family: "Sans-serif" */
|
||||||
|
|
||||||
|
|
||||||
|
@import "chat"
|
||||||
|
@import "green-black"
|
65
libresapi/src/webui-src/app/menu.js
Normal file
65
libresapi/src/webui-src/app/menu.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
var mnodes = require("menudef");
|
||||||
|
|
||||||
|
function goback(){
|
||||||
|
rs.content=null;
|
||||||
|
m.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildmenu(menu, tagname, runstate, ignore){
|
||||||
|
if (
|
||||||
|
(menu.runstate === undefined
|
||||||
|
|| runstate.match("^(" + menu.runstate + ")$")!=null)
|
||||||
|
&& (!menu.name.match(ignore))
|
||||||
|
&& (menu.path === undefined || menu.path.match(":")==null)
|
||||||
|
&& (menu.show === undefined || menu.show)
|
||||||
|
) {
|
||||||
|
var name = menu.name;
|
||||||
|
if (menu.counter != undefined) {
|
||||||
|
name += menu.counter();
|
||||||
|
}
|
||||||
|
if (menu.action === undefined) {
|
||||||
|
return m(tagname , {
|
||||||
|
onclick: function(){
|
||||||
|
m.route(
|
||||||
|
menu.path != undefined ? menu.path : "/" + menu.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, name);
|
||||||
|
} else {
|
||||||
|
return m(tagname, {onclick: function(){menu.action(m)}}, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
var runstate = rs("control/runstate");
|
||||||
|
if (runstate === undefined
|
||||||
|
|| runstate.runstate === undefined
|
||||||
|
|| runstate.runstate == null)
|
||||||
|
return m("div.nav","menu: waiting for server ...");
|
||||||
|
if (m.route() != "/")
|
||||||
|
return m("span",[
|
||||||
|
m("span"," | "),
|
||||||
|
mnodes.nodes.map(function(menu){
|
||||||
|
var item = buildmenu(menu,"span.menu", runstate.runstate, "-");
|
||||||
|
if (item != null){
|
||||||
|
return [
|
||||||
|
item,
|
||||||
|
m("span"," | ")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
return m("div", [
|
||||||
|
m("h2","home"),
|
||||||
|
m("hr"),
|
||||||
|
mnodes.nodes.map(function(menu){
|
||||||
|
return buildmenu(menu,"div.btn2", runstate.runstate, "home");
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
119
libresapi/src/webui-src/app/menudef.js
Normal file
119
libresapi/src/webui-src/app/menudef.js
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
var rs=require("retroshare");
|
||||||
|
module.exports = { nodes: [
|
||||||
|
{
|
||||||
|
name: "home",
|
||||||
|
path: "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "login",
|
||||||
|
module: "accountselect",
|
||||||
|
runstate: "waiting_account_select",
|
||||||
|
counter: rs.counting("control/locations"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create login",
|
||||||
|
path: "/createlogin",
|
||||||
|
module: "createlogin",
|
||||||
|
runstate: "waiting_account_select",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "peers",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
counter: rs.counting("peers", function(data){
|
||||||
|
var onlinecount = 0;
|
||||||
|
data.map(function(peer) {
|
||||||
|
var is_online = false;
|
||||||
|
peer.locations.map(function (location){
|
||||||
|
if (location.is_online) {
|
||||||
|
is_online=true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (is_online) {
|
||||||
|
onlinecount +=1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return onlinecount + "/" + data.length;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "addpeer",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "identities",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
counter: rs.counting("identity/own"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "addidentity",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"searchresult",
|
||||||
|
path: "/search/:id",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "search",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "downloads",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
counter: rs.counting("transfers/downloads")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "adddownloads",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
path: "/downloads/add",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "forums",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "chat",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
counter: rs.counting2({
|
||||||
|
"peers": function(peer) {
|
||||||
|
var sum = 0;
|
||||||
|
peer.locations.map(function (loc) {
|
||||||
|
sum += parseInt(loc.unread_msgs);
|
||||||
|
});
|
||||||
|
return sum;
|
||||||
|
},
|
||||||
|
"chat/lobbies": function(lobby) {
|
||||||
|
return lobby.unread_msg_count;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"settings",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"servicecontrol",
|
||||||
|
runstate: "running_ok.*",
|
||||||
|
path:"/settings/servicecontrol",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "shutdown",
|
||||||
|
runstate: "running_ok|waiting_account_select",
|
||||||
|
action: function(m){
|
||||||
|
rs.request("control/shutdown",null,function(){
|
||||||
|
rs("control/runstate").runstate=null;
|
||||||
|
rs.forceUpdate("control/runstate");
|
||||||
|
m.redraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "waiting",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
2141
libresapi/src/webui-src/app/mithril.js
Normal file
2141
libresapi/src/webui-src/app/mithril.js
Normal file
File diff suppressed because it is too large
Load diff
8
libresapi/src/webui-src/app/mithril.min.js
vendored
Normal file
8
libresapi/src/webui-src/app/mithril.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
libresapi/src/webui-src/app/mithril.min.js.map
Normal file
1
libresapi/src/webui-src/app/mithril.min.js.map
Normal file
File diff suppressed because one or more lines are too long
89
libresapi/src/webui-src/app/peers.js
Normal file
89
libresapi/src/webui-src/app/peers.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
var peers = rs("peers");
|
||||||
|
//console.log("peers:" + peers);
|
||||||
|
|
||||||
|
//waiting for peerlist ...
|
||||||
|
if(peers === undefined || peers == null){
|
||||||
|
return m("div",[
|
||||||
|
m("h2","peers"),
|
||||||
|
m("h3","waiting_server"),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
peers = peers.sort(rs.sort("name"));
|
||||||
|
|
||||||
|
//building peerlist (prebuild for counting)
|
||||||
|
var online = 0;
|
||||||
|
var peerlist = peers.map(function(peer){
|
||||||
|
var isonline = false;
|
||||||
|
var avatar_address ="";
|
||||||
|
|
||||||
|
//building location list (prebuild for state + icon)
|
||||||
|
var loclist = peer.locations.map(function(location){
|
||||||
|
if (location.is_online && ! isonline){
|
||||||
|
online +=1;
|
||||||
|
isonline = true;
|
||||||
|
}
|
||||||
|
if (location.avatar_address != "" && avatar_address =="") {
|
||||||
|
avatar_address=location.avatar_address;
|
||||||
|
}
|
||||||
|
return m("li",{
|
||||||
|
style:"color:" + (location.is_online ? "lime": "grey")
|
||||||
|
+ ";cursor:pointer",
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/chat?lobby=" + location.chat_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
}, location.location);
|
||||||
|
});
|
||||||
|
|
||||||
|
//return friend (peer + locations)
|
||||||
|
return m("div.flexbox[style=color:lime]",[
|
||||||
|
// avatar-icon
|
||||||
|
m("div", [
|
||||||
|
avatar_address == "" ? "" : (
|
||||||
|
m("img",{
|
||||||
|
src: rs.apiurl("peers" + avatar_address),
|
||||||
|
style:"border-radius:3mm;margin:2mm;",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
//peername + locations
|
||||||
|
m("div.flexwidemember",[
|
||||||
|
m("h1[style=margin-bottom:1mm;]",
|
||||||
|
{style:"color:" + (isonline ? "lime": "grey")} ,
|
||||||
|
peer.name
|
||||||
|
),
|
||||||
|
m("ul", loclist ),
|
||||||
|
]),
|
||||||
|
//remove-button
|
||||||
|
m("div", {
|
||||||
|
style: "color:red;" +
|
||||||
|
"font-size:1.5em;" +
|
||||||
|
"padding:0.2em;" +
|
||||||
|
"cursor:pointer",
|
||||||
|
onclick: function (){
|
||||||
|
var yes = window.confirm(
|
||||||
|
"Remove " + peer.name + " from friendslist?");
|
||||||
|
if(yes){
|
||||||
|
rs.request("peers/" + peer.pgp_id +"/delete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "X")
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// return add-peer-button + peerlist
|
||||||
|
return m("div",[
|
||||||
|
m("div.btn2",{onclick: function(){m.route("/addpeer")}},"add new friend"),
|
||||||
|
m("h2","peers (online: " + online +" / " + peers.length + "):"),
|
||||||
|
m("div", [
|
||||||
|
peerlist,
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
410
libresapi/src/webui-src/app/retroshare.js
Normal file
410
libresapi/src/webui-src/app/retroshare.js
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
/*
|
||||||
|
var rs = requires("rs");
|
||||||
|
var m = require("mithril");
|
||||||
|
|
||||||
|
function main(){
|
||||||
|
var state = rs("runstate");
|
||||||
|
if(state=== undefined){
|
||||||
|
return m("div", "waiting for server");
|
||||||
|
}
|
||||||
|
if(state === "waiting_login"){
|
||||||
|
return require("login")();
|
||||||
|
}
|
||||||
|
if(state === "running_ok"){
|
||||||
|
return require("mainwindow")();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
idea: statetokenservice could just send the date instead of the token
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
|
||||||
|
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 upload_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/upload/";
|
||||||
|
|
||||||
|
function for_key_in_obj(obj, callback){
|
||||||
|
var key;
|
||||||
|
for(key in obj){
|
||||||
|
callback(key, obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cache = {};
|
||||||
|
var last_update_ts = 0;
|
||||||
|
|
||||||
|
function check_for_changes(){
|
||||||
|
var tokens = [];
|
||||||
|
var paths_to_fetch = [];
|
||||||
|
// console.log("start-check " + Object.keys(cache));
|
||||||
|
for_key_in_obj(cache, function(path, item){
|
||||||
|
var token = item.statetoken;
|
||||||
|
if(token === undefined || token== null) {
|
||||||
|
paths_to_fetch.push(path)
|
||||||
|
} else if (tokens.indexOf(token)<0) {
|
||||||
|
tokens.push(token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log("tokens found: " + tokens);
|
||||||
|
var req = m.request({
|
||||||
|
method: "POST",
|
||||||
|
url: api_url + "statetokenservice",
|
||||||
|
background: true,
|
||||||
|
data: tokens,
|
||||||
|
});
|
||||||
|
|
||||||
|
req.then(function handle_statetoken_response(response){
|
||||||
|
// console.log("checking result " + response.data ? Object.keys(response.data) : "<null>") ;
|
||||||
|
for_key_in_obj(cache, function(path, item){
|
||||||
|
var found = false;
|
||||||
|
for(var i = 0; i < response.data.length; i++){
|
||||||
|
if(response.data[i] === item.statetoken){
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found){
|
||||||
|
paths_to_fetch.push(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log("generating Results for paths " + paths_to_fetch);
|
||||||
|
var requests = [];
|
||||||
|
paths_to_fetch.map(function request_it(path){
|
||||||
|
var req2 = m.request({
|
||||||
|
method: "GET",
|
||||||
|
url: api_url + path,
|
||||||
|
background: true,
|
||||||
|
});
|
||||||
|
req2 = req2.then(function fill_in_result(response){
|
||||||
|
cache[path].data = response.data;
|
||||||
|
cache[path].statetoken = response.statetoken;
|
||||||
|
});
|
||||||
|
requests.push(req2);
|
||||||
|
});
|
||||||
|
if(requests.length > 0){
|
||||||
|
// console.log("requesting " + requests.length + " requests");
|
||||||
|
m.sync(requests).then(function trigger_render(){
|
||||||
|
m.startComputation();
|
||||||
|
m.endComputation();
|
||||||
|
checkFocus();
|
||||||
|
setTimeout(check_for_changes, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// console.log("no requests");
|
||||||
|
setTimeout(check_for_changes, 500);
|
||||||
|
}
|
||||||
|
}, function errhandling(value){
|
||||||
|
// console.log("server disconnected " + value);
|
||||||
|
setTimeout(check_for_changes, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
check_for_changes();
|
||||||
|
|
||||||
|
var update_scheduled = false;
|
||||||
|
function schedule_request_missing(){
|
||||||
|
if(update_scheduled)
|
||||||
|
return;
|
||||||
|
update_scheduled = true;
|
||||||
|
// place update logic outside of render loop, this way we can fetch multiple things at once
|
||||||
|
// (because after the render loop everything we should fetch is in the list)
|
||||||
|
// if we fetch multiple things at once, we can delay a re-rende runtil everything is done
|
||||||
|
// so we need only one re-render for multiple updates
|
||||||
|
setTimeout(function request_missing(){
|
||||||
|
update_scheduled = false;
|
||||||
|
var requests = [];
|
||||||
|
for_key_in_obj(cache, function(path, item){
|
||||||
|
if(!item.requested){
|
||||||
|
var req = m.request({
|
||||||
|
method: "GET",
|
||||||
|
url: api_url + path,
|
||||||
|
background: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
req.then(function fill_data(response){
|
||||||
|
// TODO: add errorhandling
|
||||||
|
item.data = response.data;
|
||||||
|
item.statetoken = response.statetoken;
|
||||||
|
if (item.then != undefined && item.then != null) {
|
||||||
|
try {
|
||||||
|
item.then(response);
|
||||||
|
} catch (ex) {
|
||||||
|
if (item.errorCallback != undefined && item.errorCallback != null) {
|
||||||
|
item.errorCallback(ex);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, function errhandling(value){
|
||||||
|
if (item.errorCallback != undefined && item.errorCallback != null) {
|
||||||
|
item.errorCallback(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
requests.push(req);
|
||||||
|
}
|
||||||
|
item.requested = true;
|
||||||
|
});
|
||||||
|
m.sync(requests).then(function trigger_render(){
|
||||||
|
m.startComputation();
|
||||||
|
m.endComputation();
|
||||||
|
checkFocus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFocus(){
|
||||||
|
if (m.initControl != undefined) {
|
||||||
|
var ctrl = document.getElementById(m.initControl);
|
||||||
|
if (ctrl!= null) {
|
||||||
|
ctrl.focus();
|
||||||
|
m.initControl = undefined;
|
||||||
|
} else {
|
||||||
|
console.log("focus-control '" + m.initControl + "' not found!");
|
||||||
|
m.initControl = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// called every time, rs or rs.request failed, only response or value is set
|
||||||
|
function requestFail(path, response, value) {
|
||||||
|
rs.error = "error on " + path;
|
||||||
|
console.log("Error on " + path +
|
||||||
|
(response == null ? ", value: " + value : (", response: " +
|
||||||
|
(response.debug_msg === undefined ? response : response.debug_msg)
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rs(path, args, callback, options){
|
||||||
|
if(cache[path] === undefined){
|
||||||
|
options=optionsPrep(options,path);
|
||||||
|
var req = {
|
||||||
|
data: args,
|
||||||
|
statetoken: undefined,
|
||||||
|
requested: false,
|
||||||
|
allow: options.allow,
|
||||||
|
then: function(response){
|
||||||
|
options.log(path + ": response: " + response.returncode);
|
||||||
|
if (!this.allow.match(response.returncode)) {
|
||||||
|
options.onmismatch(response);
|
||||||
|
} else if (callback != undefined && callback != null) {
|
||||||
|
callback(response.data, response.statetoken);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errorCallback: options.onfail
|
||||||
|
};
|
||||||
|
cache[path] = req;
|
||||||
|
schedule_request_missing();
|
||||||
|
}
|
||||||
|
return cache[path].data;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = rs;
|
||||||
|
|
||||||
|
rs.for_key_in_obj = for_key_in_obj;
|
||||||
|
|
||||||
|
// single request for action
|
||||||
|
rs.request=function(path, args, callback, options){
|
||||||
|
options = optionsPrep(options, path);
|
||||||
|
var req = m.request({
|
||||||
|
method: options.method === undefined ? "POST" : options.method,
|
||||||
|
url: api_url + path,
|
||||||
|
data: args,
|
||||||
|
background: true
|
||||||
|
});
|
||||||
|
req.then(function checkResponseAndCallback(response){
|
||||||
|
options.log(path + ": response: " + response.returncode);
|
||||||
|
if (!options.allow.match(response.returncode)) {
|
||||||
|
options.onmismatch(response);
|
||||||
|
} else if (callback != undefined && callback != null) {
|
||||||
|
callback(response.data, response.statetoken);
|
||||||
|
}
|
||||||
|
}, options.onfail);
|
||||||
|
return req;
|
||||||
|
};
|
||||||
|
|
||||||
|
//set default-values for shared options in rs() and rs.request()
|
||||||
|
function optionsPrep(options, path) {
|
||||||
|
if (options === undefined) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.onfail === undefined) {
|
||||||
|
options.onfail = function errhandling(value){
|
||||||
|
requestFail(path, null, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (options.onmismatch === undefined) {
|
||||||
|
options.onmismatch = function errhandling(response){
|
||||||
|
requestFail(path, response,null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.log === undefined) {
|
||||||
|
options.log = function(message) {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.allow === undefined) {
|
||||||
|
options.allow = "ok";
|
||||||
|
};
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
// force reload for path
|
||||||
|
rs.forceUpdate = function(path, removeCache){
|
||||||
|
if (removeCache === undefined || !removeCache) {
|
||||||
|
cache[path].requested=false;
|
||||||
|
} else {
|
||||||
|
delete cache[path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// force reload for all
|
||||||
|
rs.clearCache = function(path, removeCache){
|
||||||
|
console.log("clearing Cache ...")
|
||||||
|
cache = {};
|
||||||
|
console.log("update_scheduled: " + update_scheduled);
|
||||||
|
update_scheduled = false;
|
||||||
|
check_for_changes();
|
||||||
|
console.log("Cache cleared.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// dismiss statetoken (= force reload)
|
||||||
|
rs.untoken = function(path) {
|
||||||
|
cache[path].statetoken = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//return api-path
|
||||||
|
rs.apiurl = function(path) {
|
||||||
|
if (path === undefined) {
|
||||||
|
path="";
|
||||||
|
}
|
||||||
|
if (path.length > 0 && "^\\\\|\\/".match(path)) {
|
||||||
|
path=path.substr(1);
|
||||||
|
}
|
||||||
|
return api_url + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// counting in menu
|
||||||
|
rs.counting = function(path, counterfnkt) {
|
||||||
|
return function () {
|
||||||
|
var data=rs(path);
|
||||||
|
if (data != undefined) {
|
||||||
|
if (counterfnkt === undefined) {
|
||||||
|
return " (" + data.length + ")";
|
||||||
|
}
|
||||||
|
return " (" + counterfnkt(data) + ")";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// counting in menu
|
||||||
|
rs.counting2 = function(targets) {
|
||||||
|
return function () {
|
||||||
|
var sum = 0;
|
||||||
|
for (var path in targets) {
|
||||||
|
var data=rs(path);
|
||||||
|
if (data != undefined) {
|
||||||
|
data.map(function(item){
|
||||||
|
sum += parseInt(targets[path](item));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (sum > 0) {
|
||||||
|
return " (" + sum + ")";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// listing data-elements
|
||||||
|
rs.list = function(path, buildfktn, sortfktn){
|
||||||
|
var list = rs(path);
|
||||||
|
if (list === undefined|| list == null) {
|
||||||
|
return "< waiting for server ... >"
|
||||||
|
};
|
||||||
|
if (sortfktn != undefined && sortfktn != null) {
|
||||||
|
list=list.sort(sortfktn);
|
||||||
|
}
|
||||||
|
return list.map(buildfktn);
|
||||||
|
};
|
||||||
|
|
||||||
|
//remember additional data (feature of last resort)
|
||||||
|
rs.memory = function(path, args){
|
||||||
|
var item = cache[path];
|
||||||
|
if (item === undefined) {
|
||||||
|
rs(path, args);
|
||||||
|
item = cache[path];
|
||||||
|
}
|
||||||
|
if (item.memory === undefined) {
|
||||||
|
item.memory = {};
|
||||||
|
}
|
||||||
|
return item.memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sortierfunktion für Texte von Objekten,
|
||||||
|
// falls einfache Namen nicht funktionieren
|
||||||
|
rs.stringSort = function(textA,textB, innersort, objectA, objectB){
|
||||||
|
if (textA.toLowerCase() == textB.toLowerCase()) {
|
||||||
|
if (innersort === undefined) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return innersort(objectA,objectB);
|
||||||
|
} else if (textA.toLowerCase() < textB.toLowerCase()) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//return sorting-function for string, based on property name
|
||||||
|
//using: list.sort(rs.sort("name"));
|
||||||
|
// -----
|
||||||
|
//innersort: cascading sorting - using:
|
||||||
|
//list.sort(rs.sort("type",rs.sort("name")))
|
||||||
|
rs.sort = function(name, innersort){
|
||||||
|
return function(a,b) {
|
||||||
|
return rs.stringSort(a[name],b[name],innersort,a,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return sorting-function for boolean, based on property name
|
||||||
|
rs.sort.bool = function(name, innersort){
|
||||||
|
return function(a,b){
|
||||||
|
if (a[name] == b[name]) {
|
||||||
|
if (innersort === undefined) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return innersort(a,b);
|
||||||
|
} else if (a[name]) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// searching a element in a list
|
||||||
|
// items: list to search in
|
||||||
|
// name: name of attribute to lookup
|
||||||
|
// value: attribute's value to compare
|
||||||
|
rs.find = function(items, name, value) {
|
||||||
|
if (items === undefined||items == null) {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
for(var i = 0, l = items.length; i < l; ++i) {
|
||||||
|
if (items[i][name] == value) {
|
||||||
|
return items[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
54
libresapi/src/webui-src/app/search.js
Normal file
54
libresapi/src/webui-src/app/search.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
var state = {};
|
||||||
|
var searchText = "";
|
||||||
|
|
||||||
|
function updateText(newText) {
|
||||||
|
searchText = newText;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dosearch(){
|
||||||
|
console.log("searching for: "+searchText);
|
||||||
|
rs.request(
|
||||||
|
"filesearch/create_search", {
|
||||||
|
distant: true,
|
||||||
|
search_string: searchText
|
||||||
|
},
|
||||||
|
function(resp){
|
||||||
|
m.route("/search/" + resp.search_id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
var results = rs("filesearch");
|
||||||
|
if (results === undefined||results == null) {
|
||||||
|
results = [];
|
||||||
|
};
|
||||||
|
return m("div",[
|
||||||
|
m("h2","turtle file search"),
|
||||||
|
m("div", [
|
||||||
|
m("input[type=text]", {onchange:m.withAttr("value", updateText)}),
|
||||||
|
m("input[type=button][value=search]",{onclick:dosearch})
|
||||||
|
]),
|
||||||
|
m("hr"),
|
||||||
|
m("h2","previous searches:"),
|
||||||
|
m("div", [
|
||||||
|
results.map(function(item){
|
||||||
|
var res = rs("filesearch/" + item.id,{},null,{allow:"not_set|ok"});
|
||||||
|
if (res === undefined) {
|
||||||
|
res =[];
|
||||||
|
};
|
||||||
|
return m("div.btn2",{
|
||||||
|
onclick:function(){
|
||||||
|
m.route("/search/" + item.id);
|
||||||
|
}
|
||||||
|
}, item.search_string + " (" + res.length + ")");
|
||||||
|
})
|
||||||
|
])
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
71
libresapi/src/webui-src/app/searchresult.js
Normal file
71
libresapi/src/webui-src/app/searchresult.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
var id=m.route.param("id");
|
||||||
|
var results = rs("filesearch/" + id ,{},null,{allow:"not_set|ok"});
|
||||||
|
if (results === undefined || results.length == undefined) {
|
||||||
|
results = [];
|
||||||
|
}
|
||||||
|
var searches = rs("filesearch");
|
||||||
|
var searchdetail = "<unknown>";
|
||||||
|
if (!(searches === undefined) && !(searches.length === undefined)) {
|
||||||
|
searches.forEach(function(s){
|
||||||
|
if (s.id == id) {
|
||||||
|
searchdetail = s.search_string;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var dl_ids = [];
|
||||||
|
|
||||||
|
var downloads =rs("transfers/downloads");
|
||||||
|
if (downloads !== undefined) {
|
||||||
|
downloads.map(function(item){
|
||||||
|
dl_ids.push(item.hash);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return m("div",[
|
||||||
|
m("h2","turtle file search results"),
|
||||||
|
m("h3", "searchtext: " + searchdetail + " (" + results.length + ")"),
|
||||||
|
m("hr"),
|
||||||
|
m("table", [
|
||||||
|
m("tr" ,[
|
||||||
|
m("th","name"),
|
||||||
|
m("th","size"),
|
||||||
|
m("th",""),
|
||||||
|
]),
|
||||||
|
results.map(function(file){
|
||||||
|
if (dl_ids.indexOf(file.hash)>=0) {
|
||||||
|
file.state="in download queue"
|
||||||
|
}
|
||||||
|
return m("tr",[
|
||||||
|
m("th",file.name),
|
||||||
|
m("th",file.size),
|
||||||
|
m("th",[
|
||||||
|
file.state === undefined
|
||||||
|
? m("span.btn", {
|
||||||
|
onclick:function(){
|
||||||
|
rs.request("transfers/control_download", {
|
||||||
|
action: "begin",
|
||||||
|
name: file.name,
|
||||||
|
size: file.size,
|
||||||
|
hash: file.hash,
|
||||||
|
}, function(){
|
||||||
|
result="added";
|
||||||
|
});
|
||||||
|
m.startComputation();
|
||||||
|
m.endComputation();
|
||||||
|
}
|
||||||
|
}, "download")
|
||||||
|
: file.state
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
])
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
264
libresapi/src/webui-src/app/servicecontrol.js
Normal file
264
libresapi/src/webui-src/app/servicecontrol.js
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
function setOption(id,value) {
|
||||||
|
return function(){
|
||||||
|
rs.request("servicecontrol", {
|
||||||
|
service_id: id,
|
||||||
|
default_allowed: value,
|
||||||
|
});
|
||||||
|
rs.forceUpdate("servicecontrol", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUserOption(serviceid, userid, value) {
|
||||||
|
return function(){
|
||||||
|
rs.request("servicecontrol/user", {
|
||||||
|
service_id: serviceid,
|
||||||
|
peer_id: userid,
|
||||||
|
enabled: value
|
||||||
|
}, function(){
|
||||||
|
rs.forceUpdate("servicecontrol", true)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSwitch(isOn, width) {
|
||||||
|
if (width === undefined) {
|
||||||
|
width = "2.1em";
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
m("div.menu", {
|
||||||
|
style: {
|
||||||
|
float:"left",
|
||||||
|
width: width,
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#303030",
|
||||||
|
borderColor: isOn
|
||||||
|
? "lime"
|
||||||
|
: "red",
|
||||||
|
backgroundColor: !isOn
|
||||||
|
? "black"
|
||||||
|
: "lime",
|
||||||
|
}
|
||||||
|
}, "ON"),
|
||||||
|
m("div.menu",{
|
||||||
|
style: {
|
||||||
|
float:"left",
|
||||||
|
width: width,
|
||||||
|
textAlign: "center",
|
||||||
|
marginRight:"5px",
|
||||||
|
color: "#303030",
|
||||||
|
borderColor: isOn
|
||||||
|
? "lime"
|
||||||
|
: "red",
|
||||||
|
backgroundColor: isOn
|
||||||
|
? "black"
|
||||||
|
: "red",
|
||||||
|
}
|
||||||
|
}, "OFF"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function breadcrums(name, parts){
|
||||||
|
var result = [];
|
||||||
|
rs.for_key_in_obj(parts, function(partname,item){
|
||||||
|
result.push(
|
||||||
|
m("span.btn",{
|
||||||
|
onclick: function(){
|
||||||
|
m.route(item)
|
||||||
|
}
|
||||||
|
},partname)
|
||||||
|
);
|
||||||
|
result.push(" / ");
|
||||||
|
});
|
||||||
|
result.push(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function serviceView(serviceid) {
|
||||||
|
var service, liste;
|
||||||
|
service = rs.find(rs("servicecontrol"),"service_id",serviceid);
|
||||||
|
if (service == null) {
|
||||||
|
return m("h3","<please wait ... >");
|
||||||
|
}
|
||||||
|
liste = service.default_allowed
|
||||||
|
? service.peers_denied
|
||||||
|
: service.peers_allowed;
|
||||||
|
return m("div", [
|
||||||
|
m("h2", breadcrums(service.service_name, {
|
||||||
|
settings:"/settings",
|
||||||
|
rights: "/settings/servicecontrol",
|
||||||
|
})),
|
||||||
|
m("hr"),
|
||||||
|
m("h2",{
|
||||||
|
style:{
|
||||||
|
float:"left",
|
||||||
|
}
|
||||||
|
},[
|
||||||
|
m("div",{
|
||||||
|
style:{
|
||||||
|
float:"left",
|
||||||
|
}
|
||||||
|
},"user rights for: " + service.service_name + ", default: "),
|
||||||
|
m("div", {
|
||||||
|
onclick: setOption(
|
||||||
|
serviceid,
|
||||||
|
!service.default_allowed
|
||||||
|
),
|
||||||
|
style: {
|
||||||
|
float:"left",
|
||||||
|
marginLeft: "0.4em",
|
||||||
|
marginRight: "0.4em",
|
||||||
|
}
|
||||||
|
},createSwitch(service.default_allowed)),
|
||||||
|
]),
|
||||||
|
m("div", {
|
||||||
|
style: {
|
||||||
|
clear:"left",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
m("ul", rs.list("peers",function(peer){
|
||||||
|
var locs;
|
||||||
|
locs = peer.locations;
|
||||||
|
locs.sort(rs.sort("location"));
|
||||||
|
return peer.locations.map(function(location){
|
||||||
|
var isExcept, isOn;
|
||||||
|
isExcept = liste != null
|
||||||
|
&& liste.indexOf(location.peer_id)>=0;
|
||||||
|
isOn = service.default_allowed ? !isExcept: isExcept;
|
||||||
|
return m("li", {
|
||||||
|
style: {
|
||||||
|
margin: "5px",
|
||||||
|
color: isOn ? "lime" :"red",
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
m("div"),
|
||||||
|
m("div", {
|
||||||
|
onclick: setUserOption(
|
||||||
|
serviceid,
|
||||||
|
location.peer_id,
|
||||||
|
!isOn
|
||||||
|
),
|
||||||
|
style: {
|
||||||
|
float:"left",
|
||||||
|
},
|
||||||
|
},createSwitch(isOn)),
|
||||||
|
m("div",
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
//color: "lime",
|
||||||
|
float:"left",
|
||||||
|
marginLeft: "5px",
|
||||||
|
marginRight: "5px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
peer.name + (location.location
|
||||||
|
? " (" + location.location + ")"
|
||||||
|
: "")
|
||||||
|
),
|
||||||
|
m("div", {
|
||||||
|
style: {
|
||||||
|
clear: "left"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
}, rs.sort("name")))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
if (m.route.param("service_id")) {
|
||||||
|
return serviceView(m.route.param("service_id"));
|
||||||
|
}
|
||||||
|
return m("div", [
|
||||||
|
m("h2", breadcrums("rights", {
|
||||||
|
settings:"/settings",
|
||||||
|
})),
|
||||||
|
m("hr"),
|
||||||
|
m("ul", rs.list("servicecontrol", function(item){
|
||||||
|
return m("li", {
|
||||||
|
style: {
|
||||||
|
margin: "5px",
|
||||||
|
color: item.default_allowed ? "lime" :"red",
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
m("div"),
|
||||||
|
m("div", {
|
||||||
|
onclick: setOption(
|
||||||
|
item.service_id,
|
||||||
|
!item.default_allowed
|
||||||
|
),
|
||||||
|
style: {
|
||||||
|
float:"left",
|
||||||
|
}
|
||||||
|
},createSwitch(item.default_allowed)),
|
||||||
|
m("div.menu",
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
// color: "lime",
|
||||||
|
borderColor: item.default_allowed
|
||||||
|
? "lime"
|
||||||
|
: "red",
|
||||||
|
float: "left",
|
||||||
|
marginLeft: "5px",
|
||||||
|
marginRight: "5px",
|
||||||
|
paddingLeft: "2px",
|
||||||
|
paddingRight: "2px",
|
||||||
|
},
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/settings/servicecontrol/", {
|
||||||
|
service_id: item.service_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, "more"
|
||||||
|
),
|
||||||
|
m("div",
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
// color: "lime",
|
||||||
|
float:"left",
|
||||||
|
marginLeft: "5px",
|
||||||
|
marginRight: "5px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
item.service_name
|
||||||
|
),
|
||||||
|
m("div",
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
color: "lime",
|
||||||
|
float:"left",
|
||||||
|
marginLeft: "5px",
|
||||||
|
marginRight: "5px",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(
|
||||||
|
item.default_allowed
|
||||||
|
? ( item.peers_denied != null
|
||||||
|
? "(" + item.peers_denied.length + " denied)"
|
||||||
|
: "")
|
||||||
|
: ( item.peers_allowed != null
|
||||||
|
? "(" + item.peers_allowed.length + " allowed)"
|
||||||
|
: "")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
m("div", {
|
||||||
|
style: {
|
||||||
|
clear: "left"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
libresapi/src/webui-src/app/settings.js
Normal file
19
libresapi/src/webui-src/app/settings.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
view: function(){
|
||||||
|
return m("div", [
|
||||||
|
m("h2","settings"),
|
||||||
|
m("hr"),
|
||||||
|
m("div.btn2",{
|
||||||
|
onclick: function(){
|
||||||
|
m.route("/settings/servicecontrol");
|
||||||
|
},
|
||||||
|
}, "rights")
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
8
libresapi/src/webui-src/app/waiting.js
Normal file
8
libresapi/src/webui-src/app/waiting.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var m = require("mithril");
|
||||||
|
var rs = require("retroshare");
|
||||||
|
|
||||||
|
module.exports = {view: function(){
|
||||||
|
return m("h2","please wait ...");
|
||||||
|
}}
|
12
libresapi/src/webui-src/brunch-config.js
Normal file
12
libresapi/src/webui-src/brunch-config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
module.exports = {
|
||||||
|
config:{
|
||||||
|
files:{
|
||||||
|
javascripts:{
|
||||||
|
joinTo: 'app.js'
|
||||||
|
},
|
||||||
|
stylesheets:{
|
||||||
|
joinTo: 'app.css'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
41
libresapi/src/webui-src/make-src/build.bat
Normal file
41
libresapi/src/webui-src/make-src/build.bat
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
@echo off
|
||||||
|
REM create webfiles from sources at compile time (works without npm/node.js)
|
||||||
|
|
||||||
|
set publicdest=%1\webui
|
||||||
|
set src=%1\webui-src
|
||||||
|
|
||||||
|
if "%1" == "" set publicdest=..\..\webui&&set src=..
|
||||||
|
|
||||||
|
if exist "%publicdest%" echo remove existing %publicdest%&&rd %publicdest% /S /Q
|
||||||
|
|
||||||
|
echo mkdir %publicdest%
|
||||||
|
md %publicdest%
|
||||||
|
|
||||||
|
echo building app.js
|
||||||
|
echo - copy template.js ...
|
||||||
|
copy %src%\make-src\template.js %publicdest%\app.js
|
||||||
|
|
||||||
|
for %%F in (%src%\app\*.js) DO (set "fname=%%~nF" && CALL :addfile)
|
||||||
|
|
||||||
|
echo building app.css
|
||||||
|
type %src%\app\green-black.scss >> %publicdest%\app.css
|
||||||
|
type %src%\make-src\main.css >> %publicdest%\app.css
|
||||||
|
type %src%\make-src\chat.css >> %publicdest%\app.css
|
||||||
|
|
||||||
|
echo copy index.html
|
||||||
|
copy %src%\app\assets\index.html %publicdest%\index.html
|
||||||
|
|
||||||
|
echo build.bat complete
|
||||||
|
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:addfile
|
||||||
|
echo - adding %fname% ...
|
||||||
|
echo require.register("%fname%", function(exports, require, module) { >> %publicdest%\app.js
|
||||||
|
echo %src%\app\%fname%.js
|
||||||
|
type %src%\app\%fname%.js >> %publicdest%\app.js
|
||||||
|
echo. >> %publicdest%\app.js
|
||||||
|
echo }); >> %publicdest%\app.js
|
||||||
|
|
||||||
|
|
||||||
|
:EOF
|
62
libresapi/src/webui-src/make-src/build.sh
Executable file
62
libresapi/src/webui-src/make-src/build.sh
Executable file
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# create webfiles from sources at compile time (works without npm/node.js)
|
||||||
|
|
||||||
|
if [ "$1" = "" ]; then
|
||||||
|
publicdest=../../webui
|
||||||
|
src=..
|
||||||
|
else
|
||||||
|
publicdest=$1/webui
|
||||||
|
src=$1/webui-src
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" = "" ]; then
|
||||||
|
|
||||||
|
if [ -d "$publicdest" ]; then
|
||||||
|
echo remove existing $publicdest
|
||||||
|
rm $publicdest -R
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$publicdest" ]; then
|
||||||
|
echo mkdir $publicdest
|
||||||
|
mkdir $publicdest
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" = "" ]||[ "$2" = "app.js" ]; then
|
||||||
|
echo building app.js
|
||||||
|
echo - copy template.js ...
|
||||||
|
cp $src/make-src/template.js $publicdest/app.js
|
||||||
|
|
||||||
|
for filename in $src/app/*.js; do
|
||||||
|
fname=$(basename "$filename")
|
||||||
|
fname="${fname%.*}"
|
||||||
|
echo - adding $fname ...
|
||||||
|
echo require.register\(\"$fname\", function\(exports, require, module\) { >> $publicdest/app.js
|
||||||
|
cat $filename >> $publicdest/app.js
|
||||||
|
echo >> $publicdest/app.js
|
||||||
|
echo }\)\; >> $publicdest/app.js
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" = "" ]||[ "$2" = "app.css" ]; then
|
||||||
|
echo building app.css
|
||||||
|
cat $src/app/green-black.scss >> $publicdest/app.css
|
||||||
|
cat $src/make-src/main.css >> $publicdest/app.css
|
||||||
|
cat $src/make-src/chat.css >> $publicdest/app.css
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" = "" ]||[ "$2" = "index.html" ]; then
|
||||||
|
echo copy index.html
|
||||||
|
cp $src/app/assets/index.html $publicdest/index.html
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" != "" ]&&[ "$3" != "" ]; then
|
||||||
|
if [ ! -d "$3/webui" ]; then
|
||||||
|
echo mkdir $3/webui
|
||||||
|
mkdir $3/webui
|
||||||
|
fi
|
||||||
|
echo copy $2 nach $3/webui/$2
|
||||||
|
cp $publicdest/$2 $3/webui/$2
|
||||||
|
fi
|
||||||
|
echo build.sh complete
|
72
libresapi/src/webui-src/make-src/chat.css
Normal file
72
libresapi/src/webui-src/make-src/chat.css
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
.chat {
|
||||||
|
padding: 15px; }
|
||||||
|
.chat.container {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.chat.header {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: black;
|
||||||
|
border-bottom: solid 1px gray;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.chat.left {
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 200px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: black; }
|
||||||
|
.chat.right {
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 200px;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.chat.middle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
margin-top: 50px;
|
||||||
|
left: 200px;
|
||||||
|
right: 200px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0px;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll; }
|
||||||
|
.chat.bottom {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 200px;
|
||||||
|
left: 200px;
|
||||||
|
padding: 5px; }
|
||||||
|
.chat.msg {
|
||||||
|
padding: 0px; }
|
||||||
|
.chat.msg.container {
|
||||||
|
position: relative;
|
||||||
|
border-bottom: solid 1px lightgray;
|
||||||
|
padding: 10px;
|
||||||
|
height: unset; }
|
||||||
|
.chat.msg.from {
|
||||||
|
position: absolute;
|
||||||
|
width: 100px;
|
||||||
|
top: 10px;
|
||||||
|
left: 0px;
|
||||||
|
color: white;
|
||||||
|
text-align: right; }
|
||||||
|
.chat.msg.when {
|
||||||
|
float: right;
|
||||||
|
color: lightgray;
|
||||||
|
margin-bottom: 10px; }
|
||||||
|
.chat.msg.text {
|
||||||
|
padding-left: 100px;
|
||||||
|
top: 0px;
|
||||||
|
left: 100px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
height: initial; }
|
||||||
|
|
15
libresapi/src/webui-src/make-src/init.bat
Normal file
15
libresapi/src/webui-src/make-src/init.bat
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
@echo off
|
||||||
|
REM create dummy webfiles at qmake run
|
||||||
|
|
||||||
|
set publicdest=%1\webui
|
||||||
|
if "%1" == "" set publicdest=..\..\webui
|
||||||
|
|
||||||
|
if exist %publicdest% echo remove %publicdest%&&rd %publicdest% /S /Q
|
||||||
|
|
||||||
|
echo create %publicdest%
|
||||||
|
md %publicdest%
|
||||||
|
|
||||||
|
echo create %publicdest%\app.js, %publicdest%\app.css, %publicdest%\index.html
|
||||||
|
echo. > %publicdest%\app.js
|
||||||
|
echo. > %publicdest%\app.css
|
||||||
|
echo. > %publicdest%\index.html
|
22
libresapi/src/webui-src/make-src/init.sh
Executable file
22
libresapi/src/webui-src/make-src/init.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# create dummy webfiles at qmake run
|
||||||
|
|
||||||
|
if [ "$1" = "" ];then
|
||||||
|
publicdest=../../webui
|
||||||
|
else
|
||||||
|
publicdest=$1/webui
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$publicdest" ]; then
|
||||||
|
echo remove $publicdest
|
||||||
|
rm $publicdest -R
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo create $publicdest
|
||||||
|
mkdir $publicdest
|
||||||
|
|
||||||
|
echo touch $publicdest/app.js, $publicdest/app.css, $publicdest/index.html
|
||||||
|
touch $publicdest/app.js -d 1970-01-01
|
||||||
|
touch $publicdest/app.css -d 1970-01-01
|
||||||
|
touch $publicdest/index.html -d 1970-01-01
|
2
libresapi/src/webui-src/make-src/main.css
Normal file
2
libresapi/src/webui-src/make-src/main.css
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
html, body, #main {
|
||||||
|
height: 100%; }
|
7
libresapi/src/webui-src/make-src/readme.md
Normal file
7
libresapi/src/webui-src/make-src/readme.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
this folder contains files needed to create webfiles at compile-time and qmake
|
||||||
|
|
||||||
|
* init.sh creates dummy files at qmake
|
||||||
|
* build.sh creates files at compile time
|
||||||
|
* chat.css compiled version of _chat.sass (.sass should replaced by .scss)
|
||||||
|
* main.css simple template extracted from main.sass
|
||||||
|
* template.js start of compiled app.js, containing additional created content
|
112
libresapi/src/webui-src/make-src/template.js
Normal file
112
libresapi/src/webui-src/make-src/template.js
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var globals = typeof window === 'undefined' ? global : window;
|
||||||
|
if (typeof globals.require === 'function') return;
|
||||||
|
|
||||||
|
var modules = {};
|
||||||
|
var cache = {};
|
||||||
|
var aliases = {};
|
||||||
|
var has = ({}).hasOwnProperty;
|
||||||
|
|
||||||
|
var endsWith = function(str, suffix) {
|
||||||
|
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _cmp = 'components/';
|
||||||
|
var unalias = function(alias, loaderPath) {
|
||||||
|
var start = 0;
|
||||||
|
if (loaderPath) {
|
||||||
|
if (loaderPath.indexOf(_cmp) === 0) {
|
||||||
|
start = _cmp.length;
|
||||||
|
}
|
||||||
|
if (loaderPath.indexOf('/', start) > 0) {
|
||||||
|
loaderPath = loaderPath.substring(start, loaderPath.indexOf('/', start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var result = aliases[alias + '/index.js'] || aliases[loaderPath + '/deps/' + alias + '/index.js'];
|
||||||
|
if (result) {
|
||||||
|
return _cmp + result.substring(0, result.length - '.js'.length);
|
||||||
|
}
|
||||||
|
return alias;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _reg = /^\.\.?(\/|$)/;
|
||||||
|
var expand = function(root, name) {
|
||||||
|
var results = [], part;
|
||||||
|
var parts = (_reg.test(name) ? root + '/' + name : name).split('/');
|
||||||
|
for (var i = 0, length = parts.length; i < length; i++) {
|
||||||
|
part = parts[i];
|
||||||
|
if (part === '..') {
|
||||||
|
results.pop();
|
||||||
|
} else if (part !== '.' && part !== '') {
|
||||||
|
results.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.join('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
var dirname = function(path) {
|
||||||
|
return path.split('/').slice(0, -1).join('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
var localRequire = function(path) {
|
||||||
|
return function expanded(name) {
|
||||||
|
var absolute = expand(dirname(path), name);
|
||||||
|
return globals.require(absolute, path);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var initModule = function(name, definition) {
|
||||||
|
var module = {id: name, exports: {}};
|
||||||
|
cache[name] = module;
|
||||||
|
definition(module.exports, localRequire(name), module);
|
||||||
|
return module.exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
var require = function(name, loaderPath) {
|
||||||
|
var path = expand(name, '.');
|
||||||
|
if (loaderPath == null) loaderPath = '/';
|
||||||
|
path = unalias(name, loaderPath);
|
||||||
|
|
||||||
|
if (has.call(cache, path)) return cache[path].exports;
|
||||||
|
if (has.call(modules, path)) return initModule(path, modules[path]);
|
||||||
|
|
||||||
|
var dirIndex = expand(path, './index');
|
||||||
|
if (has.call(cache, dirIndex)) return cache[dirIndex].exports;
|
||||||
|
if (has.call(modules, dirIndex)) return initModule(dirIndex, modules[dirIndex]);
|
||||||
|
|
||||||
|
throw new Error('Cannot find module "' + name + '" from '+ '"' + loaderPath + '"');
|
||||||
|
};
|
||||||
|
|
||||||
|
require.alias = function(from, to) {
|
||||||
|
aliases[to] = from;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.register = require.define = function(bundle, fn) {
|
||||||
|
if (typeof bundle === 'object') {
|
||||||
|
for (var key in bundle) {
|
||||||
|
if (has.call(bundle, key)) {
|
||||||
|
modules[key] = bundle[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modules[bundle] = fn;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
require.list = function() {
|
||||||
|
var result = [];
|
||||||
|
for (var item in modules) {
|
||||||
|
if (has.call(modules, item)) {
|
||||||
|
result.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.brunch = true;
|
||||||
|
require._cache = cache;
|
||||||
|
globals.require = require;
|
||||||
|
})();
|
||||||
|
|
11
libresapi/src/webui-src/package.json
Normal file
11
libresapi/src/webui-src/package.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "webui_neu",
|
||||||
|
"scripts": {
|
||||||
|
"watch": "brunch watch --server"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"auto-reload-brunch": "^1.8.0",
|
||||||
|
"brunch": "^1.8.5",
|
||||||
|
"sass-brunch": "^1.9.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
REACT_VERSION = 0.13.1
|
|
||||||
|
|
||||||
DISTDIR = ../webfiles
|
|
||||||
JSEXTLIBS = $(DISTDIR)/react.js $(DISTDIR)/JSXTransformer.js
|
|
||||||
JSLIBS = RsXHRConnection.js RsApi.js
|
|
||||||
HTML = index.html
|
|
||||||
JSGUI = gui.jsx
|
|
||||||
CSS = green-black.css
|
|
||||||
|
|
||||||
all: $(DISTDIR) $(JSEXTLIBS) $(addprefix $(DISTDIR)/, $(JSLIBS)) $(addprefix $(DISTDIR)/, $(HTML)) $(addprefix $(DISTDIR)/, $(JSGUI)) $(addprefix $(DISTDIR)/, $(CSS))
|
|
||||||
.PHONY: all
|
|
||||||
|
|
||||||
$(DISTDIR)/livereload: $(DISTDIR) $(JSEXTLIBS) $(addprefix $(DISTDIR)/, $(JSLIBS)) $(addprefix $(DISTDIR)/, $(HTML)) $(addprefix $(DISTDIR)/, $(JSGUI)) $(addprefix $(DISTDIR)/, $(CSS))
|
|
||||||
wget -qO- http://localhost:9090/api/v2/livereload/trigger
|
|
||||||
touch $(DISTDIR)/livereload
|
|
||||||
|
|
||||||
$(DISTDIR)/react.js:
|
|
||||||
cd $(DISTDIR) && wget --no-check-certificate --output-document react.js http://fb.me/react-$(REACT_VERSION).js
|
|
||||||
|
|
||||||
$(DISTDIR)/JSXTransformer.js:
|
|
||||||
cd $(DISTDIR) && wget --no-check-certificate --output-document JSXTransformer.js http://fb.me/JSXTransformer-$(REACT_VERSION).js
|
|
||||||
|
|
||||||
$(addprefix $(DISTDIR)/, $(JSLIBS)): $(DISTDIR)/%: %
|
|
||||||
cp $< $@
|
|
||||||
|
|
||||||
$(addprefix $(DISTDIR)/, $(HTML)): $(DISTDIR)/%: %
|
|
||||||
cp $< $@
|
|
||||||
|
|
||||||
$(addprefix $(DISTDIR)/, $(JSGUI)): $(DISTDIR)/%: %
|
|
||||||
cp $< $@
|
|
||||||
|
|
||||||
$(addprefix $(DISTDIR)/, $(CSS)): $(DISTDIR)/%: %
|
|
||||||
cp $< $@
|
|
||||||
|
|
||||||
$(DISTDIR):
|
|
||||||
mkdir $(DISTDIR)
|
|
|
@ -1,142 +0,0 @@
|
||||||
var TypesMod = require("./Types.js");
|
|
||||||
var Type = TypesMod.Type;
|
|
||||||
var string = TypesMod.string;
|
|
||||||
var bool = TypesMod.bool;
|
|
||||||
var any = TypesMod.any;
|
|
||||||
|
|
||||||
if(require.main === module)
|
|
||||||
{
|
|
||||||
var RsNodeHttpConnection = require("./RsNodeHttpConnection.js");
|
|
||||||
debugger;
|
|
||||||
var connection = new RsNodeHttpConnection();
|
|
||||||
var RsApi = require("./RsApi.js");
|
|
||||||
var RS = new RsApi(connection);
|
|
||||||
|
|
||||||
var tests = [];
|
|
||||||
var doc = {
|
|
||||||
counter: 0,
|
|
||||||
toc: [],
|
|
||||||
content: [],
|
|
||||||
header: function(h){
|
|
||||||
this.toc.push(h);
|
|
||||||
this.content.push("<a name=\""+this.counter+"\"><h1>"+h+"</h1></a>");
|
|
||||||
this.counter += 1;
|
|
||||||
},
|
|
||||||
paragraph: function(p){
|
|
||||||
this.content.push("<p>"+p+"</p>");
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
PeersTest(tests, doc);
|
|
||||||
|
|
||||||
var docstr = "<!DOCTYPE html><html><body>";
|
|
||||||
docstr += "<h1>Table of Contents</h1>";
|
|
||||||
docstr += "<ul>";
|
|
||||||
for(var i in doc.toc)
|
|
||||||
{
|
|
||||||
docstr += "<li><a href=\"#"+i+"\">"+doc.toc[i]+"</a></li>";
|
|
||||||
}
|
|
||||||
docstr += "</ul>";
|
|
||||||
for(var i in doc.content)
|
|
||||||
{
|
|
||||||
docstr += doc.content[i];
|
|
||||||
}
|
|
||||||
docstr += "</body></html>";
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
fs.writeFile("dist/api_documentation.html", docstr);
|
|
||||||
|
|
||||||
tests.map(function(test){
|
|
||||||
test(RS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function PeersTest(tests, doc)
|
|
||||||
{
|
|
||||||
// compound types
|
|
||||||
var location = new Type("location",
|
|
||||||
{
|
|
||||||
avatar_address: string,
|
|
||||||
groups: any,
|
|
||||||
is_online: bool,
|
|
||||||
location: string,
|
|
||||||
peer_id: any,
|
|
||||||
});
|
|
||||||
var peer_info = new Type("peer_info",
|
|
||||||
{
|
|
||||||
name: string,
|
|
||||||
pgp_id: any,
|
|
||||||
locations: [location],
|
|
||||||
});
|
|
||||||
var peers_list = new Type("peers_list",[peer_info]);
|
|
||||||
|
|
||||||
doc.header("peers");
|
|
||||||
doc.paragraph("<pre>"+graphToText(peers_list)+"</pre>");
|
|
||||||
|
|
||||||
tests.push(function(RS){
|
|
||||||
console.log("testing peers module...");
|
|
||||||
console.log("expected schema is:")
|
|
||||||
console.log(graphToText(peers_list));
|
|
||||||
RS.request({path: "peers"}, function(resp){
|
|
||||||
//console.log("got response:"+JSON.stringify(resp));
|
|
||||||
var ok = peers_list.check(function(str){console.log(str);}, resp.data, [])
|
|
||||||
if(ok)
|
|
||||||
console.log("success");
|
|
||||||
else
|
|
||||||
console.log("fail");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function graphToText(top_node)
|
|
||||||
{
|
|
||||||
//var dbg = function(str){console.log(str);};
|
|
||||||
var dbg = function(str){};
|
|
||||||
|
|
||||||
dbg("called graphToText with " + top_node);
|
|
||||||
|
|
||||||
var res = "";
|
|
||||||
|
|
||||||
_visit(top_node.getObj(), 0);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
function _indent(count)
|
|
||||||
{
|
|
||||||
var str = "";
|
|
||||||
for(var i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
str = str + " ";
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
function _visit(node, indent)
|
|
||||||
{
|
|
||||||
dbg("_visit");
|
|
||||||
if(node instanceof Array)
|
|
||||||
{
|
|
||||||
dbg("is instanceof Array");
|
|
||||||
//res = res + "[";
|
|
||||||
res = res + "array\n";
|
|
||||||
_visit(node[0], indent);
|
|
||||||
//res = res + _indent(indent) + "]\n";
|
|
||||||
}
|
|
||||||
else if(node instanceof Type && node.isLeaf())
|
|
||||||
{
|
|
||||||
dbg("is instanceof Type");
|
|
||||||
res = res + node.getName() + "\n";
|
|
||||||
}
|
|
||||||
else // Object, have to check all children
|
|
||||||
{
|
|
||||||
dbg("is Object");
|
|
||||||
//res = res + "{\n";
|
|
||||||
for(m in node.getObj())
|
|
||||||
{
|
|
||||||
res = res + _indent(indent+1) + m + ": ";
|
|
||||||
_visit(node.getObj()[m], indent+1);
|
|
||||||
}
|
|
||||||
//res = res + _indent(indent) + "}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
A new approach to build a webinterface for RS
|
|
||||||
=============================================
|
|
||||||
|
|
||||||
1. get JSON encoded data from the backend, data contains a state token
|
|
||||||
2. render data with react.js
|
|
||||||
3. ask the backend if the state token from step 1 expired. If yes, then start again with step 1.
|
|
||||||
|
|
||||||
Steps 1. and 3. are common for most things, only Step 2. differs. This allows to re-use code for steps 1. and 3.
|
|
||||||
|
|
||||||
BUILD / INSTALLATION
|
|
||||||
------------
|
|
||||||
|
|
||||||
- run (requires wget, use MinGW shell on Windows)
|
|
||||||
make
|
|
||||||
- all output files are now in libresapi/src/webfiles
|
|
||||||
- use the --webinterface 9090 command line parameter to enable webui in retroshare-nogui
|
|
||||||
- set the --docroot parameter of retroshare-nogui to point to the "libresapi/src/webfiles" directory
|
|
||||||
(or symlink from /usr/share/RetroShare06/webui on Linux, ./webui on Windows)
|
|
||||||
- retroshare-gui does not have a --docroot parameter. Use symlinks then.
|
|
||||||
|
|
||||||
DEVELOPMENT
|
|
||||||
-----------
|
|
||||||
|
|
||||||
- Ubuntu: install nodejs package
|
|
||||||
sudo apt-get install nodejs
|
|
||||||
- Windows: download and install nodejs from http://nodejs.org
|
|
||||||
- Download development tools with the nodejs package manager (short npm)
|
|
||||||
npm install
|
|
||||||
- run Retroshare with webinterface on port 9090
|
|
||||||
- during development, run this command (use MinGW shell on Windows)
|
|
||||||
while true; do make ../webfiles/livereload --silent; sleep 1; done
|
|
||||||
- the command will copy the source files to libresapi/src/webfiles if they change
|
|
||||||
- it will trigger livereload at http://localhost:9090/api/v2/livereload/trigger
|
|
||||||
|
|
||||||
API DOCUMENTATION
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
- run
|
|
||||||
node PeersTest.js
|
|
||||||
- this will print the expected schema of the api output, and it will try to test it with real data
|
|
||||||
- run retroshare-nogui with webinterface enabled on port 9090, to test if the real output of the api matches the expected schema
|
|
||||||
|
|
||||||
CONTRIBUTE
|
|
||||||
----------
|
|
||||||
|
|
||||||
- if you are a web developer or want to become one
|
|
||||||
get in contact!
|
|
||||||
- lots of work to do, i need you!
|
|
|
@ -1,109 +0,0 @@
|
||||||
/**
|
|
||||||
* JS Api for Retroshare
|
|
||||||
* @constructor
|
|
||||||
* @param {object} connection - an object which implements a request() function.
|
|
||||||
* The request function should take two parameters: an object to be send as request and a callback.
|
|
||||||
* The callback should get called with an response object on success.
|
|
||||||
*/
|
|
||||||
function RsApi(connection)
|
|
||||||
{
|
|
||||||
var runnign = true;
|
|
||||||
/**
|
|
||||||
* Send a request to the server
|
|
||||||
* @param req - the request so send
|
|
||||||
* @param {Function} cb - callback function which takes the response as parameter
|
|
||||||
*/
|
|
||||||
this.request = function(req, cb)
|
|
||||||
{
|
|
||||||
connection.request(req, cb);
|
|
||||||
};
|
|
||||||
var tokenlisteners = [];
|
|
||||||
/**
|
|
||||||
* Register a callback to be called when the state token expired.
|
|
||||||
* @param {Function} listener - the callback function, which does not take arguments
|
|
||||||
* @param token - the state token to listen for
|
|
||||||
*/
|
|
||||||
this.register_token_listener = function(listener, token)
|
|
||||||
{
|
|
||||||
tokenlisteners.push({listener:listener, token:token});
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Unregister a previously registered callback.
|
|
||||||
*/
|
|
||||||
this.unregister_token_listener = function(listener) // no token as parameter, assuming unregister from all listening tokens
|
|
||||||
{
|
|
||||||
var to_delete = [];
|
|
||||||
for(var i=0; i<tokenlisteners.length; i++){
|
|
||||||
if(tokenlisteners[i].listener === listener){
|
|
||||||
to_delete.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(var i=0; i<to_delete.length; i++){
|
|
||||||
// copy the last element to the current index
|
|
||||||
var index = to_delete[i];
|
|
||||||
tokenlisteners[index] = tokenlisteners[tokenlisteners.length-1];
|
|
||||||
// remove last element
|
|
||||||
tokenlisteners.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* start polling for state changes
|
|
||||||
*/
|
|
||||||
this.start = function(){
|
|
||||||
running = true;
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* stop polling for state changes
|
|
||||||
*/
|
|
||||||
this.stop = function(){
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************** interal stuff **************
|
|
||||||
var TICK_INTERVAL = 3000;
|
|
||||||
function received_tokenstates(resp)
|
|
||||||
{
|
|
||||||
if(resp.data){
|
|
||||||
for(var i=0; i<resp.data.length; i++){
|
|
||||||
var token = resp.data[i];
|
|
||||||
// search the listener for this token
|
|
||||||
for(var j=0; j<tokenlisteners.length; j++){
|
|
||||||
if(tokenlisteners[j].token === token){
|
|
||||||
// call the listener
|
|
||||||
tokenlisteners[j].listener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// schedule new update
|
|
||||||
if(running)
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
};
|
|
||||||
function received_error()
|
|
||||||
{
|
|
||||||
// try again, maybe want a better logic later
|
|
||||||
if(running)
|
|
||||||
setTimeout(tick, TICK_INTERVAL);
|
|
||||||
};
|
|
||||||
function tick()
|
|
||||||
{
|
|
||||||
var data = [];
|
|
||||||
// maybe cache the token list?
|
|
||||||
// profiler will tell us if we should
|
|
||||||
for(var i=0; i<tokenlisteners.length; i++){
|
|
||||||
data.push(tokenlisteners[i].token);
|
|
||||||
}
|
|
||||||
connection.request({
|
|
||||||
path: "statetokenservice",
|
|
||||||
data: data,
|
|
||||||
}, received_tokenstates, received_error);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// with this trick, we should be able to run in browser or nodejs
|
|
||||||
if(typeof window === 'undefined')
|
|
||||||
{
|
|
||||||
// we are running in nodejs, so have to add to export
|
|
||||||
module.exports = RsApi;
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
var http = require('http');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connection to the RS backend using http for running under node.js
|
|
||||||
* Mainly for testing, but could also use it for general purpose scripting.
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
module.exports = function()
|
|
||||||
{
|
|
||||||
var server_hostname = "localhost";
|
|
||||||
var server_port = "9090";
|
|
||||||
var api_root_path = "/api/v2/";
|
|
||||||
|
|
||||||
this.request = function(request, callback)
|
|
||||||
{
|
|
||||||
var data;
|
|
||||||
if(request.data)
|
|
||||||
data = JSON.stringify(request.data);
|
|
||||||
else
|
|
||||||
data = "";
|
|
||||||
|
|
||||||
// NODEJS specific
|
|
||||||
var req = http.request({
|
|
||||||
host: server_hostname,
|
|
||||||
port: server_port,
|
|
||||||
path: api_root_path + request.path,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Content-Length": data.length, // content length is required, else Wt will not provide the data (maybe WT does not like chunked encoding?)
|
|
||||||
}
|
|
||||||
//method: "POST",
|
|
||||||
}, function(response){
|
|
||||||
var databuffer = [];
|
|
||||||
response.on("data", function(chunk){
|
|
||||||
//console.log("got some data");
|
|
||||||
databuffer = databuffer + chunk;
|
|
||||||
})
|
|
||||||
response.on("end", function(){
|
|
||||||
//console.log("finished receiving data");
|
|
||||||
//console.log("data:"+databuffer);
|
|
||||||
callback(JSON.parse(databuffer));
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
//console.log("uploading data:");
|
|
||||||
//console.log(data);
|
|
||||||
req.write(data);
|
|
||||||
req.end();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
/**
|
|
||||||
* Connection to the RS backend using XHR
|
|
||||||
* (could add other connections later, for example WebSockets)
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function RsXHRConnection(server_hostname, server_port)
|
|
||||||
{
|
|
||||||
var debug;
|
|
||||||
//debug = function(str){console.log(str);};
|
|
||||||
debug = function(str){};
|
|
||||||
|
|
||||||
//server_hostname = "localhost";
|
|
||||||
//server_port = "9090";
|
|
||||||
var api_root_path = "/api/v2/";
|
|
||||||
|
|
||||||
var status_listeners = [];
|
|
||||||
|
|
||||||
function notify_status(status)
|
|
||||||
{
|
|
||||||
for(var i = 0; i < status_listeners.length; i++)
|
|
||||||
{
|
|
||||||
status_listeners[i](status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a callback to be called when the state of the connection changes.
|
|
||||||
* @param {function} cb - callback which receives a single argument. The arguments value is "connected" or "not_connected".
|
|
||||||
*/
|
|
||||||
this.register_status_listener = function(cb)
|
|
||||||
{
|
|
||||||
status_listeners.push(cb);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister a status callback function.
|
|
||||||
* @param {function} cb - a privously registered callback function
|
|
||||||
*/
|
|
||||||
this.unregister_status_listener = function(cb)
|
|
||||||
{
|
|
||||||
var to_delete = [];
|
|
||||||
for(var i = 0; i < status_listeners.length; i++)
|
|
||||||
{
|
|
||||||
if(status_listeners[i] === cb){
|
|
||||||
to_delete.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(var i = 0; i < to_delete.length; i++)
|
|
||||||
{
|
|
||||||
// copy the last element to the current index
|
|
||||||
var index = to_delete[i];
|
|
||||||
status_listeners[i] = status_listeners[status_listeners.length-1];
|
|
||||||
// remove the last element
|
|
||||||
status_listeners.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a request to the backend
|
|
||||||
* automatically encodes the request as JSON before sending it to the server
|
|
||||||
* @param {object} req - the request to send to the server
|
|
||||||
* @param {function} cb - callback function to be called to handle the response. The callback takes one object as parameter. Can be left undefined.
|
|
||||||
* @param {function} err_cb - callback function to signal a failed request. Can be undefined.
|
|
||||||
*/
|
|
||||||
this.request = function(req, cb, err_cb)
|
|
||||||
{
|
|
||||||
//var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
|
|
||||||
// TODO: window is not available in QML
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.onreadystatechange = function(){
|
|
||||||
//console.log("onreadystatechanged state"+xhr.readyState);
|
|
||||||
// TODO: figure out how to catch errors like connection refused
|
|
||||||
// maybe want to have to set a state variable like ok=false
|
|
||||||
// the gui could then display: "no connection to server"
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if(xhr.status !== 200)
|
|
||||||
{
|
|
||||||
console.log("RsXHRConnection: request failed with status: "+xhr.status);
|
|
||||||
console.log("request was:");
|
|
||||||
console.log(req);
|
|
||||||
notify_status("not_connected");
|
|
||||||
if(err_cb !== undefined)
|
|
||||||
err_cb();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// received response
|
|
||||||
notify_status("connected");
|
|
||||||
debug("RsXHRConnection received response:");
|
|
||||||
debug(xhr.responseText);
|
|
||||||
if(false)//if(xhr.responseText === "")
|
|
||||||
{
|
|
||||||
debug("Warning: response is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var respObj = JSON.parse(xhr.responseText);
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
debug("Exception during response handling: "+e);
|
|
||||||
}
|
|
||||||
if(cb === undefined)
|
|
||||||
debug("No callback function specified");
|
|
||||||
else
|
|
||||||
cb(respObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// post is required for sending data
|
|
||||||
var method;
|
|
||||||
if(req.data){
|
|
||||||
method = "POST";
|
|
||||||
} else {
|
|
||||||
method = "GET";
|
|
||||||
}
|
|
||||||
xhr.open(method, "http://"+server_hostname+":"+server_port+api_root_path+req.path);
|
|
||||||
var data = JSON.stringify(req.data);
|
|
||||||
debug("RsXHRConnection sending data:");
|
|
||||||
debug(data);
|
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
||||||
xhr.send(data);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,146 +0,0 @@
|
||||||
/**
|
|
||||||
* Construct a new type from an array, object or function.
|
|
||||||
* Use instances of this class to build a schema graph.
|
|
||||||
* The schema graph must not contain data other than arrays and instances of this class.
|
|
||||||
* Use the check function to check if arbitrary JS objects matches the schema.
|
|
||||||
* @constructor
|
|
||||||
* @param {String} name - name for the new type
|
|
||||||
* @param obj - array, object or function
|
|
||||||
* array: array should contain one instance of class "Type"
|
|
||||||
* object: object members can be arrays or instances of class "Type".
|
|
||||||
* Can also have child objects, but the leaf members have to be instances of class "Type"
|
|
||||||
* function: a function which takes three parameters: log, other, stack
|
|
||||||
* must return true if other matches the type, can report errors using the function passed in log.
|
|
||||||
*/
|
|
||||||
function Type(name, obj)
|
|
||||||
{
|
|
||||||
//var dbg = function(str){console.log(str);};
|
|
||||||
var dbg = function(str){};
|
|
||||||
|
|
||||||
this.getName = function(){
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
this.isLeaf = function(){
|
|
||||||
return typeof(obj) === "function";
|
|
||||||
}
|
|
||||||
this.getObj = function(){
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
this.check = function(log, other, stack)
|
|
||||||
{
|
|
||||||
if(typeof(obj) === "object")
|
|
||||||
{
|
|
||||||
stack.push("<"+name+">");
|
|
||||||
var ok = _check(log, obj, other, stack);
|
|
||||||
stack.pop;
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
if(typeof(obj) === "function")
|
|
||||||
return obj(log, other, stack);
|
|
||||||
log("FATAL Error: wrong usage of new Type(), second parameter should be an object or checker function");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function _check(log, ref, other, stack)
|
|
||||||
{
|
|
||||||
dbg("_check");
|
|
||||||
dbg("ref=" + ref);
|
|
||||||
dbg("other=" + other);
|
|
||||||
dbg("stack=[" + stack + "]");
|
|
||||||
if(ref instanceof Array)
|
|
||||||
{
|
|
||||||
dbg("is instanceof Array");
|
|
||||||
if(other instanceof Array)
|
|
||||||
{
|
|
||||||
if(other.length > 0)
|
|
||||||
{
|
|
||||||
return _check(log, ref[0], other[0], stack);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Warning: can't check array of length 0 in ["+stack+"]");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Error: not an Array ["+stack+"]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ref instanceof Type)
|
|
||||||
{
|
|
||||||
dbg("is instanceof Type");
|
|
||||||
return ref.check(log, other, stack);
|
|
||||||
}
|
|
||||||
else // Object, have to check all children
|
|
||||||
{
|
|
||||||
dbg("is Object");
|
|
||||||
var ok = true;
|
|
||||||
for(m in ref)
|
|
||||||
{
|
|
||||||
if(m in other)
|
|
||||||
{
|
|
||||||
stack.push(m);
|
|
||||||
ok = ok && _check(log, ref[m], other[m], stack);
|
|
||||||
stack.pop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Error: missing member \""+m+"\" in ["+stack+"]");
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check for additionally undocumented members
|
|
||||||
for(m in other)
|
|
||||||
{
|
|
||||||
if(!(m in ref))
|
|
||||||
{
|
|
||||||
log("Warning: found additional member \""+m+"\" in ["+stack+"]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// basic data types
|
|
||||||
// - string
|
|
||||||
// - bool
|
|
||||||
// - any (placeholder for unknown type)
|
|
||||||
|
|
||||||
var string = new Type("string",
|
|
||||||
function(log, other, stack)
|
|
||||||
{
|
|
||||||
if(typeof(other) !== "string")
|
|
||||||
{
|
|
||||||
log("Error: not a string ["+stack+"]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var bool = new Type("bool",
|
|
||||||
function(log, other, stack)
|
|
||||||
{
|
|
||||||
if(typeof(other) !== "boolean")
|
|
||||||
{
|
|
||||||
log("Error: not a bool ["+stack+"]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var any = new Type("any",
|
|
||||||
function(log, other, stack)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
exports.Type = Type;
|
|
||||||
exports.string = string;
|
|
||||||
exports.bool = bool;
|
|
||||||
exports.any = any;
|
|
|
@ -1,134 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: black;
|
|
||||||
color: lime;
|
|
||||||
font-family: monospace;
|
|
||||||
margin: 0em;
|
|
||||||
/*padding: 1.5em;*/
|
|
||||||
padding: 2mm;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#overlay{
|
|
||||||
z-index: 10;
|
|
||||||
position: fixed;
|
|
||||||
top:0;
|
|
||||||
left:0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.paddingbox{
|
|
||||||
padding:2mm;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav{
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0em;
|
|
||||||
margin: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav li{
|
|
||||||
display: inline;
|
|
||||||
padding: 0.1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
border-width: 0.1em;
|
|
||||||
border-color: blue;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
td{
|
|
||||||
padding: 0.3em;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0.1em;
|
|
||||||
border-color: lime;
|
|
||||||
}
|
|
||||||
.btn{
|
|
||||||
border-style: solid;
|
|
||||||
border-color: lime;
|
|
||||||
border-width: 0.1em;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn2, .box{
|
|
||||||
border-style: solid;
|
|
||||||
/*border-color: lime;*/
|
|
||||||
border-color: limeGreen;
|
|
||||||
/*border-width: 1px;*/
|
|
||||||
border-radius: 3mm;
|
|
||||||
padding: 2mm;
|
|
||||||
font-size: 10mm;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-bottom: 2mm;
|
|
||||||
}
|
|
||||||
.btn2:hover{
|
|
||||||
background-color: midnightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filelink{
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
input, textarea{
|
|
||||||
color: lime;
|
|
||||||
font-family: monospace;
|
|
||||||
background-color: black;
|
|
||||||
border-color: lime;
|
|
||||||
font-size: 10mm;
|
|
||||||
border-radius: 3mm;
|
|
||||||
border-width: 1mm;
|
|
||||||
padding: 2mm;
|
|
||||||
margin-bottom: 2mm;
|
|
||||||
margin-right: 2mm;
|
|
||||||
|
|
||||||
/* make the button the whole screen width */
|
|
||||||
width: 100%;
|
|
||||||
/* make the text input fit small screens*/
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
input:hover{
|
|
||||||
background-color: midnightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flexbox{
|
|
||||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
|
||||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
|
||||||
display: -webkit-flex; /* NEW - Chrome */
|
|
||||||
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
.flexwidemember{
|
|
||||||
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
|
||||||
width: 20%; /* For old syntax, otherwise collapses. */
|
|
||||||
-webkit-flex: 1; /* Chrome */
|
|
||||||
-ms-flex: 1; /* IE 10 */
|
|
||||||
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo_splash{
|
|
||||||
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
-webkit-animation-name: logo_splash; /* Chrome, Safari, Opera */
|
|
||||||
-webkit-animation-duration: 3s; /* Chrome, Safari, Opera */
|
|
||||||
animation-name: logo_splash;
|
|
||||||
animation-duration: 3s;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
/* Chrome, Safari, Opera */
|
|
||||||
@-webkit-keyframes logo_splash {
|
|
||||||
from {opacity: 0;}
|
|
||||||
to {opacity: 1;}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Standard syntax */
|
|
||||||
@keyframes logo_splash {
|
|
||||||
from {opacity: 0;}
|
|
||||||
to {opacity: 1;}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,29 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>New webinterface for Retroshare</title>
|
|
||||||
|
|
||||||
<script src="RsXHRConnection.js"></script>
|
|
||||||
<script src="RsApi.js"></script>
|
|
||||||
|
|
||||||
<!-- it seems to work more reliable, if the jsx file is loaded before react -->
|
|
||||||
<script type="text/jsx" src="gui.jsx"></script>
|
|
||||||
|
|
||||||
<script src="react.js"></script>
|
|
||||||
<script src="JSXTransformer.js"></script>
|
|
||||||
|
|
||||||
<link href="green-black.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="initial-scale=1">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script>
|
|
||||||
document.write("<p>loading lots of stuff...</p>");
|
|
||||||
</script>
|
|
||||||
<p><noscript>The Retroshare web interface requires JavaScript. Please enable JavaScript in your browser.</noscript></p>
|
|
||||||
<!--<div id="logo_splash">
|
|
||||||
<img src="img/logo_splash.png"></img>
|
|
||||||
</div>-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "rswebui",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"dependencies": {
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
This is the list of known BUGS:
|
|
||||||
-------------------------------
|
|
||||||
* None!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -124,10 +124,13 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
|
||||||
std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl;
|
std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id)
|
bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool is_client_side)
|
||||||
{
|
{
|
||||||
bool res = true ;
|
bool res = true ;
|
||||||
|
|
||||||
|
if(is_client_side) // always accept distant chat when we're the client side.
|
||||||
|
return true ;
|
||||||
|
|
||||||
if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
|
if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
|
||||||
res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ;
|
res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ;
|
||||||
|
|
||||||
|
@ -261,9 +264,12 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,
|
||||||
RsChatMsgItem *item = new RsChatMsgItem;
|
RsChatMsgItem *item = new RsChatMsgItem;
|
||||||
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
|
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
|
||||||
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
|
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
|
||||||
|
item->sendTime = time(NULL) ;
|
||||||
item->PeerId(RsPeerId(tunnel_id)) ;
|
item->PeerId(RsPeerId(tunnel_id)) ;
|
||||||
handleRecvChatMsgItem(item) ;
|
handleRecvChatMsgItem(item) ;
|
||||||
|
|
||||||
|
delete item ; // item is replaced by NULL if partial, but this is not the case here.
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
|
|
||||||
// derived in p3ChatService, so as to pass down some info
|
// derived in p3ChatService, so as to pass down some info
|
||||||
virtual void handleIncomingItem(RsItem *) = 0;
|
virtual void handleIncomingItem(RsItem *) = 0;
|
||||||
virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ;
|
virtual bool handleRecvChatMsgItem(RsChatMsgItem *& ci)=0 ;
|
||||||
|
|
||||||
bool handleOutgoingItem(RsChatItem *) ;
|
bool handleOutgoingItem(RsChatItem *) ;
|
||||||
bool handleRecvItem(RsChatItem *) ;
|
bool handleRecvItem(RsChatItem *) ;
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
|
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelService::RsGxsTunnelId& tunnel_id) ;
|
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool is_client_side) ;
|
||||||
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
|
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
|
||||||
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
|
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,10 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous
|
||||||
|
|
||||||
|
rsGRouter->addRoutingClue(GRouterKeyId(cli->signature.keyId),cli->PeerId()) ;
|
||||||
|
|
||||||
ChatLobbyFlags fl ;
|
ChatLobbyFlags fl ;
|
||||||
|
|
||||||
// delete items that are not for us, as early as possible.
|
// delete items that are not for us, as early as possible.
|
||||||
|
@ -420,11 +424,6 @@ void DistributedChatService::checkSizeAndSendLobbyMessage(RsChatItem *msg)
|
||||||
sendChatItem(msg) ;
|
sendChatItem(msg) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *ci)
|
|
||||||
{
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DistributedChatService::handleRecvItem(RsChatItem *item)
|
bool DistributedChatService::handleRecvItem(RsChatItem *item)
|
||||||
{
|
{
|
||||||
switch(item->PacketSubType())
|
switch(item->PacketSubType())
|
||||||
|
@ -699,6 +698,9 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
// add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous
|
||||||
|
rsGRouter->addRoutingClue(GRouterKeyId(item->signature.keyId),item->PeerId()) ;
|
||||||
|
|
||||||
if(! bounceLobbyObject(item,item->PeerId()))
|
if(! bounceLobbyObject(item,item->PeerId()))
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue