Commit dd92f507 authored by Matthieu Le Corre's avatar Matthieu Le Corre

refactor CE and adjust route calls

Signed-off-by: Matthieu Le Corre's avatarMatthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
parent 95084675
......@@ -27,12 +27,12 @@ return [
[ 'name'=> 'collaboration#startSession', 'url' => '/collaboration/startsession','verb' => 'POST'],
[ 'name'=> 'collaboration#addStep', 'url' => '/collaboration/addstep','verb' => 'POST'],
[ 'name'=> 'collaboration#getSteps', 'url' => '/collaboration/getsteps','verb' => 'GET'],
[ 'name'=> 'collaboration#getAllSteps', 'url' => '/collaboration/getallsteps','verb' => 'GET'],
[ 'name'=> 'collaboration#addUser', 'url' => '/collaboration/adduser','verb' => 'POST'],
[ 'name'=> 'collaboration#removeUser', 'url' => '/collaboration/removeuser','verb' => 'POST'],
[ 'name'=> 'collaboration#getUserList', 'url' => '/collaboration/getuserlist','verb' => 'GET'],
[ 'name'=> 'collaboration#pushStep', 'url'=> '/collaboration/pushstep', 'verb' => 'GET']
[ 'name'=> 'collaboration#getNewSteps', 'url'=> '/collaboration/getnewsteps', 'verb' => 'GET']
]
];
......@@ -3,7 +3,7 @@
top: 0 ;
left:0 ;
width: 100% ;
height: 100% ;
height: calc(100vh - 50px) ;
background-color: white;
z-index: 1000;
overflow: hidden;
......@@ -11,7 +11,7 @@
}
.icon-whiteboard {
background-image: url("../img/whiteboard.svg");
background-image: url("../img/wbr.svg");
}
.icon-save {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -26,7 +26,7 @@ use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IRequest;
use OCA\whiteboard\Collaboration\CollaborationEngine ;
use OCA\whiteboard\Service\CollaborationEngine ;
class CollaborationController extends Controller {
......@@ -34,64 +34,68 @@ class CollaborationController extends Controller {
* @NoAdminRequired
*
**/
public function __construct($AppName, IRequest $request, CollaborationEngine $engine) {
public function __construct(string $AppName, IRequest $request, CollaborationEngine $engine, $userId) {
parent::__construct($AppName, $request);
$this->engine = $engine ;
$this->engine = $engine ;
$this->engine->setUserId($userId) ;
$this->engine->setAppName($AppName) ;
$this->engine->setRessourceId($request->getParam('id')) ;
}
/**
* @NoAdminRequired
*
**/
public function startSession($id) {
return $this->engine->startSession($id) ;
public function startSession() {
return new DataResponse($this->engine->startSession(),Http::STATUS_NO_CONTENT) ;
}
/**
* @NoAdminRequired
*
**/
public function addUser($id,$user) {
return $this->engine->addUser($id,$user) ;
public function addUser() {
return new DataResponse($this->engine->addUser()) ;
}
/**
* @NoAdminRequired
*
**/
public function removeUser($id,$user) {
return $this->engine->removeUser($id,$user) ;
public function removeUser() {
return new DataResponse($this->engine->removeUser()) ;
}
/**
* @NoAdminRequired
*
**/
public function getUserList($id) {
return $this->engine->getUserList($id) ;
public function getUserList() {
return new DataResponse($this->engine->getUserList()) ;
}
/**
* @NoAdminRequired
*
* @param int $id
* @param string $user
* @param string $type
* @param string $step
*
**/
public function addStep(int $id,string $user,string $type, string $step) {
return $this->engine->addStep($id,$user,$type,$step) ;
public function addStep(string $type, string $step) {
return new DataResponse($this->engine->addStep($type,$step)) ;
}
/**
* @NoAdminRequired
*
**/
public function getSteps($id) {
public function getAllSteps() {
try {
return new DataResponse($this->engine->getSteps($id)) ;
return new DataResponse($this->engine->getAllSteps()) ;
} catch (DoesNotExistException $ex) {
return new DataResponse($ex.message,Http::STATUS_NO_CONTENT) ;
}
......@@ -101,7 +105,7 @@ class CollaborationController extends Controller {
* @NoAdminRequired
*
**/
public function pushStep(int $id,string $user) {
return $this->engine->waitForNewSteps($id,$user) ;
public function getNewSteps() {
return new DataResponse($this->engine->waitForNewSteps()) ;
}
}
......@@ -19,9 +19,7 @@
*
*/
namespace OCA\whiteboard\Collaboration ;
use OCP\ICacheFactory;
namespace OCA\whiteboard\Service ;
use OCA\whiteboard\Db\Step ;
use OCA\whiteboard\Db\StepMapper ;
......@@ -30,73 +28,84 @@ use OCA\whiteboard\Db\User ;
use OCA\whiteboard\Db\UserMapper ;
class CollaborationEngine {
private $StepMapper ;
private $UserMapper ;
private $AppName ;
private $userId ;
private $ressourceId ;
// private $cache ;
public function __construct(StepMapper $StepMapper, UserMapper $UserMapper) {
public function __construct(ICacheFactory $cacheFactory, StepMapper $StepMapper, UserMapper $UserMapper) {
$this->StepMapper = $StepMapper ;
$this->UserMapper = $UserMapper ;
$this->AppName = "whiteboard";
}
// $this->cache = $cacheFactory->createDistributed('WhiteboardSession::'.$this->file);
public function setAppName(string $AppName) {
$this->AppName = $AppName ;
}
//DONE
public function startSession(int $fileId) {
public function setUserId(string $userId) {
$this->userId = $userId ;
}
public function setRessourceId(string $ressourceId) {
$this->ressourceId = $ressourceId ;
}
//DONE
public function startSession() {
// nothing to setup with DB engine
}
//DONE
public function addUser(int $fileId, string $user) {
$usr = $this->UserMapper->find($user,$this->AppName,$fileId) ;
public function addUser() {
$usr = $this->UserMapper->find($this->userId,$this->AppName,$this->ressourceId) ;
if (! $usr) {
$Nuser = new User() ;
$Nuser->setAppId($this->AppName) ;
$Nuser->setUserId($user) ;
$Nuser->setUserId($this->userId) ;
$Nuser->setLastSeen(time()) ;
$Nuser->setFileId($fileId) ;
$Nuser->setFileId($this->ressourceId) ;
return $this->UserMapper->insert($Nuser);
} else {
$this->updateLastSeen($user,$fileId) ;
$this->updateLastSeen($this->userId,$this->ressourceId) ;
return "already there" ;
} ;
}
//DONE
public function removeUser(int $fileId, string $user) {
$usr = $this->UserMapper->find($user,$this->AppName,$fileId) ;
$cnt = count($this->UserMapper->findAll($this->AppName,$fileId)) ;
public function removeUser() {
$usr = $this->UserMapper->find($this->userId,$this->AppName,$this->ressourceId) ;
$cnt = count($this->UserMapper->findAll($this->AppName,$this->ressourceId)) ;
if ($usr) {
$this->UserMapper->delete($usr) ;
}
$cnt = count($this->UserMapper->findAll($this->AppName,$fileId)) ;
$cnt = count($this->UserMapper->findAll($this->AppName,$this->ressourceId)) ;
if ($cnt == 0) {
$this->StepMapper->removeAll($fileId) ;
$this->StepMapper->removeAll($this->ressourceId) ;
}
return "user removed" ;
}
// DONE
public function addStep(int $fileId,string $user, string $type, string $datas) {
$this->updateLastSeen($user,$fileId) ;
public function addStep(string $type, string $datas) {
$this->updateLastSeen($this->userId,$this->ressourceId) ;
$Nstep = new Step() ;
$Nstep->setAppId($this->AppName) ;
$Nstep->setUserId($user) ;
$Nstep->setUserId($this->userId) ;
$Nstep->setStepId(time()) ;
$Nstep->setFileId($fileId) ;
$Nstep->setStepForwarded($user) ;
$Nstep->setFileId($this->ressourceId) ;
$Nstep->setStepForwarded($this->userId) ;
$Nstep->setStepType($type) ;
$Nstep->setStepData($datas) ;
......@@ -104,14 +113,14 @@ class CollaborationEngine {
}
// DONE
public function getSteps($fileId) {
$result =$this->StepMapper->findAll($this->AppName,$fileId) ;
public function getAllSteps() {
$result =$this->StepMapper->findAll($this->AppName,$this->ressourceId) ;
return $result ;
}
// DONE
public function getUserList($fileId) {
$users = $this->UserMapper->findAll($this->AppName,$fileId) ;
public function getUserList() {
$users = $this->UserMapper->findAll($this->AppName,$this->ressourceId) ;
foreach ($users as $user) {
if ($user->getLastSeen() + 60 < time()) {
......@@ -122,33 +131,34 @@ class CollaborationEngine {
}
// DONE
public function waitForNewSteps(int $fileId, string $user) {
public function waitForNewSteps() {
$timeout = 20 ;
$elapsedTime = 0;
while (empty($steps) && $elapsedTime < $timeout) {
$steps = $this->StepMapper->findLasts($this->AppName,$fileId,$user) ;
$steps = $this->StepMapper->findLasts($this->AppName,$this->ressourceId,$this->userId) ;
$elapsedTime++ ;
if (empty($steps)) {
sleep(1) ;
}
} ;
$this->updateLastSeen($user,$fileId) ;
$this->updateLastSeen() ;
foreach ($steps as $step) {
$forwarded = explode(',',$step->getStepForwarded()) ;
$forwarded[] = $user ;
$forwarded[] = $this->userId ;
$result = implode(',',$forwarded) ;
$step->setStepForwarded($result) ;
$this->StepMapper->update($step) ;
} ;
return $steps ;
}
// PRIVATE
private function updateLastSeen(string $userId, int $fileId) {
$usr = $this->UserMapper->find($userId,$this->AppName,$fileId) ;
private function updateLastSeen() {
$usr = $this->UserMapper->find($this->userId,$this->AppName,$this->ressourceId) ;
$usr->setLastSeen(time()) ;
$this->UserMapper->update($usr) ;
}
......
This diff is collapsed.
......@@ -68,6 +68,12 @@ export default {
}
},
destroyed: function() {
document.getElementById('app-content-' + this.appName).remove()
document.body.style.overflowY = ''
document.getElementById('app-navigation').classList.remove('hidden')
},
methods: {
isOffline: function(user) {
const now = Math.floor(Date.now() / 1000) - 30
......@@ -95,14 +101,11 @@ export default {
},
},
destroyed: function() {
document.getElementById('app-content-' + this.appName).remove()
document.getElementById('app-navigation').classList.remove('hidden')
},
}
</script>
<style scoped>
button {
position: relative;
float:right ;
......
/* eslint-env jquery */
/**
* @author Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
......@@ -45,7 +43,7 @@ export default {
// because we may arrive in an allready running session
// get all steps from last save
self.getSteps()
self.getAllSteps()
.then(function(steps) {
steps.data.forEach(step => emit(self.appName + '::externalAddStep', step))
}).catch(function(error) {
......@@ -68,7 +66,6 @@ export default {
stop: function() {
this.removeUser()
this.stopCommunication()
// console.log('CE : Collaboration stopped for ' + this.appName)
},
init: function() {
......@@ -86,12 +83,10 @@ export default {
const url = generateUrl('apps/' + this.appName + '/collaboration/adduser')
// console.log('CE : Adding user ' + OC.currentUser)
const ajx = axios.post(url, {
return axios.post(url, {
id: this.id,
user: getCurrentUser().uid,
})
return ajx
},
removeUser: function() {
......@@ -100,29 +95,30 @@ export default {
const ajx = axios.post(url, {
id: this.id,
user: getCurrentUser().uid,
})
return ajx
},
sendStep: function(payload) {
const self = this
const url = generateUrl('apps/' + this.appName + '/collaboration/addstep')
// console.log('CE : Sending ', payload.type, ' step')
const ajx = axios.post(url, {
return axios.post(url, {
id: this.id,
user: getCurrentUser().uid,
type: payload.type,
step: JSON.stringify(payload.step),
}).catch((error) => {
console.error('Network or server error, waiting 5 sec before retry -> ', error.message)
setTimeout(() => { self.sendStep(payload) }, 5000)
return Promise.reject(error)
})
return ajx
},
getSteps: function() {
const url = generateUrl('apps/' + this.appName + '/collaboration/getsteps')
getAllSteps: function() {
const url = generateUrl('apps/' + this.appName + '/collaboration/getallsteps')
const ajx = axios.get(url, {
params: {
id: this.id,
......@@ -162,11 +158,13 @@ export default {
})
}
}).catch(function(Err) {
if (axios.isCancel(Err)) {
console.debug(Err.message)
}).catch((error) => {
if (axios.isCancel(error)) {
console.debug(error.message)
// return Promise.reject(error.message)
} else {
console.debug('LP Error', Err)
console.error('Network or server error, waiting 5 sec before retry -> ', error.message)
setTimeout(() => { self.startCommunication() }, 5000)
}
})
},
......@@ -175,15 +173,15 @@ export default {
const CancelToken = axios.CancelToken
this.longPullCancelToken = CancelToken.source()
const url = generateUrl('apps/' + this.appName + '/collaboration/pushstep')
const ajx = axios.get(url, {
const url = generateUrl('apps/' + this.appName + '/collaboration/getnewsteps')
return axios.get(url, {
cancelToken: this.longPullCancelToken.token,
params: {
id: this.id,
user: getCurrentUser().uid,
},
})
return ajx
},
stopCommunication: function() {
......
/* eslint-env jquery */
/**
* @author Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
......@@ -19,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { emit } from '@nextcloud/event-bus'
import { linkTo } from '@nextcloud/router'
......
......@@ -63,6 +63,7 @@ export default {
container.id = 'app-content-' + this.APP_NAME
document.getElementById('app-content').appendChild(container)
document.body.style.overflowY = 'hidden'
document.getElementById('app-navigation').classList.add('hidden')
Vue.prototype.t = window.t
......@@ -89,7 +90,6 @@ export default {
this.vm.$mount(container)
// TODO unsubscribe !!
subscribe(this.APP_NAME + '::saveClick', this.SC = () => {
self.saveEdit()
})
......@@ -195,7 +195,7 @@ export default {
unsubscribe(this.APP_NAME + '::externalAddStep', this.EAS)
unsubscribe(this.APP_NAME + '::usersListChanged', this.ECU)
unsubscribe(this.APP_NAME + '::closeClick', this.CC)
unsubscribe(this.APP_NAME + '::closeClick', this.SC)
unsubscribe(this.APP_NAME + '::saveClick', this.SC)
// stop collaboration Engine
this.CE.stop()
......
......@@ -8,7 +8,7 @@ module.exports = {
path: path.resolve(__dirname, './js'),
publicPath: '/js/',
filename: 'main.js',
chunkFilename: 'chunks/[name]-[hash].js',
chunkFilename: 'chunks/[name].js',
jsonpFunction: "webpackJsonpWhiteboard"
},
module: {
......@@ -53,4 +53,4 @@ module.exports = {
extensions: ['*', '.js', '.vue'],
symlinks: false,
},
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment