FollowOver

Rollover for user info and follow button.

目前为 2016-11-27 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name FollowOver
  3. // @namespace https://www.ekkooff.com/
  4. // @version 1.0
  5. // @description Rollover for user info and follow button.
  6. // @author Kevin Roberts (@echo)
  7. // @match https://gab.ai/*
  8. // @include https://gab.ai/home
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. window.addEventListener('load',function() {
  16. var timeout=null;
  17. var timeout2=null;
  18. var id=null;
  19.  
  20. var styles = $('<style type="text/css">\n\
  21. #followpopup {\n\
  22. font-family: freight-sans-pro!important;\n\
  23. background-color:white;\n\
  24. position:absolute;\n\
  25. z-index:10000;\n\
  26. display:none;\n\
  27. height:140px;\n\
  28. width:500px;\n\
  29. padding:4px;\n\
  30. border:1px solid #666;\n\
  31. border-radius:5px;\n\
  32. }\n\
  33. \n\
  34. #followpopup-head {\n\
  35. text-align: center;\n\
  36. margin-bottom:3px;\n\
  37. }\n\
  38. #followpopup-head span {\n\
  39. padding-right:5px;\n\
  40. }\n\
  41. \n\
  42. #followpopup-bio {\n\
  43. height: 82px;\n\
  44. overflow: hidden;\n\
  45. word-wrap: break-word;\n\
  46. -ms-word-break: break-all;\n\
  47. overflow-wrap: break-word;\n\
  48. word-break: break-word;\n\
  49. text-overflow: ellipsis;\n\
  50. margin-bottom:5px;\n\
  51. }\n\
  52. \n\
  53. #followpopup-info {\n\
  54. border: 1px solid #edeeee;\n\
  55. overflow:hidden;\n\
  56. white-space: nowrap;\n\
  57. text-overflow: ellipsis;\n\
  58. border-radius:4px;\n\
  59. display:block;\n\
  60. width:100%;\n\
  61. height: 28px;\n\
  62. position:relative;\n\
  63. }\n\
  64. \n\
  65. #followpopup-follow {\n\
  66. right:0;\n\
  67. position:absolute;\n\
  68. width:55px;\n\
  69. color: white;\n\
  70. text-decoration: none;\n\
  71. padding: 5px 10px;\n\
  72. display: inline-block;\n\
  73. }\n\
  74. \n\
  75. #followpopup-info span {\n\
  76. border-right: 1px solid #edeeee;\n\
  77. padding: 3px;\n\
  78. display: inline-block;\n\
  79. }\n\
  80. \n\
  81. #followpopup #followpopup-followback {\n\
  82. background-color: white;\n\
  83. right:75px;\n\
  84. position:absolute;\n\
  85. padding-right: 6px;\n\
  86. height: 100%;\n\
  87. }\n\
  88. \n\
  89. #followpopup .follow {\n\
  90. background: #34cf7f;\n\
  91. }\n\
  92. \n\
  93. #followpopup .unfollow {\n\
  94. background: red;\n\
  95. }\n\
  96. \n\
  97. #followpopup .pending {\n\
  98. background: #edeeee;\n\
  99. color: #000;\n\
  100. }\n\
  101. \n\
  102. #followpopup .empty {\n\
  103. background: transparent;\n\
  104. }\n\
  105. #followpopup .ion-checkmark-circled.verified-badge {\n\
  106. background:transparent;\n\
  107. color:#33f!important;\n\
  108. }\n\
  109. \n\
  110. </style>');
  111.  
  112.  
  113. var userInfoPopup = $('<div id="followpopup">\
  114. <div id="followpopup-head">\
  115. <strong><span id="followpopup-name"></span></strong>\
  116. <span id="followpopup-username"></span>\
  117. </div>\
  118. <div id="followpopup-bio"></div>\
  119. <div id="followpopup-info">\
  120. ?<span id="followpopup-score"></span>\
  121. <span id="followpopup-posts"></span>\
  122. <span id="followpopup-followers"></span>\
  123. <span id="followpopup-following"></span>\
  124. <span id="followpopup-followback"></span>\
  125. <a href="#" id="followpopup-follow"></a>\
  126. </div>\
  127. </div>');
  128. $('body').append(styles).append(userInfoPopup);
  129. if($('body').css('background-color')!=='rgba(0, 0, 0, 0)'&&$('body').css('background-color')!=='transparent') {
  130. userInfoPopup.css('background-color',$('body').css('background-color'));
  131. $('#followpopup-followback').css('background-color',$('body').css('background-color'));
  132. }
  133.  
  134. $('#followpopup-follow').click(function() {
  135. var d = {};
  136. if($(this).text()==='Unfollow'||$(this).text()==='Pending') {
  137. d._method = 'delete';
  138. }
  139. var priv = $(this).hasClass('private');
  140. $.ajax({
  141. method: 'POST',
  142. url: '/users/'+id+'/follow',
  143. data: d
  144. }).done(function(data) {
  145. if(data.state==='success') {
  146. if(d._method) {
  147. $('#followpopup-follow').text('Follow').removeClass().addClass('follow');
  148. if($('#followpopup-followback i').hasClass('ion-arrow-swap')) {
  149. $('#followpopup-followback i').removeClass().addClass('ion-arrow-left-c');
  150. }
  151. } else if(!priv) {
  152. $('#followpopup-follow').text('Unfollow').removeClass().addClass('unfollow');
  153. if($('#followpopup-followback i').hasClass('ion-arrow-left-c')) {
  154. $('#followpopup-followback i').removeClass().addClass('ion-arrow-swap');
  155. }
  156. } else {
  157. $('#followpopup-follow').text('Pending').removeClass().addClass('pending');
  158. }
  159.  
  160. if(priv) {
  161. $('#followpopup-follow').addClass('private');
  162. }
  163. }
  164. });
  165. return false;
  166. });
  167.  
  168. var targets = 'a.post__meta__name__full, a.post__meta__name__username, .notification-list .notification-list__item__message div:first-child span a:first-child, .notification-list__item__users a, a.notification-list__item__mention__name, a.notification-list__item__mention__username, a.inner-post-mention, a.profile-badge__name, a.profile-badge__username';
  169. var nameTarget = 'span.mini-user-list__item__name';
  170. var usernameTarget = 'span.mini-user-list__item__username';
  171. var allTargets = targets+', '+nameTarget+', '+usernameTarget;
  172.  
  173. var populatePopup = function(data,css) {
  174. id = data.id;
  175. $('#followpopup-name').html(data.name+(data.verified?' <i class="ion-checkmark-circled verified-badge"></i>':''));
  176. $('#followpopup-username').text('@'+data.username);
  177. $('#followpopup-bio').text(data.bio);
  178. $('#followpopup-score').text(data.score);
  179. $('#followpopup-posts').text(data.post_count+' posts');
  180. $('#followpopup-followers').text(data.follower_count+' followers');
  181. $('#followpopup-following').text(data.following_count+' following');
  182. if(data.followed) {
  183. if(data.following) {
  184. $('#followpopup-followback').html('<i class="ion-arrow-swap"></i>');
  185. } else {
  186. $('#followpopup-followback').html('<i class="ion-arrow-left-c"></i>');
  187. }
  188. } else {
  189. $('#followpopup-followback').html('');
  190. }
  191. if(authUser.username!=data.username) {
  192. if(data.follow_pending) {
  193. $('#followpopup-follow').text('Pending').removeClass().addClass('pending');
  194. } else if(!data.following) {
  195. $('#followpopup-follow').text('Follow').removeClass().addClass('follow');
  196. } else {
  197. $('#followpopup-follow').text('Unfollow').removeClass().addClass('unfollow');
  198. }
  199. } else {
  200. $('#followpopup-follow').text('').removeClass().addClass('empty');
  201. }
  202. if(data.is_private) {
  203. $('#followpopup-follow').addClass('private');
  204. }
  205. userInfoPopup.css(css).show();
  206. };
  207.  
  208. var getUserInfo = function(name,e) {
  209. clearTimeout(timeout);
  210. var offset = $(e.currentTarget).offset();
  211. var offset2 = $(e.currentTarget.parentElement).offset();
  212. var height = $(window).height();
  213. var width = $(window).width();
  214. var css = {
  215. top:((e.clientY<(height/2))?offset.top+25:offset.top-160)+'px',
  216. left:(((width-515)>offset2.left)?offset2.left:width-515)+'px'
  217. };
  218. $.ajax({
  219. method: 'GET',
  220. url: '/users/'+name,
  221. headers: {
  222. 'Authorization': 'Bearer '+localStorage.id_token
  223. }
  224. }).done(function(data) {
  225. populatePopup(data,css);
  226. });
  227. };
  228.  
  229. $('body').on('mouseenter',targets ,function(e){
  230. clearTimeout(timeout);
  231. clearTimeout(timeout2);
  232. var name = e.currentTarget.href.substr(e.currentTarget.href.lastIndexOf('/')+1);
  233. timeout2 = setTimeout(function() {
  234. getUserInfo(name,e);
  235. },500);
  236. }).on('mouseenter',nameTarget,function(e) {
  237. clearTimeout(timeout);
  238. clearTimeout(timeout2);
  239. var name = $(e.currentTarget).next().text().substring(1);
  240. timeout2 = setTimeout(function() {
  241. getUserInfo(name,e);
  242. },500);
  243. }).on('mouseenter',usernameTarget,function(e) {
  244. clearTimeout(timeout);
  245. clearTimeout(timeout2);
  246. var name = $(e.currentTarget).text().substring(1);
  247. timeout2 = setTimeout(function() {
  248. getUserInfo(name,e);
  249. },500);
  250. }).on('click',allTargets,function(e){
  251. clearTimeout(timeout);
  252. clearTimeout(timeout2);
  253. userInfoPopup.hide();
  254. }).on('mouseleave',allTargets,function(){
  255. clearTimeout(timeout2);
  256. timeout = setTimeout(function(){
  257. userInfoPopup.hide();
  258. }, 650);
  259. });
  260.  
  261. (function(history){
  262. var pushState = history.pushState;
  263. history.pushState = function(state) {
  264. if (typeof history.onpushstate == "function") {
  265. history.onpushstate({state: state});
  266. }
  267. clearTimeout(timeout);
  268. clearTimeout(timeout2);
  269. userInfoPopup.hide();
  270. return pushState.apply(history, arguments);
  271. };
  272. })(window.history);
  273.  
  274. userInfoPopup.mouseenter(function() {
  275. clearTimeout(timeout);
  276. clearTimeout(timeout2);
  277. }).mouseleave(function() {
  278. clearTimeout(timeout2);
  279. timeout = setTimeout(function() {
  280. userInfoPopup.hide();
  281. }, 650);
  282. });
  283. },false);
  284. })();