Loklak Walls Manual Moderation – approving tweets

This is a continuation from the previous post – Loklak walls manual moderation – tweet storage. In this section, I will show the changes I made to enable the user to approve or reject a tweet, and make that change happen across all walls that are opened.

First, I had to examine how loklak.net displays it’s tweets previously. On each wall page, a timeout would be called every interval to retrieve new tweets from loklak_server, these tweets would then be stored on the client’s browser window, in the view model, or $scope in angular.

[code language=”javascript”]

vm.update2 = function(refreshTime) {
return $timeout(function() {
SearchService.initData(searchParams).then(function(data) {

vm.statuses = data.statuses.splice(0, searchParams.count);

}, refreshTime);
};
[/code]

 

Having this kind of storage for each browser makes the data inconsistent across the same wall open in different browser windows, as they start querying loklak_server at different times and intervals. This also makes it tough to implement manual moderation previously as the tweets on each open page could not be controlled from the dashboard, since they all lived in their own page.

Now that we have shifted the storage of tweets to mongoDB, we are now able to control how tweets are displayed for all open walls! First, I shifted the calls to loklak_server to the dashboard page instead of the walls page as it made more sense to control the interval from the dashboard rather than the display pages themselves.

Next, I needed a way to sync changes in the database across the dashboard as well as the display pages. At first, I tried to use the same method of http calls, but I soon found them too complicated to sync, having 3 components with interconnected actions. Actions from the dashboard and new entries from the database would have to affect the display, and new entries from the database would have to affect the dashboard and display. Also having an interval for updating the wall after changes were made to the database made it seem very unresponsive and resulted in a bad user experience.

The solution to this was: WebSockets! This allows us to listen for new events like addition of new tweets. When first initialized, the display pages and the dashboard just had to load the existing tweets in the database, when new tweets are loaded, they’ll be added into the database AND the displays and dashboard, making it update in real time.

websocket-small

I chose socket.io as it made integrating WebSockets into the MEAN stack relatively easy. After the http request for new tweets from loklak_server is returned, the app then sends a POST request to the node server, which then emits an event to update the display and the dashboard. Below is the route controller, which posts the tweet array received from loklak_server.

[code language=”javascript”]
module.exports.storeTweet = function (req, res) {
req.body.tweetArr.forEach(function(tweet){
var newTweet = new Tweet(tweet);
newTweet.save(function(err,tweet){
// EMIT DASHBOARD EVENT
io.emit("addNewTweet", tweet);
// EMIT WALL DISPLAY EVENT
io.emit("addNewTweet"+req.body.userWallId, tweet);
}
})
});

[/code]

On the wall display page controller, it listens for the emitted event and adds the data to the display.

[code language=”javascript”]
socket.on(‘addNewTweets’ + $stateParams.user + $stateParams.id, function(tweet){
vm.statuses.splice(0,0, tweet);
})
[/code]

The toggle events are similar in that instead of POST requests,  now we are sending PUT requests from the dashboard to update the tweet in mongoDB, and then changing the data attribute on the wall display. Using AngularJS’s ng-hide we can show/hide the tweet depending on it’s approval field.

Inside the angular directive on the dashboard we attach a toggle function to the click:

[code language=”javascript”]
$scope.toggle = function(){
$scope.data.approval = !$scope.data.approval;
$http.put(‘/api/tweets/’+$scope.data._id, $scope.data);
}
[/code]

[code language=”html”]
<div ng-show="data.approval" ng-attr-id="{{data.id_str}}" class="linear linear-simple" /&amp;gt;
[/code]

Similarly on the server we emit an event:

[code language=”javascript”]

module.exports.updateTweet = function (req, res) {
Tweet
.findById(req.params.tweetId)
.exec(function(err, tweet) {
tweet.approval = !tweet.approval;
tweet.save(function(err) {
res.json({tweet: tweet});
});
});

// EMIT TOGGLE EVENT
io.emit("toggle", req.params.tweetId);
}
}
[/code]

And on the wallDisplay controller we can listen to that toggle event:

[code language=”javascript”]

socket.on(‘toggle’,function(tweetId){
var tweetIdx = vm.statuses.findIndex(function(tweet){
return tweet._id === tweetId;
});
vm.statuses[tweetIdx].approval = !vm.statuses[tweetIdx].approval;
});

[/code]

The end result is manual moderation from the dashboard!

icLfu4KZE9

 

 

Loklak Walls Manual Moderation – approving tweets

One thought on “Loklak Walls Manual Moderation – approving tweets

Comments are closed.