fossasia/loklak_webclient

View on GitHub
app/js/directives/signin-twitter.js

Summary

Maintainability
D
2 days
Test Coverage
'use strict';
/* global angular, $ */
/* jshint unused:false */

var directivesModule = require('./_index.js');



directivesModule.directive('signinTwitter', ['$interval', '$location', '$timeout', '$rootScope', 'HelloService', 'SearchService', 'AppSettings', 'AuthorizedSearch', '$http', function($interval, $location, $timeout, $rootScope, HelloService, SearchService, AppSettings, AuthorizedSearch, $http) {
    return {
        scope: {
            hello: '=',
            twitterSession: '='
        },
        templateUrl: 'signin-twitter.html',
        controller: function($scope) {
            var timelineIntervals = [];
            $rootScope.root.timelineNewTweets = [];
            $rootScope.root.haveNewerTweets = false;
            $rootScope.root.doneGettingFeed = false;
            /* Check if a session is available before hello.js even initialize
             * in order to determine if the application is going to login automatically or not
             */
            var twitterStorageObject = JSON.parse(localStorage.getItem("hello"));
            if (!twitterStorageObject || !twitterStorageObject.twitter) {
                $rootScope.root.twitterSession = false;
            } else {
                $rootScope.root.twitterSession = true;
            }

            $rootScope.root.isHelloDoneCheckingCookies = true;

            /* Hello related init*/
            var hello = $scope.hello;
            window.hello = hello;

            // Init service, will also evaluate available cookies
            hello.init({
                twitter: AppSettings.twitterConsumerKey
            },
            {
                oauth_proxy: AppSettings.oauthProxyUrl,
                redirect_uri: '/redirect'
            }
            );

            // If service init result in e.g. login
            // Create global session variable
            hello.on('auth.login', function(auth) {
                hello(auth.network).api('/me').then(function(twitterSession) {
                    $rootScope.root.twitterSession = true;

                    $rootScope.$apply(function() {
                        $rootScope.root.twitterSession = twitterSession;
                        $scope.imageURLClear = twitterSession.profile_image_url_https.split('_normal');
                        $rootScope.root.twitterSession.profileURL = $scope.imageURLClear[0]+$scope.imageURLClear[1];
                    });

                    SearchService.retrieveTopology($rootScope.root.twitterSession.screen_name, 10000).then(function(result) {
                        result.topology.followers.forEach(function(status) {
                            status.isAFollower = true;
                            status.isAFollowing = status.following;
                        });
                        result.topology.following.forEach(function(status) {
                            status.isAFollower = false;
                            status.isAFollowing = true;
                        });
                        $rootScope.userTopology  = result.topology;
                        console.log($rootScope.userTopology);
                        $rootScope.userTopology.noOfFollowings = result.user.friends_count;
                        $rootScope.userTopology.noOfFollowers = result.user.followers_count;
                    }, function() {});

                    var oauth_info = hello("twitter").getAuthResponse();
                    if (oauth_info) {
                        var screen_name = oauth_info.screen_name;
                        var token = oauth_info.access_token.split(":")[0];
                        var secret = oauth_info.access_token.split(":")[1].split("@")[0];
                        AuthorizedSearch.getLoggedInAccountInfo(screen_name, token, secret).then(function(data) {
                                $rootScope.root.authorizedUserInfo = data;
                        }, function() {});
                    }

                    angular.element(".topnav .global-search-container").removeClass("ng-hide");


                }, function() {
                    console.log("Authentication failed, try again later");
                });

                hello(auth.network).api('/me/friends').then(function(twitterFriendFeed) {
                    // Gather id_str from result from Twitter API
                    // for later the get similar results from loklak
                    var activityFeedIdStrArray = [];
                    twitterFriendFeed.data.forEach(function(feed) {
                        if (feed.status) {
                            activityFeedIdStrArray.push(feed.status.id_str);
                        }
                    });
                    // Sort by created time to show on timeline
                    twitterFriendFeed.data.sort(function(a,b) {
                        if (b.status && a.status) {
                            return new Date(b.status.created_at) - new Date(a.status.created_at);
                        }
                    });
                    // Injection out of angular operations
                    $rootScope.$apply(function() {
                        $rootScope.root.twitterFriends = twitterFriendFeed;
                        $rootScope.root.activityFeedIdStrArray = activityFeedIdStrArray;
                        $rootScope.root.homeFeedLimit = 15;
                        $rootScope.root.doneGettingFeed = true;
                        $rootScope.root.loadMoreHomeFeed = function(operand) {
                            $rootScope.root.homeFeedLimit += operand;
                        };
                    });
                }, function(){
                    console.log('Unable to load tweets from your followers');
                });

                var updateTimeline = function() {
                    console.log("Getting newer tweets");
                    hello(auth.network).api('/me/friends').then(function(twitterFriendFeed) {
                        // Sort by created time to show on timeline
                        twitterFriendFeed.data.sort(function(a,b) {
                            if (b.status && a.status) {
                                return new Date(b.status.created_at) - new Date(a.status.created_at);
                            }
                        });
                        var haveNewerTweet = true;
                        var i = 0;
                        var newerTweets = [];
                        var currentNewest = new Date($rootScope.root.twitterFriends.data[0].status.created_at);
                        while (haveNewerTweet && i < twitterFriendFeed.data.length) {
                            if (!twitterFriendFeed.data[i].status) {
                                i++;
                            } else {
                                var beingEvalTimestamp = new Date(twitterFriendFeed.data[i].status.created_at);
                                if (beingEvalTimestamp <= currentNewest) {
                                    haveNewerTweet = false;
                                } else {
                                    newerTweets.push(twitterFriendFeed.data[i]);
                                    i++;
                                }
                            }
                        }
                        if (newerTweets.length > 0) {
                            $rootScope.$apply(function() {
                                $rootScope.root.timelineNewTweets = newerTweets;
                                $rootScope.root.haveNewerTweets = true;
                            });
                        }
                    }, function(){
                        console.log('Unable to load tweets from your followers');
                    });
                };

                /*
                 * Start an interval to update timeline
                 * The interval is incremental
                 * implemented with recursive interval
                 * base interval is 20s, increment is 11s
                 */
                angular.forEach(timelineIntervals, function(interval) {
                    $interval.cancel(interval);
                });
                var updateTimlineInterval = function(refreshTime) {
                    return $timeout(function() {
                        updateTimeline();
                        refreshTime += 11000;
                        updateTimlineInterval(refreshTime);
                    }, refreshTime);
                };
                updateTimlineInterval(20000);

            });

            hello.on('auth.logout', function(auth) {
                $rootScope.$apply(function() {
                    $rootScope.root.twitterSession = false;
                });
                angular.element("#map").remove();
                if ($location.path() === "/search") {
                    angular.element(".topnav .global-search-container").removeClass("ng-hide");
                } else {
                    angular.element(".topnav .global-search-container").addClass("ng-hide");
                }
            }, function() {
                    console.log("Signed out failed, try again later");
            });

            $rootScope.root.timelineShowNewerTweets = function() {
                $rootScope.root.twitterFriends.data = $rootScope.root.timelineNewTweets.concat($rootScope.root.twitterFriends.data);
                $rootScope.root.timelineNewTweets = [];
                $rootScope.root.haveNewerTweets = false;
            };

            /* Listener on nav */
            $rootScope.root.ToggleMobileNav = function() {
                angular.element("#pull .lines-button").toggleClass("close");
                $(".hidden-items").toggle();
                $(".topnav-user-actions .signin-twitter").toggle();
            };

            /* Listen on user avatar */
            $scope.toggleOptions = function() {
                angular.element(".hidden-user-info").toggleClass("hide");
            };


            /* Global listener, mainly used to disable features when clicked out of area*/
            window.onclick = function(e) {
                var targetClasses = e.target.className;
                var targetId = e.target.id;

                // If user-info (top-right nav) is shown, clicked out of its area will disable it
                if (!targetClasses || typeof(targetClasses) === "object") {
                    if (!angular.element(".hidden-user-info").hasClass("hide")) {
                        angular.element(".hidden-user-info").toggleClass("hide");
                    }
                } else {
                    if (targetClasses.indexOf("hidden-user-info") === -1 && targetId.indexOf("home-view-user-avatar") === -1) {
                        if (!angular.element(".hidden-user-info").hasClass("hide")) {
                            angular.element(".hidden-user-info").toggleClass("hide");
                        }
                    }
                }

                // If suggestions are shown, clicked out of its area will disable it
                if(!targetClasses || targetClasses.indexOf("suggestion-item") === -1) {
                    if ($rootScope.root.haveSearchSuggestion !== false) {
                        $rootScope.suggestionsHttpCanceler.resolve();
                        $rootScope.root.haveSearchSuggestion = false;
                    }
                }

            };

            /** Model for home view **/
            $rootScope.root.home = {};
            $rootScope.root.home.evalToCloseOverlay = function($event) {
                if ($event.target.className === "operator-overlay-container") {
                    $rootScope.root.home.operatorOverlayShow = false;
                }
            };

            $rootScope.root.home.operators = {
                'loklak messages': 'containing both "loklak" and "messages". This is the default operators',
                'loklak /image': 'containing "loklak" and must have at least an image. Other possible filter is /video, /accounts, /map',
                'loklak since:2015-08-02 until:2015-08-14' : 'containing "loklak" and shared between the according point of time',
                'beer -root': 'containing "beer" but not "root"',
                'beer -/profanity': 'containing "beer" but not tweet with profane content',
                '"happy hour"': 'containing the exact phrase "happy hour".',
                'love OR hate': 'containing either "love" or "hate" (or both).',
                '#haiku': 'containing the hastag "haiku"',
                'from:alexiskold' : 'shared by user with screen name "alexiskold"',
                'near:London': 'shared near London'
            };

            /** Get hashtag trends **/
            $timeout(function() {
                function getMonth(monthStr){
                    return new Date(monthStr+'-1-01').getMonth()+1;
                }
                var hashtagData = [];
                var queryString = '';
                var currentDate = new Date();
                var untilDate = currentDate.toString();
                var untilElements = untilDate.split(' ');
                var untilMonthValue = ('0'+getMonth(untilElements[1])).slice(-2);
                var untilDateString = 'until:'+untilElements[3]+'-'+untilMonthValue+'-'+('0'+untilElements[2]).slice(-2);
                var sinceDate = new Date();
                sinceDate.setDate(sinceDate.getDate()-20);
                var sinceDay = ('0' + sinceDate.getDate()).slice(-2);
                var sinceMonth = ('0' + (sinceDate.getMonth()+1)).slice(-2);
                var sinceYear = sinceDate.getFullYear();
                var sinceDateString = 'since:'+sinceYear+'-'+sinceMonth+'-'+sinceDay+' ';
                queryString = sinceDateString+untilDateString;
                var params = {
                    q: queryString,
                    source: 'cache',
                    count: 0,
                    fields: 'hashtags',
                    limit: 6
                };
                SearchService.getTrendsAggregation(params).then(function(data) {
                           hashtagData = hashtagData.concat(data.aggregations.hashtags);
                           $rootScope.root.trends = hashtagData[0];
                    }, function() {

                    });
            }, 1000);

        },
        link: function(scope) {
            var hello = scope.hello;
            var isOnline = hello('twitter').getAuthResponse();
            var idleTime = 0;

            $rootScope.root.aSearchWasDone = false;
            var timerIncrement = function() {
                idleTime = idleTime + 1;
                if (idleTime > 10 && (!$rootScope.root.twitterSession && !$rootScope.root.aSearchWasDone)) {
                    $('#signupModal').modal('show');
                    $rootScope.root.aSearchWasDone = true;
                }
            };

            angular.element(document).ready(function() {
                var idleInterval = setInterval(timerIncrement, 1000);
                $(this).mousemove(function (e) { idleTime = 0; });
                $(this).keypress(function (e) { idleTime = 0; });

                if (!isOnline) {
                    if ($location.path() !== "/search" && $location.path() !== "/advancedsearch" && $location.path() !== "/topology") {
                        angular.element(".topnav .global-search-container").addClass("ng-hide");
                    }
                }

                /*
                 * Dynamic UI on state changes
                 */
                $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
                    // If moving away from search: cancel old search, suggestion, empty search field
                    if (toState.name !== "Search") {
                        $rootScope.root.globalSearchTerm = "";
                        if ($rootScope.httpCanceler) { $rootScope.httpCanceler.resolve();}
                        if ($rootScope.suggestionsHttpCanceler) { $rootScope.suggestionsHttpCanceler.resolve();}
                        $rootScope.root.haveSearchSuggestion = false;
                    }

                    // Maintain only one search box in all views when logged/not logged in.
                    var isOnline = hello('twitter').getAuthResponse();
                    if (!isOnline) {
                        if (toState.name === "Search" || toState.name === "Topology") {
                            angular.element(".topnav .global-search-container").removeClass("ng-hide");
                        } else {
                            angular.element(".topnav .global-search-container").addClass("ng-hide");
                        }
                    } else {
                        angular.element(".topnav .global-search-container").removeClass("ng-hide");
                    }
                });
            });

            hello.on('auth.login', function(auth) {
                angular.element('.modal-backdrop').remove();
                angular.element("body").removeClass("modal-open");
            });
        }
    };
}]);